[dovecot-cvs] dovecot/src/lib-index mail-index-lock.c, 1.13, 1.14 mail-index-view.c, 1.7, 1.8 mail-index.c, 1.120, 1.121

cras at procontrol.fi cras at procontrol.fi
Sun May 16 23:20:27 EEST 2004


Update of /home/cvs/dovecot/src/lib-index
In directory talvi:/tmp/cvs-serv1096

Modified Files:
	mail-index-lock.c mail-index-view.c mail-index.c 
Log Message:
Locking fixes



Index: mail-index-lock.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-index/mail-index-lock.c,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -d -r1.13 -r1.14
--- mail-index-lock.c	3 May 2004 19:53:07 -0000	1.13
+++ mail-index-lock.c	16 May 2004 20:20:24 -0000	1.14
@@ -149,7 +149,7 @@
 			   unsigned int timeout_secs, int update_index,
 			   unsigned int *lock_id_r)
 {
-	int ret;
+	int ret, ret2;
 
 	i_assert(lock_type == F_RDLCK || lock_type == F_WRLCK);
 
@@ -166,8 +166,11 @@
 	}
 
 	if (update_index && index->excl_lock_count == 0) {
-		if (mail_index_has_changed(index) < 0)
+		if ((ret2 = mail_index_has_changed(index)) < 0)
 			return -1;
+		if (ret > 0 && ret2 == 0)
+			return 1;
+		ret = 0;
 	}
 
 	if (ret > 0)
@@ -192,16 +195,36 @@
 		return 1;
 	}
 
-	ret = file_wait_lock_full(index->fd, lock_type, timeout_secs,
-				  NULL, NULL);
-	if (ret <= 0) {
-		if (ret == 0 || errno == EDEADLK) {
-			/* deadlock equals to timeout */
-			return 0;
+	if (lock_type == F_RDLCK || !index->log_locked) {
+		ret = file_wait_lock_full(index->fd, lock_type, timeout_secs,
+					  NULL, NULL);
+		if (ret < 0) {
+			mail_index_set_syscall_error(index, "file_wait_lock()");
+			return -1;
+		}
+	} else {
+		/* this is kind of kludgy. we wish to avoid deadlocks while
+		   trying to lock transaction log, but it can happen if our
+		   process is holding transaction log lock and waiting for
+		   index write lock, while the other process is holding index
+		   read lock and waiting for transaction log lock.
+
+		   we don't have a problem with grabbing read index lock
+		   because the only way for it to block is if it's
+		   write-locked, which isn't allowed unless transaction log
+		   is also locked.
+
+		   so, the workaround for this problem is that we simply try
+		   locking once. if it doesn't work, just rewrite the file.
+		   hopefully there won't be any other deadlocking issues. :) */
+		ret = file_try_lock(index->fd, lock_type);
+		if (ret < 0) {
+			mail_index_set_syscall_error(index, "file_try_lock()");
+			return -1;
 		}
-		mail_index_set_syscall_error(index, "file_wait_lock()");
-		return -1;
 	}
+	if (ret == 0)
+		return 0;
 
 	if (index->lock_type == F_UNLCK)
 		index->lock_id += 2;
@@ -291,7 +314,7 @@
 
 	old_lock_type = index->lock_type;
 	index->lock_type = F_WRLCK;
-        index->excl_lock_count++;
+	index->excl_lock_count++;
 
 	if (mail_index_reopen(index, fd) < 0) {
 		i_assert(index->excl_lock_count == 1);
@@ -422,5 +445,10 @@
 
 int mail_index_is_locked(struct mail_index *index, unsigned int lock_id)
 {
-	return (index->lock_id ^ lock_id) <= 1;
+	if ((index->lock_id ^ lock_id) <= 1) {
+		i_assert(index->lock_type != F_UNLCK);
+		return TRUE;
+	}
+
+	return FALSE;
 }

Index: mail-index-view.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-index/mail-index-view.c,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -d -r1.7 -r1.8
--- mail-index-view.c	9 May 2004 23:20:04 -0000	1.7
+++ mail-index-view.c	16 May 2004 20:20:24 -0000	1.8
@@ -50,11 +50,6 @@
 {
 	unsigned int lock_id;
 
-	if (view->map != view->index->map) {
-		if (mail_index_view_map_protect(view) < 0)
-			return -1;
-	}
-
 	if (!mail_index_is_locked(view->index, view->lock_id)) {
 		if (mail_index_lock_shared(view->index, update_index,
 					   &view->lock_id) < 0)
@@ -78,6 +73,15 @@
 		view->lock_id = lock_id;
 	}
 
+	i_assert(view->index->lock_type != F_UNLCK);
+
+	/* mail_index_lock_shared() may have reopened the file,
+	   so do this after it. */
+	if (view->map != view->index->map) {
+		if (mail_index_view_map_protect(view) < 0)
+			return -1;
+	}
+
 	return 0;
 }
 

Index: mail-index.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-index/mail-index.c,v
retrieving revision 1.120
retrieving revision 1.121
diff -u -d -r1.120 -r1.121
--- mail-index.c	9 May 2004 23:06:27 -0000	1.120
+++ mail-index.c	16 May 2004 20:20:24 -0000	1.121
@@ -574,6 +574,7 @@
 		index->shared_lock_count = 0;
 		index->excl_lock_count = 0;
 		index->lock_type = F_UNLCK;
+		index->lock_id = 2;
 
 		index->nodiskspace = FALSE;
 		index->index_lock_timeout = FALSE;



More information about the dovecot-cvs mailing list