changeset 2936:57f975a9b63b HEAD

Renamed mail_index_refresh() to mail_index_reopen_if_needed(). Added public mail_index_refresh() which makes sure index is fully refreshed at the time. Added mbox code to call it after mbox is locked to avoid using old mbox offsets.
author Timo Sirainen <tss@iki.fi>
date Sun, 05 Dec 2004 03:45:53 +0200
parents 0b72e95cd3ae
children 43deb226d769
files src/lib-index/mail-cache.c src/lib-index/mail-index-lock.c src/lib-index/mail-index-private.h src/lib-index/mail-index-view.c src/lib-index/mail-index.c src/lib-index/mail-index.h src/lib-storage/index/maildir/maildir-sync.c src/lib-storage/index/mbox/mbox-mail.c
diffstat 8 files changed, 47 insertions(+), 32 deletions(-) [+]
line wrap: on
line diff
--- a/src/lib-index/mail-cache.c	Sun Dec 05 03:41:45 2004 +0200
+++ b/src/lib-index/mail-cache.c	Sun Dec 05 03:45:53 2004 +0200
@@ -310,7 +310,8 @@
 	if (MAIL_CACHE_IS_UNUSABLE(cache))
 		return 0;
 
-	if (mail_index_view_open_locked(cache->index, &view) < 0)
+	view = mail_index_view_open(cache->index);
+	if (mail_index_refresh(cache->index) < 0)
 		return -1;
 
 	ext = mail_index_view_get_ext(view, cache->ext_id);
