From f27a51cd9a66685b63357de25e733c37eb03b07c Mon Sep 17 00:00:00 2001 From: Timo Sirainen Date: Tue, 6 Feb 2018 17:35:18 +0200 Subject: [PATCH] lib: Add file_lock_from_dotlock() The dotlock creation requires various settings, so the file-lock.h API can't easily be used to create it. But once created, it's simpler to keep all lock types in the same struct file_lock, which can be unlocked/freed once finished. --- src/lib/file-lock.c | 24 +++++++++++++++++++++++- src/lib/file-lock.h | 5 +++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/src/lib/file-lock.c b/src/lib/file-lock.c index eb6bdbe686..b60fd22637 100644 --- a/src/lib/file-lock.c +++ b/src/lib/file-lock.c @@ -3,6 +3,7 @@ #include "lib.h" #include "istream.h" #include "file-lock.h" +#include "file-dotlock.h" #include "time-util.h" #include @@ -14,6 +15,7 @@ struct file_lock { int fd; char *path; + struct dotlock *dotlock; struct timeval locked_time; int lock_type; @@ -352,6 +354,23 @@ void file_lock_set_close_on_free(struct file_lock *lock, bool set) lock->close_on_free = set; } +struct file_lock *file_lock_from_dotlock(struct dotlock **dotlock) +{ + struct file_lock *lock; + + lock = i_new(struct file_lock, 1); + lock->fd = -1; + lock->path = i_strdup(file_dotlock_get_lock_path(*dotlock)); + lock->lock_type = F_WRLCK; + lock->lock_method = FILE_LOCK_METHOD_DOTLOCK; + if (gettimeofday(&lock->locked_time, NULL) < 0) + i_fatal("gettimeofday() failed: %m"); + lock->dotlock = *dotlock; + + *dotlock = NULL; + return lock; +} + static void file_unlock_real(struct file_lock *lock) { const char *error; @@ -374,7 +393,8 @@ void file_unlock(struct file_lock **_lock) could be deleting the new lock. */ i_assert(!lock->unlink_on_free); - file_unlock_real(lock); + if (lock->dotlock == NULL) + file_unlock_real(lock); file_lock_free(&lock); } @@ -418,6 +438,8 @@ void file_lock_free(struct file_lock **_lock) *_lock = NULL; + if (lock->dotlock != NULL) + file_dotlock_delete(&lock->dotlock); if (lock->unlink_on_free) file_try_unlink_locked(lock); if (lock->close_on_free) diff --git a/src/lib/file-lock.h b/src/lib/file-lock.h index e4d6eb19fe..d32d5f8029 100644 --- a/src/lib/file-lock.h +++ b/src/lib/file-lock.h @@ -7,6 +7,7 @@ #define DEFAULT_LOCK_TIMEOUT 120 struct file_lock; +struct dotlock; enum file_lock_method { FILE_LOCK_METHOD_FCNTL, @@ -53,6 +54,10 @@ void file_lock_set_unlink_on_free(struct file_lock *lock, bool set); be useful for files that are only created to exist as lock files. */ void file_lock_set_close_on_free(struct file_lock *lock, bool set); +/* Convert dotlock into file_lock, which can be deleted with either + file_unlock() or file_lock_free(). */ +struct file_lock *file_lock_from_dotlock(struct dotlock **dotlock); + /* Unlock and free the lock. */ void file_unlock(struct file_lock **lock); /* Free the lock without unlocking it (because you're closing the fd anyway). */