[dovecot-cvs] dovecot/src/lib-index mail-tree.c,1.11,1.12

cras at procontrol.fi cras at procontrol.fi
Wed Nov 20 18:15:59 EET 2002


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

Modified Files:
	mail-tree.c 
Log Message:
Avoid rebuilding tree twice if two processes notice it's broken at the same
time.



Index: mail-tree.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-index/mail-tree.c,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -d -r1.11 -r1.12
--- mail-tree.c	6 Nov 2002 07:12:47 -0000	1.11
+++ mail-tree.c	20 Nov 2002 16:15:57 -0000	1.12
@@ -201,40 +201,57 @@
 	return TRUE;
 }
 
-int mail_tree_open_or_create(MailIndex *index)
+static int mail_tree_open_init(MailTree *tree)
 {
-	MailTree *tree;
+	if (!mmap_update(tree))
+		return FALSE;
 
-	tree = mail_tree_open(index);
-	if (tree == NULL)
+	if (tree->mmap_full_length == 0) {
+		/* just created it */
 		return FALSE;
+	}
 
-	do {
-		if (!mmap_update(tree))
-			break;
+	if (!mmap_verify(tree)) {
+		/* broken header */
+		return FALSE;
+	}
 
-		if (tree->mmap_full_length == 0) {
-			/* just created it */
-			if (!mail_tree_rebuild(tree))
-				break;
-		} else if (!mmap_verify(tree)) {
-			/* broken header */
-			if (!mail_tree_rebuild(tree))
-				break;
-		} else if (tree->header->indexid != index->indexid) {
-			index_set_error(tree->index,
+	if (tree->header->indexid != tree->index->indexid) {
+		index_set_error(tree->index,
 				"IndexID mismatch for binary tree file %s",
 				tree->filepath);
 
-			if (!mail_tree_rebuild(tree))
-				break;
+		return FALSE;
+	} 
+
+	return TRUE;
+}
+
+int mail_tree_open_or_create(MailIndex *index)
+{
+	MailTree *tree;
+
+	tree = mail_tree_open(index);
+	if (tree == NULL)
+		return FALSE;
+
+	if (!mail_tree_open_init(tree)) {
+		/* lock and check again, just to avoid rebuilding it twice
+		   if two processes notice the error at the same time */
+		if (!tree->index->set_lock(tree->index, MAIL_LOCK_EXCLUSIVE)) {
+			mail_tree_free(tree);
+			return FALSE;
 		}
 
-		return TRUE;
-	} while (0);
+		if (!mail_tree_open_init(tree)) {
+			if (!mail_tree_rebuild(tree)) {
+				mail_tree_free(tree);
+				return FALSE;
+			}
+		}
+	}
 
-	mail_tree_free(tree);
-	return FALSE;
+	return TRUE;
 }
 
 static void mail_tree_close(MailTree *tree)




More information about the dovecot-cvs mailing list