dovecot-1.2: mbox: flock() and lockf() now use blocking alarm()e...
dovecot at dovecot.org
dovecot at dovecot.org
Wed Feb 4 22:13:07 EET 2009
details: http://hg.dovecot.org/dovecot-1.2/rev/8cca2bf6ab76
changeset: 8716:8cca2bf6ab76
user: Timo Sirainen <tss at iki.fi>
date: Wed Feb 04 15:13:01 2009 -0500
description:
mbox: flock() and lockf() now use blocking alarm()ed locking.
diffstat:
1 file changed, 75 insertions(+), 28 deletions(-)
src/lib-storage/index/mbox/mbox-lock.c | 103 +++++++++++++++++++++++---------
diffs (151 lines):
diff -r 25dfff279eda -r 8cca2bf6ab76 src/lib-storage/index/mbox/mbox-lock.c
--- a/src/lib-storage/index/mbox/mbox-lock.c Wed Feb 04 14:59:41 2009 -0500
+++ b/src/lib-storage/index/mbox/mbox-lock.c Wed Feb 04 15:13:01 2009 -0500
@@ -423,6 +423,7 @@ static int mbox_lock_flock(struct mbox_l
time_t max_wait_time)
{
time_t now, last_notify;
+ unsigned int next_alarm;
if (mbox_file_open_latest(ctx, lock_type) < 0)
return -1;
@@ -437,26 +438,49 @@ static int mbox_lock_flock(struct mbox_l
else
lock_type = LOCK_UN;
+ if (max_wait_time == 0) {
+ /* usually we're waiting here, but if we came from
+ mbox_lock_dotlock(), we just want to try locking */
+ lock_type |= LOCK_NB;
+ } else {
+ now = time(NULL);
+ if (now >= max_wait_time)
+ alarm(1);
+ else
+ alarm(I_MIN(max_wait_time - now, 5));
+ }
+
last_notify = 0;
- while (flock(ctx->mbox->mbox_fd, lock_type | LOCK_NB) < 0) {
- if (errno != EWOULDBLOCK) {
+ while (flock(ctx->mbox->mbox_fd, lock_type) < 0) {
+ if (errno != EINTR) {
+ if (errno == EWOULDBLOCK && max_wait_time == 0) {
+ /* non-blocking lock trying failed */
+ return 0;
+ }
+ alarm(0);
mbox_set_syscall_error(ctx->mbox, "flock()");
return -1;
}
now = time(NULL);
- if (now >= max_wait_time)
+ if (now >= max_wait_time) {
+ alarm(0);
return 0;
-
- if (now != last_notify) {
- index_storage_lock_notify(&ctx->mbox->ibox,
- MAILBOX_LOCK_NOTIFY_MAILBOX_ABORT,
- max_wait_time - now);
- }
-
- usleep(LOCK_RANDOM_USLEEP_TIME);
- }
-
+ }
+
+ /* notify locks once every 5 seconds.
+ try to use rounded values. */
+ next_alarm = (max_wait_time - now) % 5;
+ if (next_alarm == 0)
+ next_alarm = 5;
+ alarm(next_alarm);
+
+ index_storage_lock_notify(&ctx->mbox->ibox,
+ MAILBOX_LOCK_NOTIFY_MAILBOX_ABORT,
+ max_wait_time - now);
+ }
+
+ alarm(0);
return 1;
}
#endif
@@ -466,6 +490,7 @@ static int mbox_lock_lockf(struct mbox_l
time_t max_wait_time)
{
time_t now, last_notify;
+ unsigned int next_alarm;
if (mbox_file_open_latest(ctx, lock_type) < 0)
return -1;
@@ -473,31 +498,53 @@ static int mbox_lock_lockf(struct mbox_l
if (lock_type == F_UNLCK && ctx->mbox->mbox_fd == -1)
return 1;
- if (lock_type != F_UNLCK)
+ if (lock_type == F_UNLCK)
+ lock_type = F_ULOCK;
+ else if (max_wait_time == 0) {
+ /* usually we're waiting here, but if we came from
+ mbox_lock_dotlock(), we just want to try locking */
lock_type = F_TLOCK;
- else
- lock_type = F_ULOCK;
+ } else {
+ now = time(NULL);
+ if (now >= max_wait_time)
+ alarm(1);
+ else
+ alarm(I_MIN(max_wait_time - now, 5));
+ lock_type = F_LOCK;
+ }
last_notify = 0;
while (lockf(ctx->mbox->mbox_fd, lock_type, 0) < 0) {
- if (errno != EAGAIN) {
+ if (errno != EINTR) {
+ if ((errno == EACCES || errno == EAGAIN) &&
+ max_wait_time == 0) {
+ /* non-blocking lock trying failed */
+ return 0;
+ }
+ alarm(0);
mbox_set_syscall_error(ctx->mbox, "lockf()");
return -1;
}
now = time(NULL);
- if (now >= max_wait_time)
+ if (now >= max_wait_time) {
+ alarm(0);
return 0;
-
- if (now != last_notify) {
- index_storage_lock_notify(&ctx->mbox->ibox,
- MAILBOX_LOCK_NOTIFY_MAILBOX_ABORT,
- max_wait_time - now);
- }
-
- usleep(LOCK_RANDOM_USLEEP_TIME);
- }
-
+ }
+
+ /* notify locks once every 5 seconds.
+ try to use rounded values. */
+ next_alarm = (max_wait_time - now) % 5;
+ if (next_alarm == 0)
+ next_alarm = 5;
+ alarm(next_alarm);
+
+ index_storage_lock_notify(&ctx->mbox->ibox,
+ MAILBOX_LOCK_NOTIFY_MAILBOX_ABORT,
+ max_wait_time - now);
+ }
+
+ alarm(0);
return 1;
}
#endif
More information about the dovecot-cvs
mailing list