[dovecot-cvs] dovecot/src/lib-index/mbox mbox-index.c,1.48,1.49 mbox-lock.c,1.14,1.15

cras at procontrol.fi cras at procontrol.fi
Mon Nov 25 21:02:52 EET 2002


Update of /home/cvs/dovecot/src/lib-index/mbox
In directory danu:/tmp/cvs-serv2991/src/lib-index/mbox

Modified Files:
	mbox-index.c mbox-lock.c 
Log Message:
Locking changes triggered a bit larger cleanup :) If we have to wait for a
lock longer, the client is now notified about it every 30 seconds. Also if
mailbox opening fails because of lock timeout, we won't overwrite the index
anymore. Finally user gets a clear error message about lock timeout instead
of "internal error".



Index: mbox-index.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-index/mbox/mbox-index.c,v
retrieving revision 1.48
retrieving revision 1.49
diff -u -d -r1.48 -r1.49
--- mbox-index.c	21 Nov 2002 20:50:53 -0000	1.48
+++ mbox-index.c	25 Nov 2002 19:02:49 -0000	1.49
@@ -784,6 +784,7 @@
 	mbox_index_free,
 	mbox_index_set_lock,
 	mbox_index_try_lock,
+        mail_index_set_lock_notify_callback,
 	mbox_index_rebuild,
 	mail_index_fsck,
 	mbox_index_sync,
@@ -805,8 +806,7 @@
 	mail_index_update_field,
 	mail_index_update_field_raw,
 	mail_index_get_last_error,
-	mail_index_is_diskspace_error,
-	mail_index_is_inconsistency_error,
+	mail_index_get_last_error_text,
 
 	MAIL_INDEX_PRIVATE_FILL
 };

Index: mbox-lock.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-index/mbox/mbox-lock.c,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -d -r1.14 -r1.15
--- mbox-lock.c	22 Nov 2002 13:48:36 -0000	1.14
+++ mbox-lock.c	25 Nov 2002 19:02:49 -0000	1.15
@@ -66,6 +66,8 @@
 static int mbox_lock_flock(MailIndex *index, MailLockType lock_type,
 			   time_t max_wait_time)
 {
+	time_t now, last_notify;
+
 	if (lock_type == MAIL_LOCK_EXCLUSIVE)
 		lock_type = LOCK_EX;
 	else if (lock_type == MAIL_LOCK_SHARED)
@@ -73,18 +75,29 @@
 	else
 		lock_type = LOCK_UN;
 
+        last_notify = 0;
 	while (flock(index->mbox_fd, lock_type | LOCK_NB) < 0) {
 		if (errno != EWOULDBLOCK) {
-			index_file_set_syscall_error(index, index->mbox_path,
-						     "flock()");
+                        mbox_set_syscall_error(index, "flock()");
 			return FALSE;
 		}
 
-		if (max_wait_time != 0 && time(NULL) >= max_wait_time) {
-			errno = EAGAIN;
+		now = time(NULL);
+		if (max_wait_time != 0 && now >= max_wait_time) {
+			index->mailbox_lock_timeout = TRUE;
+			index_set_error(index, "Timeout while waiting for "
+					"release of flock() lock for mbox file "
+					"%s", index->mbox_path);
 			return FALSE;
 		}
 
+		if (now != last_notify && index->lock_notify_func != NULL) {
+			last_notify = now;
+			index->lock_notify_func(MAIL_LOCK_NOTIFY_MAILBOX_ABORT,
+						max_wait_time - now,
+						index->lock_notify_context);
+		}
+
 		usleep(LOCK_RANDOM_USLEEP_TIME);
 	}
 
@@ -96,6 +109,7 @@
 			   time_t max_wait_time)
 {
 	struct flock fl;
+	time_t now;
 
 	fl.l_type = MAIL_LOCK_TO_FLOCK(lock_type);
 	fl.l_whence = SEEK_SET;
@@ -104,15 +118,24 @@
 
 	while (fcntl(index->mbox_fd, F_SETLKW, &fl) == -1) {
 		if (errno != EINTR) {
-			index_file_set_syscall_error(index, index->mbox_path,
-						     "fcntl()");
+			mbox_set_syscall_error(index, "fcntl()");
 			return FALSE;
 		}
 
-		if (max_wait_time != 0 && time(NULL) >= max_wait_time) {
-			errno = EAGAIN;
+		now = time(NULL);
+		if (max_wait_time != 0 && now >= max_wait_time) {
+			index->mailbox_lock_timeout = TRUE;
+			index_set_error(index, "Timeout while waiting for "
+					"release of fcntl() lock for mbox file "
+					"%s", index->mbox_path);
 			return FALSE;
 		}
+
+		if (index->lock_notify_func != NULL) {
+			index->lock_notify_func(MAIL_LOCK_NOTIFY_MAILBOX_ABORT,
+						max_wait_time - now,
+						index->lock_notify_context);
+		}
 	}
 
 	return TRUE;
@@ -122,16 +145,19 @@
 			     time_t max_wait_time, int checkonly)
 {
 	struct stat st;
-	time_t now, last_change, last_mtime;
+	time_t now, last_change, last_notify, last_mtime, stale_notify;
 	off_t last_size;
+	unsigned int secs_left;
 	int fd;
 
 	path = t_strconcat(path, ".lock", NULL);
+	stale_notify = dotlock_change_timeout/2;
 
 	/* don't bother with the temp files as we'd just leave them lying
 	   around. besides, postfix also relies on O_EXCL working so we
 	   might as well. */
-	last_change = time(NULL); last_size = 0; last_mtime = 0;
+	last_change = time(NULL); last_notify = 0;
+	last_size = 0; last_mtime = 0;
 	do {
 		now = time(NULL);
 
@@ -159,6 +185,23 @@
 				continue;
 			}
 
+			if (last_notify != now) {
+				last_notify = now;
+				if (now > last_change + stale_notify) {
+					secs_left = now - last_change +
+						dotlock_change_timeout;
+					index->lock_notify_func(
+					      MAIL_LOCK_NOTIFY_MAILBOX_OVERRIDE,
+					      secs_left,
+					      index->lock_notify_context);
+				} else {
+					index->lock_notify_func(
+						MAIL_LOCK_NOTIFY_MAILBOX_ABORT,
+						max_wait_time - now,
+						index->lock_notify_context);
+				}
+			}
+
 			usleep(LOCK_RANDOM_USLEEP_TIME);
 			continue;
 		}
@@ -203,6 +246,7 @@
 
 	index_set_error(index, "Timeout while waiting for release of mbox "
 			"dotlock %s", path);
+	index->mailbox_lock_timeout = TRUE;
 	return FALSE;
 }
 




More information about the dovecot-cvs mailing list