commit 6ee94d8cf21e021d561f87ce20440489373ca31c
Author: Thomas Mittelstaedt <tmstaedt@t-mittelstaedt.de>
Date:   Thu May 27 19:09:05 2010 +0200

    Next try for bug 550414. This time with patch
    https://bugzilla.gnome.org/attachment.cgi?id=162092 for evolution
    2.30, kindly provided by Milan Crha. See also: comment 170 in the
    bug.

diff --git a/camel/camel-folder-summary.c b/camel/camel-folder-summary.c
index c5c5308..514427b 100644
--- a/camel/camel-folder-summary.c
+++ b/camel/camel-folder-summary.c
@@ -173,11 +173,11 @@ camel_folder_summary_init (CamelFolderSummary *s)
 	s->uids = g_ptr_array_new ();
 	s->loaded_infos = g_hash_table_new (g_str_hash, g_str_equal);
 
-	p->summary_lock = g_mutex_new();
-	p->io_lock = g_mutex_new();
-	p->filter_lock = g_mutex_new();
-	p->alloc_lock = g_mutex_new();
-	p->ref_lock = g_mutex_new();
+	g_static_rec_mutex_init (&p->summary_lock);
+	g_static_rec_mutex_init (&p->io_lock);
+	g_static_rec_mutex_init (&p->filter_lock);
+	g_static_rec_mutex_init (&p->alloc_lock);
+	g_static_rec_mutex_init (&p->ref_lock);
 
 	s->meta_summary = g_malloc0(sizeof(CamelFolderMetaSummary));
 
@@ -244,11 +244,11 @@ camel_folder_summary_finalize (CamelObject *obj)
 	g_free(s->meta_summary->path);
 	g_free(s->meta_summary);
 
-	g_mutex_free(p->summary_lock);
-	g_mutex_free(p->io_lock);
-	g_mutex_free(p->filter_lock);
-	g_mutex_free(p->alloc_lock);
-	g_mutex_free(p->ref_lock);
+	g_static_rec_mutex_free (&p->summary_lock);
+	g_static_rec_mutex_free (&p->io_lock);
+	g_static_rec_mutex_free (&p->filter_lock);
+	g_static_rec_mutex_free (&p->alloc_lock);
+	g_static_rec_mutex_free (&p->ref_lock);
 
 	g_free(p);
 }
@@ -562,8 +562,6 @@ message_info_from_uid (CamelFolderSummary *s, const gchar *uid)
 		folder_name = s->folder->full_name;
 		cdb = s->folder->parent_store->cdb_r;
 
-		CAMEL_SUMMARY_UNLOCK(s, summary_lock);
-
 		data.summary = s;
 		data.double_ref = TRUE;
 		data.add = FALSE;
@@ -571,11 +569,10 @@ message_info_from_uid (CamelFolderSummary *s, const gchar *uid)
 		ret = camel_db_read_message_info_record_with_uid (cdb, folder_name, uid, &data, camel_read_mir_callback, &ex);
 		if (ret != 0) {
 			camel_exception_clear (&ex);
+			CAMEL_SUMMARY_UNLOCK(s, summary_lock);
 			return NULL;
 		}
 
-		CAMEL_SUMMARY_LOCK(s, summary_lock);
-
 		/* We would have double reffed at camel_read_mir_callback */
 		info = g_hash_table_lookup (s->loaded_infos, uid);
 
@@ -5058,3 +5055,21 @@ camel_folder_summary_get_need_preview (CamelFolderSummary *summary)
 	return _PRIVATE(summary)->need_preview;
 }
 
+void
+camel_folder_summary_lock_summary (CamelFolderSummary *summary)
+{
+	g_return_if_fail (summary != NULL);
+	g_return_if_fail (CAMEL_IS_FOLDER_SUMMARY (summary));
+
+	CAMEL_SUMMARY_LOCK (summary, summary_lock);
+}
+
+void
+camel_folder_summary_unlock_summary (CamelFolderSummary *summary)
+{
+	g_return_if_fail (summary != NULL);
+	g_return_if_fail (CAMEL_IS_FOLDER_SUMMARY (summary));
+
+	CAMEL_SUMMARY_UNLOCK (summary, summary_lock);
+}
+
diff --git a/camel/camel-folder-summary.h b/camel/camel-folder-summary.h
index 6281d18..54adcd4 100644
--- a/camel/camel-folder-summary.h
+++ b/camel/camel-folder-summary.h
@@ -483,6 +483,9 @@ void camel_message_info_dump (CamelMessageInfo *mi);
 /* Migration code */
 gint camel_folder_summary_migrate_infos(CamelFolderSummary *s);
 
+void camel_folder_summary_lock_summary (CamelFolderSummary *summary);
+void camel_folder_summary_unlock_summary (CamelFolderSummary *summary);
+
 G_END_DECLS
 
 #endif /* ! _CAMEL_FOLDER_SUMMARY_H */
