Mercurial > dovecot > original-hg > dovecot-1.2
changeset 8691:81a146c34a5c HEAD
dotlocking: Increase the wait time 1,5 x every second until we reach 3 seconds.
If the dotlock ever gets updated in any way, the wait time is dropped back
to the initial value of 0.1-0.2 secs.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Mon, 26 Jan 2009 16:21:30 -0500 |
parents | 80486913baf3 |
children | 77c67307d316 |
files | src/lib/file-dotlock.c |
diffstat | 1 files changed, 19 insertions(+), 2 deletions(-) [+] |
line wrap: on
line diff
--- a/src/lib/file-dotlock.c Mon Jan 26 14:13:23 2009 -0500 +++ b/src/lib/file-dotlock.c Mon Jan 26 16:21:30 2009 -0500 @@ -22,6 +22,8 @@ /* 0.1 .. 0.2msec */ #define LOCK_RANDOM_USLEEP_TIME (100000 + (unsigned int)rand() % 100000) +/* Maximum 3 second wait between dotlock checks */ +#define LOCK_MAX_WAIT_USECS (1000000 * 3) /* If the dotlock is newer than this, don't verify that the PID it contains is valid (since it most likely is). */ @@ -62,6 +64,7 @@ time_t last_pid_check; time_t last_change; + unsigned int wait_usecs; unsigned int have_pid:1; unsigned int pid_read:1; @@ -417,7 +420,7 @@ struct timeout *to; if (!lock_info->use_io_notify) { - usleep(LOCK_RANDOM_USLEEP_TIME); + usleep(lock_info->wait_usecs); return; } @@ -439,7 +442,7 @@ } /* timeout after a random time even when using notify, since it doesn't work reliably with e.g. NFS. */ - to = timeout_add(LOCK_RANDOM_USLEEP_TIME/1000, + to = timeout_add(lock_info->wait_usecs/1000, dotlock_wait_end, ioloop); io_loop_run(ioloop); io_remove(&io); @@ -458,6 +461,7 @@ unsigned int stale_notify_threshold; unsigned int change_secs, wait_left; time_t now, max_wait_time, last_notify; + time_t prev_last_change = 0, prev_wait_update = 0; string_t *tmp_path; int ret; bool do_wait; @@ -482,6 +486,19 @@ do { if (do_wait) { + if (prev_last_change != lock_info.last_change) { + /* dotlock changed since last check, + reset the wait time */ + lock_info.wait_usecs = LOCK_RANDOM_USLEEP_TIME; + prev_last_change = lock_info.last_change; + prev_wait_update = now; + } else if (prev_wait_update != now && + lock_info.wait_usecs < LOCK_MAX_WAIT_USECS) { + /* we've been waiting for a while now, increase + the wait time to avoid wasting CPU */ + prev_wait_update = now; + lock_info.wait_usecs += lock_info.wait_usecs/2; + } dotlock_wait(&lock_info); do_wait = FALSE; }