changeset 5938:805f2527a982 HEAD

If use_io_notify dotlock setting is enabled, use I/O notify loop for waiting dotlock deletion instead of just sleeping randomly.
author Timo Sirainen <tss@iki.fi>
date Mon, 09 Jul 2007 07:01:08 +0300
parents 772f4e8bd2a9
children 8f1d94246a8f
files src/lib-storage/index/maildir/maildir-uidlist.c src/lib/file-dotlock.c src/lib/file-dotlock.h
diffstat 3 files changed, 49 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/src/lib-storage/index/maildir/maildir-uidlist.c	Mon Jul 09 06:59:57 2007 +0300
+++ b/src/lib-storage/index/maildir/maildir-uidlist.c	Mon Jul 09 07:01:08 2007 +0300
@@ -181,6 +181,7 @@
 				     maildir_filename_base_cmp);
 	uidlist->next_uid = 1;
 
+	uidlist->dotlock_settings.use_io_notify = TRUE;
 	uidlist->dotlock_settings.use_excl_lock =
 		(mbox->storage->storage.flags &
 		 MAIL_STORAGE_FLAG_DOTLOCK_USE_EXCL) != 0;
--- a/src/lib/file-dotlock.c	Mon Jul 09 06:59:57 2007 +0300
+++ b/src/lib/file-dotlock.c	Mon Jul 09 07:01:08 2007 +0300
@@ -1,6 +1,7 @@
 /* Copyright (C) 2003 Timo Sirainen */
 
 #include "lib.h"
+#include "ioloop.h"
 #include "str.h"
 #include "hex-binary.h"
 #include "hostpid.h"
@@ -58,7 +59,7 @@
 	struct file_change_info lock_info;
 	struct file_change_info file_info;
 
-	bool have_pid;
+	bool have_pid, use_io_notify;
 	time_t last_pid_check;
 	time_t last_change;
 };
@@ -363,6 +364,46 @@
 	return 1;
 }
 
+static void dotlock_wait_end(struct ioloop *ioloop)
+{
+	io_loop_stop(ioloop);
+}
+
+static void dotlock_wait(struct lock_info *lock_info)
+{
+	struct ioloop *ioloop;
+	struct io *io;
+	struct timeout *to;
+
+	if (!lock_info->use_io_notify) {
+		usleep(LOCK_RANDOM_USLEEP_TIME);
+		return;
+	}
+
+	ioloop = io_loop_create();
+	switch (io_add_notify(lock_info->lock_path, dotlock_wait_end,
+			      ioloop, &io)) {
+	case IO_NOTIFY_ADDED:
+		break;
+	case IO_NOTIFY_NOTFOUND:
+		/* the lock file doesn't exist anymore, don't sleep */
+		io_loop_destroy(&ioloop);
+		return;
+	case IO_NOTIFY_DISABLED:
+		/* listening for files not supported */
+		io_loop_destroy(&ioloop);
+		lock_info->use_io_notify = FALSE;
+		usleep(LOCK_RANDOM_USLEEP_TIME);
+		return;
+	}
+	to = timeout_add(LOCK_RANDOM_USLEEP_TIME/1000,
+			 dotlock_wait_end, ioloop);
+	io_loop_run(ioloop);
+	io_remove(&io);
+	timeout_remove(&to);
+	io_loop_destroy(&ioloop);
+}
+
 static int dotlock_create(const char *path, struct dotlock *dotlock,
 			  enum dotlock_create_flags flags, bool write_pid)
 {
@@ -390,12 +431,13 @@
 	lock_info.set = set;
 	lock_info.lock_path = lock_path;
 	lock_info.fd = -1;
-
+	lock_info.use_io_notify = set->use_io_notify;
+;
 	last_notify = 0; do_wait = FALSE;
 
 	do {
 		if (do_wait) {
-			usleep(LOCK_RANDOM_USLEEP_TIME);
+			dotlock_wait(&lock_info);
 			do_wait = FALSE;
 		}
 
--- a/src/lib/file-dotlock.h	Mon Jul 09 06:59:57 2007 +0300
+++ b/src/lib/file-dotlock.h	Mon Jul 09 07:01:08 2007 +0300
@@ -30,6 +30,9 @@
 	/* Rely on O_EXCL locking to work instead of using hardlinks.
 	   It's faster, but doesn't work with all NFS implementations. */
 	unsigned int use_excl_lock:1;
+	/* Use io_add_notify() to speed up finding out when an existing
+	   dotlock is deleted */
+	unsigned int use_io_notify:1;
 };
 
 enum dotlock_create_flags {