diff --git a/camel/camel-private.h b/camel/camel-private.h
index e6ddb84..4cbb52f 100644
--- a/camel/camel-private.h
+++ b/camel/camel-private.h
@@ -118,11 +118,11 @@ struct _CamelFolderSummaryPrivate {
 
 	struct _CamelIndex *index;
 
-	GMutex *summary_lock;	/* for the summary hashtable/array */
-	GMutex *io_lock;	/* load/save lock, for access to saved_count, etc */
-	GMutex *filter_lock;	/* for accessing any of the filtering/indexing stuff, since we share them */
-	GMutex *alloc_lock;	/* for setting up and using allocators */
-	GMutex *ref_lock;	/* for reffing/unreffing messageinfo's ALWAYS obtain before summary_lock */
+	GStaticRecMutex summary_lock;	/* for the summary hashtable/array */
+	GStaticRecMutex io_lock;	/* load/save lock, for access to saved_count, etc */
+	GStaticRecMutex filter_lock;	/* for accessing any of the filtering/indexing stuff, since we share them */
+	GStaticRecMutex alloc_lock;	/* for setting up and using allocators */
+	GStaticRecMutex ref_lock;	/* for reffing/unreffing messageinfo's ALWAYS obtain before summary_lock */
 	GHashTable *flag_cache;
 
 	gboolean need_preview;
@@ -130,9 +130,9 @@ struct _CamelFolderSummaryPrivate {
 };
 
 #define CAMEL_SUMMARY_LOCK(f, l) \
-	(g_mutex_lock(((CamelFolderSummary *) (f))->priv->l))
+	(g_static_rec_mutex_lock (&((CamelFolderSummary *) (f))->priv->l))
 #define CAMEL_SUMMARY_UNLOCK(f, l) \
-	(g_mutex_unlock(((CamelFolderSummary *) (f))->priv->l))
+	(g_static_rec_mutex_unlock (&((CamelFolderSummary *) (f))->priv->l))
 
 struct _CamelStoreSummaryPrivate {
 	GMutex *summary_lock;	/* for the summary hashtable/array */
diff --git a/camel/providers/local/camel-mbox-summary.c b/camel/providers/local/camel-mbox-summary.c
index 5b422ac..f836e7d 100644
--- a/camel/providers/local/camel-mbox-summary.c
+++ b/camel/providers/local/camel-mbox-summary.c
@@ -472,7 +472,7 @@ meta_message_info_save(CamelFolderSummary *s, FILE *out_meta, FILE *out, CamelMe
 	io(printf("saving mbox message info\n"));
 
 	if (((CamelFolderSummaryClass *)camel_mbox_summary_parent)->meta_message_info_save(s, out_meta, out, mi) == -1
-	    || camel_file_util_encode_off_t(out_meta, mbi->frompos) == -1)
+	   || camel_file_util_encode_off_t (out, mbi->frompos) == -1)
 		return -1;
 
 	return 0;
@@ -498,7 +498,7 @@ message_info_save(CamelFolderSummary *s, FILE *out, CamelMessageInfo *mi)
 	io(printf("saving mbox message info\n"));
 
 	if (((CamelFolderSummaryClass *)camel_mbox_summary_parent)->message_info_save(s, out, mi) == -1
-	    || camel_file_util_encode_off_t (out, mbi->frompos) == -1)
+	    || camel_file_util_encode_off_t (out, (off_t) mbi->frompos) == -1)
 		return -1;
 
 	return 0;
@@ -866,6 +866,7 @@ mbox_summary_sync_quick(CamelMboxSummary *mbs, gboolean expunge, CamelFolderChan
 	camel_mime_parser_scan_pre_from(mp, TRUE);
 	camel_mime_parser_init_with_fd(mp, pfd);
 
+	camel_folder_summary_lock_summary (s);
 	/* Sync only the changes */
 	summary = camel_folder_summary_get_changed ((CamelFolderSummary *)mbs);
 	if (summary->len)
@@ -964,6 +965,7 @@ mbox_summary_sync_quick(CamelMboxSummary *mbs, gboolean expunge, CamelFolderChan
 	camel_object_unref((CamelObject *)mp);
 
 	camel_operation_end(NULL);
+	camel_folder_summary_unlock_summary (s);
 
 	return 0;
  error:
@@ -977,6 +979,7 @@ mbox_summary_sync_quick(CamelMboxSummary *mbs, gboolean expunge, CamelFolderChan
 		camel_message_info_free((CamelMessageInfo *)info);
 
 	camel_operation_end(NULL);
+	camel_folder_summary_unlock_summary (s);
 
 	return -1;
 }
@@ -1090,6 +1093,7 @@ camel_mbox_summary_sync_mbox(CamelMboxSummary *cls, guint32 flags, CamelFolderCh
 	camel_mime_parser_scan_pre_from(mp, TRUE);
 	camel_mime_parser_init_with_fd(mp, fd);
 
+	camel_folder_summary_lock_summary (s);
 	count = camel_folder_summary_count(s);
 	for (i = 0; i < count; i++) {
 		gint pc = (i + 1) * 100 / count;
@@ -1254,6 +1258,8 @@ camel_mbox_summary_sync_mbox(CamelMboxSummary *cls, guint32 flags, CamelFolderCh
 	if (touched)
 		camel_folder_summary_header_save_to_db (s, ex);
 
+	camel_folder_summary_unlock_summary (s);
+
 	return 0;
  error:
 	g_free(xevnew);
@@ -1263,6 +1269,8 @@ camel_mbox_summary_sync_mbox(CamelMboxSummary *cls, guint32 flags, CamelFolderCh
 	if (info)
 		camel_message_info_free((CamelMessageInfo *)info);
 
+	camel_folder_summary_unlock_summary (s);
+
 	return -1;
 }
 
