[dovecot-cvs] dovecot/src/lib-index mail-transaction-log-private.h, 1.13.2.2, 1.13.2.3 mail-transaction-log-view.c, 1.45.2.2, 1.45.2.3 mail-transaction-log.c, 1.111.2.3, 1.111.2.4

tss at dovecot.org tss at dovecot.org
Sat Nov 18 21:01:10 UTC 2006


Update of /var/lib/cvs/dovecot/src/lib-index
In directory talvi:/tmp/cvs-serv4036

Modified Files:
      Tag: branch_1_0
	mail-transaction-log-private.h mail-transaction-log-view.c 
	mail-transaction-log.c 
Log Message:
Reference counting fixes. Fixes an assert crash when closing the index.



Index: mail-transaction-log-private.h
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-index/mail-transaction-log-private.h,v
retrieving revision 1.13.2.2
retrieving revision 1.13.2.3
diff -u -d -r1.13.2.2 -r1.13.2.3
--- mail-transaction-log-private.h	12 Nov 2006 11:15:36 -0000	1.13.2.2
+++ mail-transaction-log-private.h	18 Nov 2006 21:01:08 -0000	1.13.2.3
@@ -13,6 +13,8 @@
 	struct mail_transaction_log *log;
         struct mail_transaction_log_file *next;
 
+	/* refcount=0 is a valid state. files start that way, and they're
+	   freed only when mail_transaction_logs_clean() is called. */
 	int refcount;
 
 	char *filepath;

Index: mail-transaction-log-view.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-index/mail-transaction-log-view.c,v
retrieving revision 1.45.2.2
retrieving revision 1.45.2.3
diff -u -d -r1.45.2.2 -r1.45.2.3
--- mail-transaction-log-view.c	12 Nov 2006 11:15:36 -0000	1.45.2.2
+++ mail-transaction-log-view.c	18 Nov 2006 21:01:08 -0000	1.45.2.3
@@ -1,7 +1,7 @@
 /* Copyright (C) 2003-2004 Timo Sirainen */
 
 #include "lib.h"
-#include "buffer.h"
+#include "array.h"
 #include "mail-index-private.h"
 #include "mail-transaction-log-private.h"
 #include "mail-transaction-util.h"
@@ -16,6 +16,10 @@
 	enum mail_transaction_type type_mask;
 	struct mail_transaction_header tmp_hdr;
 
+	/* a list of log files we've referenced. we have to keep this list
+	   explicitly because more files may be added into the linked list
+	   at any time. */
+	array_t ARRAY_DEFINE(file_refs, struct mail_transaction_log_file *);
         struct mail_transaction_log_file *cur, *head, *tail;
 	uoff_t cur_offset;
 
@@ -36,17 +40,32 @@
 
 	view->head = view->tail = view->log->head;
 	view->head->refcount++;
+	ARRAY_CREATE(&view->file_refs, default_pool,
+		     struct mail_transaction_log_file *, 8);
+	array_append(&view->file_refs, &view->head, 1);
 
 	view->next = log->views;
 	log->views = view;
 	return view;
 }
 
+static void
+mail_transaction_log_view_unref_all(struct mail_transaction_log_view *view)
+{
+	struct mail_transaction_log_file *const *files;
+	unsigned int i, count;
+
+	files = array_get(&view->file_refs, &count);
+	for (i = 0; i < count; i++)
+		files[i]->refcount--;
+
+	array_clear(&view->file_refs);
+}
+
 void mail_transaction_log_view_close(struct mail_transaction_log_view **_view)
 {
         struct mail_transaction_log_view *view = *_view;
 	struct mail_transaction_log_view **p;
-	struct mail_transaction_log_file *file;
 
 	*_view = NULL;
 
@@ -57,11 +76,10 @@
 		}
 	}
 
-	for (file = view->tail; file != view->head; file = file->next)
-		file->refcount--;
-	view->head->refcount--;
-
+	mail_transaction_log_view_unref_all(view);
 	mail_transaction_logs_clean(view->log);
+
+	array_free(&view->file_refs);
 	i_free(view);
 }
 
@@ -184,21 +202,16 @@
 		 max_file_offset <= file->sync_offset);
 
 	/* we have all of them. update refcounts. */
-	if (view->tail->hdr.file_seq < first->hdr.file_seq) {
-		/* unref old files */
-		for (file = view->tail; file != first; file = file->next)
-			file->refcount--;
-	} else {
-		/* going backwards, reference them */
-		for (file = first; file != view->tail; file = file->next)
-			file->refcount++;
-	}
+	mail_transaction_log_view_unref_all(view);
+
 	view->tail = first;
+	view->head = view->log->head;
 
-	/* reference all new files */
-	for (file = view->head->next; file != NULL; file = file->next)
+	/* reference all used files */
+	for (file = view->tail; file != NULL; file = file->next) {
+		array_append(&view->file_refs, &file, 1);
 		file->refcount++;
-	view->head = view->log->head;
+	}
 
 	view->prev_file_seq = 0;
 	view->prev_file_offset = 0;

Index: mail-transaction-log.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-index/mail-transaction-log.c,v
retrieving revision 1.111.2.3
retrieving revision 1.111.2.4
diff -u -d -r1.111.2.3 -r1.111.2.4
--- mail-transaction-log.c	12 Nov 2006 11:15:36 -0000	1.111.2.3
+++ mail-transaction-log.c	18 Nov 2006 21:01:08 -0000	1.111.2.4
@@ -247,6 +247,7 @@
 		log->head = mail_transaction_log_file_open_or_create(log, path);
 		i_assert(log->head != NULL);
 	}
+	log->head->refcount++;
 
 	if (index->fd != -1 &&
 	    INDEX_HAS_MISSING_LOGS(index, log->head)) {
@@ -683,7 +684,6 @@
 	}
 
 	file = i_new(struct mail_transaction_log_file, 1);
-	file->refcount = 1;
 	file->log = log;
 	file->filepath = i_strdup(path);
 	file->fd = fd;
@@ -766,7 +766,6 @@
 	struct mail_transaction_log_file *file;
 
 	file = i_new(struct mail_transaction_log_file, 1);
-	file->refcount = 1;
 	file->log = log;
 	file->filepath = i_strdup("(in-memory transaction log file)");
 	file->fd = -1;
@@ -866,6 +865,7 @@
 	for (file = log->files; file != NULL; file = next) {
 		next = file->next;
 
+		i_assert(file->refcount >= 0);
 		if (file->refcount == 0)
 			mail_transaction_log_file_free(file);
 	}
@@ -908,7 +908,6 @@
 
 	if (lock) {
 		if (mail_transaction_log_file_lock(file) < 0) {
-			file->refcount--;
 			mail_transaction_logs_clean(log);
 			return -1;
 		}
@@ -922,6 +921,7 @@
 
 	i_assert(log->head != file);
 	log->head = file;
+	log->head->refcount++;
 	return 0;
 }
 
@@ -967,6 +967,7 @@
 	}
 
 	log->head = file;
+	log->head->refcount++;
 	return 0;
 }
 



More information about the dovecot-cvs mailing list