# HG changeset patch # User Timo Sirainen # Date 1183953668 -10800 # Node ID 805f2527a982e4c2bbe7c279c9ead4d79f010b0b # Parent 772f4e8bd2a9e55be86ff33aa849b288e316f79a If use_io_notify dotlock setting is enabled, use I/O notify loop for waiting dotlock deletion instead of just sleeping randomly. diff -r 772f4e8bd2a9 -r 805f2527a982 src/lib-storage/index/maildir/maildir-uidlist.c --- 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; diff -r 772f4e8bd2a9 -r 805f2527a982 src/lib/file-dotlock.c --- 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; } diff -r 772f4e8bd2a9 -r 805f2527a982 src/lib/file-dotlock.h --- 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 {