--- a/src/lib-index/mail-index-lock.c	Sun Dec 05 03:41:45 2004 +0200
+++ b/src/lib-index/mail-index-lock.c	Sun Dec 05 03:45:53 2004 +0200
@@ -129,7 +129,7 @@
 
 	if (update_index && index->excl_lock_count == 0) {
 		i_assert(index->lock_type != F_WRLCK);
-		if ((ret2 = mail_index_refresh(index)) < 0)
+		if ((ret2 = mail_index_reopen_if_needed(index)) < 0)
 			return -1;
 		if (ret > 0 && ret2 == 0) {
 			i_assert(lock_type == F_RDLCK);
@@ -149,7 +149,7 @@
 		if (lock_type == F_WRLCK)
 			return 0;
 		if (update_index && index->lock_type == F_UNLCK) {
-			if (mail_index_refresh(index) < 0)
+			if (mail_index_reopen_if_needed(index) < 0)
 				return -1;
 		}
 
--- a/src/lib-index/mail-index-private.h	Sun Dec 05 03:41:45 2004 +0200
+++ b/src/lib-index/mail-index-private.h	Sun Dec 05 03:45:53 2004 +0200
@@ -172,7 +172,7 @@
 		       unsigned int timeout_secs);
 
 /* Reopen index file if it has changed. */
-int mail_index_refresh(struct mail_index *index);
+int mail_index_reopen_if_needed(struct mail_index *index);
 
 /* Map index file to memory, replacing the previous mapping for index.
    Returns 1 = ok, 0 = corrupted, -1 = error. If index needs fscking, it
--- a/src/lib-index/mail-index-view.c	Sun Dec 05 03:41:45 2004 +0200
+++ b/src/lib-index/mail-index-view.c	Sun Dec 05 03:45:53 2004 +0200
@@ -538,25 +538,6 @@
 	return view;
 }
 
-int mail_index_view_open_locked(struct mail_index *index,
-				struct mail_index_view **view_r)
-{
-	unsigned int lock_id;
-
-	if (mail_index_lock_shared(index, TRUE, &lock_id) < 0)
-		return -1;
-
-	*view_r = mail_index_view_open(index);
-	if (mail_index_view_lock_head(*view_r, FALSE) < 0) {
-		mail_index_view_close(*view_r);
-		mail_index_unlock(index, lock_id);
-		return -1;
-	}
-
-	mail_index_unlock(index, lock_id);
-	return 0;
-}
-
 const struct mail_index_ext *
 mail_index_view_get_ext(struct mail_index_view *view, uint32_t ext_id)
 {
--- a/src/lib-index/mail-index.c	Sun Dec 05 03:41:45 2004 +0200
+++ b/src/lib-index/mail-index.c	Sun Dec 05 03:45:53 2004 +0200
@@ -1288,7 +1288,7 @@
 	return ret;
 }
 
-int mail_index_refresh(struct mail_index *index)
+int mail_index_reopen_if_needed(struct mail_index *index)
 {
 	struct stat st1, st2;
 
@@ -1314,6 +1314,32 @@
 	}
 }
 
+int mail_index_refresh(struct mail_index *index)
+{
+	unsigned int lock_id;
+	int ret;
+
+	if (index->excl_lock_count > 0) {
+		/* we have index exclusively locked, nothing could
+		   have changed. */
+		return 0;
+	}
+
+	if (!index->mmap_disable) {
+		/* reopening is all we need */
+		return mail_index_reopen_if_needed(index);
+	}
+
+	/* mail_index_map() simply reads latest changes from transaction log,
+	   which makes us fully refreshed. */
+	if (mail_index_lock_shared(index, TRUE, &lock_id) < 0)
+		return -1;
+
+	ret = mail_index_map(index, FALSE);
+	mail_index_unlock(index, lock_id);
+	return ret <= 0 ? -1 : 0;
+}
+
 struct mail_cache *mail_index_get_cache(struct mail_index *index)
 {
 	return index->cache;
--- a/src/lib-index/mail-index.h	Sun Dec 05 03:41:45 2004 +0200
+++ b/src/lib-index/mail-index.h	Sun Dec 05 03:45:53 2004 +0200
@@ -151,13 +151,15 @@
 
 struct mail_cache *mail_index_get_cache(struct mail_index *index);
 
+/* Refresh index so mail_index_lookup*() will return latest values. Note that
+   immediately after this call there may already be changes, so if you need to
+   rely on validity of the returned values, use some external locking for it. */
+int mail_index_refresh(struct mail_index *index);
+
 /* View can be used to look into index. Sequence numbers inside view change
    only when you synchronize it. The view acquires required locks
    automatically, but you'll have to drop them manually. */
 struct mail_index_view *mail_index_view_open(struct mail_index *index);
-/* Open view to latest index locked. */
-int mail_index_view_open_locked(struct mail_index *index,
-				struct mail_index_view **view_r);
 void mail_index_view_close(struct mail_index_view *view);
 
 /* Returns the index for given view. */
--- a/src/lib-storage/index/maildir/maildir-sync.c	Sun Dec 05 03:41:45 2004 +0200
+++ b/src/lib-storage/index/maildir/maildir-sync.c	Sun Dec 05 03:45:53 2004 +0200
@@ -537,15 +537,13 @@
 	ibox->last_cur_mtime = mail_index_get_header(ibox->view)->sync_stamp;
 	if (ibox->dirty_cur_time == 0 && cur_mtime != ibox->last_cur_mtime) {
 		/* check if the index has been updated.. */
-		struct mail_index_view *view;
-
-		if (mail_index_view_open_locked(ibox->index, &view) < 0) {
+		if (mail_index_refresh(ibox->index) < 0) {
 			mail_storage_set_index_error(ibox);
 			return -1;
 		}
 
-		ibox->last_cur_mtime = mail_index_get_header(view)->sync_stamp;
-		mail_index_view_close(view);
+		ibox->last_cur_mtime =
+			mail_index_get_header(ibox->view)->sync_stamp;
 	}
 
 	if (new_mtime != ibox->last_new_mtime ||
--- a/src/lib-storage/index/mbox/mbox-mail.c	Sun Dec 05 03:41:45 2004 +0200
+++ b/src/lib-storage/index/mbox/mbox-mail.c	Sun Dec 05 03:45:53 2004 +0200
@@ -31,6 +31,13 @@
 		if (mbox_sync(ibox, sync_flags) < 0)
 			return -1;
 
+		/* refresh index file after mbox has been locked to make
+		   sure we get only up-to-date mbox offsets. */
+		if (mail_index_refresh(ibox->index) < 0) {
+			mail_storage_set_index_error(ibox);
+			return -1;
+		}
+
 		i_assert(ibox->mbox_lock_type != F_UNLCK);
 		t->mbox_lock_id = ibox->mbox_lock_id;
 	}