changeset 22816:d1debec5d1c1

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.
author Timo Sirainen <timo.sirainen@dovecot.fi>
date Tue, 06 Feb 2018 17:35:18 +0200
parents 880bd0712ef1
children ccd84e5bcf8c
files src/lib/file-lock.c src/lib/file-lock.h
diffstat 2 files changed, 28 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/src/lib/file-lock.c	Wed Dec 13 15:48:17 2017 +0200
+++ b/src/lib/file-lock.c	Tue Feb 06 17:35:18 2018 +0200
@@ -3,6 +3,7 @@
 #include "lib.h"
 #include "istream.h"
 #include "file-lock.h"
+#include "file-dotlock.h"
 #include "time-util.h"
 
 #include <time.h>
@@ -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 @@
 	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 @@
 	   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);
 }
 
@@ -419,6 +439,8 @@
 
 	*_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)
--- a/src/lib/file-lock.h	Wed Dec 13 15:48:17 2017 +0200
+++ b/src/lib/file-lock.h	Tue Feb 06 17:35:18 2018 +0200
@@ -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 @@
    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). */