evolution r35071 - trunk/mail



Author: mcrha
Date: Fri Feb 22 10:49:55 2008
New Revision: 35071
URL: http://svn.gnome.org/viewvc/evolution?rev=35071&view=rev

Log:
2008-02-22  Milan Crha  <mcrha redhat com>

	** Fix for bug #512776

	* Changes below prevents deadlock on start or send/receive.
	* mail-send-recv.c: (struct _refresh_folders_msg),
	(refresh_folders_exec), (refresh_folders_free),
	(receive_update_got_folderinfo): Do not look for active folders in
	main thread, rather do it in other thread and free folder info later.
	* mail-ops.h: (mail_get_folderinfo):
	* mail-ops.c: (struct _get_folderinfo_msg), (get_folderinfo_done),
	(get_folderinfo_free), (mail_get_folderinfo):
	* mail-folder-cache.h: (mail_note_store):
	* mail-folder-cache.c: (struct _update_data), (update_folders),
	(mail_note_store):
	* mail-component.c: (mc_add_store_done): 
	The 'done' function returns if we can free folder info or not.



Modified:
   trunk/mail/ChangeLog
   trunk/mail/mail-component.c
   trunk/mail/mail-folder-cache.c
   trunk/mail/mail-folder-cache.h
   trunk/mail/mail-ops.c
   trunk/mail/mail-ops.h
   trunk/mail/mail-send-recv.c

Modified: trunk/mail/mail-component.c
==============================================================================
--- trunk/mail/mail-component.c	(original)
+++ trunk/mail/mail-component.c	Fri Feb 22 10:49:55 2008
@@ -206,7 +206,7 @@
 	g_free(si);
 }
 
-static void
+static gboolean
 mc_add_store_done(CamelStore *store, CamelFolderInfo *info, void *data)
 {
 	struct _store_info *si = data;
@@ -223,6 +223,8 @@
 	}
 
 	store_info_unref(si);
+
+	return TRUE;
 }
 
 /* Utility functions.  */

Modified: trunk/mail/mail-folder-cache.c
==============================================================================
--- trunk/mail/mail-folder-cache.c	(original)
+++ trunk/mail/mail-folder-cache.c	Fri Feb 22 10:49:55 2008
@@ -723,7 +723,7 @@
 	int id;			/* id for cancellation */
 	guint cancel:1;		/* also tells us we're cancelled */
 
-	void (*done)(CamelStore *store, CamelFolderInfo *info, void *data);
+	gboolean (*done)(CamelStore *store, CamelFolderInfo *info, void *data);
 	void *data;
 };
 
@@ -782,11 +782,12 @@
 	UNLOCK(info_lock);
 }
 
-static void
+static gboolean
 update_folders(CamelStore *store, CamelFolderInfo *fi, void *data)
 {
 	struct _update_data *ud = data;
 	struct _store_info *si;
+	gboolean res = TRUE;
 
 	d(printf("Got folderinfo for store %s\n", store->parent_object.provider->protocol));
 
@@ -803,8 +804,10 @@
 	UNLOCK(info_lock);
 
 	if (ud->done)
-		ud->done(store, fi, ud->data);
+		res = ud->done (store, fi, ud->data);
 	g_free(ud);
+
+	return res;
 }
 
 
@@ -906,7 +909,7 @@
 
 void
 mail_note_store(CamelStore *store, CamelOperation *op,
-		void (*done)(CamelStore *store, CamelFolderInfo *info, void *data), void *data)
+		gboolean (*done)(CamelStore *store, CamelFolderInfo *info, void *data), void *data)
 {
 	struct _store_info *si;
 	struct _update_data *ud;

Modified: trunk/mail/mail-folder-cache.h
==============================================================================
--- trunk/mail/mail-folder-cache.h	(original)
+++ trunk/mail/mail-folder-cache.h	Fri Feb 22 10:49:55 2008
@@ -29,10 +29,11 @@
 
 /* Add a store whose folders should appear in the shell
    The folders are scanned from the store, and/or added at
-   runtime via the folder_created event */
+   runtime via the folder_created event.
+   The 'done' function returns if we can free folder info. */
 void
 mail_note_store (CamelStore *store, CamelOperation *op,
-		 void (*done) (CamelStore *store, CamelFolderInfo *info, void *data),
+		 gboolean (*done) (CamelStore *store, CamelFolderInfo *info, void *data),
 		 void *data);
 
 /* de-note a store */

Modified: trunk/mail/mail-ops.c
==============================================================================
--- trunk/mail/mail-ops.c	(original)
+++ trunk/mail/mail-ops.c	Fri Feb 22 10:49:55 2008
@@ -1042,8 +1042,9 @@
 
 	CamelStore *store;
 	CamelFolderInfo *info;
-	void (*done)(CamelStore *store, CamelFolderInfo *info, void *data);
+	gboolean (*done)(CamelStore *store, CamelFolderInfo *info, void *data);
 	void *data;
+	gboolean can_clear; /* whether we can clear folder info */
 };
 
 static gchar *
@@ -1078,13 +1079,15 @@
 	}
 
 	if (m->done)
-		m->done (m->store, m->info, m->data);
+		m->can_clear = m->done (m->store, m->info, m->data);
+	else
+		m->can_clear = TRUE;
 }
 
 static void
 get_folderinfo_free (struct _get_folderinfo_msg *m)
 {
-	if (m->info)
+	if (m->info && m->can_clear)
 		camel_store_free_folder_info(m->store, m->info);
 	camel_object_unref(m->store);
 }
@@ -1098,7 +1101,7 @@
 };
 
 int
-mail_get_folderinfo (CamelStore *store, CamelOperation *op, void (*done)(CamelStore *store, CamelFolderInfo *info, void *data), void *data)
+mail_get_folderinfo (CamelStore *store, CamelOperation *op, gboolean (*done)(CamelStore *store, CamelFolderInfo *info, void *data), void *data)
 {
 	struct _get_folderinfo_msg *m;
 	int id;

Modified: trunk/mail/mail-ops.h
==============================================================================
--- trunk/mail/mail-ops.h	(original)
+++ trunk/mail/mail-ops.h	Fri Feb 22 10:49:55 2008
@@ -103,7 +103,7 @@
 
 /* get folder info asynchronously */
 int mail_get_folderinfo (CamelStore *store, CamelOperation *op,
-			 void (*done)(CamelStore *store, CamelFolderInfo *info, void *data),
+			 gboolean (*done)(CamelStore *store, CamelFolderInfo *info, void *data),
 			 void *data);
 
 /* remove an existing folder */

Modified: trunk/mail/mail-send-recv.c
==============================================================================
--- trunk/mail/mail-send-recv.c	(original)
+++ trunk/mail/mail-send-recv.c	Fri Feb 22 10:49:55 2008
@@ -778,12 +778,30 @@
 
 /* ********************************************************************** */
 
+static void
+get_folders (CamelStore *store, GPtrArray *folders, CamelFolderInfo *info)
+{
+	CamelException ex;
+
+	camel_exception_init (&ex);
+
+	while (info) {
+		if (camel_store_can_refresh_folder (store, info, &ex))
+			g_ptr_array_add (folders, g_strdup (info->uri));
+		camel_exception_clear (&ex);
+
+		get_folders (store, folders, info->child);
+		info = info->next;
+	}
+}
+
 struct _refresh_folders_msg {
 	MailMsg base;
 
 	struct _send_info *info;
 	GPtrArray *folders;
 	CamelStore *store;
+	CamelFolderInfo *finfo;
 };
 
 static gchar *
@@ -799,6 +817,8 @@
 	CamelFolder *folder;
 	CamelException ex = CAMEL_EXCEPTION_INITIALISER;
 
+	get_folders (m->store, m->folders, m->finfo);
+
 	for (i=0;i<m->folders->len;i++) {
 		folder = mail_tool_uri_to_folder(m->folders->pdata[i], 0, &ex);
 		if (folder) {
@@ -829,6 +849,8 @@
 	for (i=0;i<m->folders->len;i++)
 		g_free(m->folders->pdata[i]);
 	g_ptr_array_free(m->folders, TRUE);
+
+	camel_store_free_folder_info (m->store, m->finfo);
 	camel_object_unref(m->store);
 }
 
@@ -840,24 +862,7 @@
 	(MailMsgFreeFunc) refresh_folders_free
 };
 
-static void
-get_folders (CamelStore *store, GPtrArray *folders, CamelFolderInfo *info)
-{
-	CamelException ex;
-
-	camel_exception_init (&ex);
-
-	while (info) {
-		if (camel_store_can_refresh_folder (store, info, &ex))
-			g_ptr_array_add (folders, g_strdup (info->uri));
-		camel_exception_clear (&ex);
-
-		get_folders (store, folders, info->child);
-		info = info->next;
-	}
-}
-
-static void
+static gboolean
 receive_update_got_folderinfo(CamelStore *store, CamelFolderInfo *info, void *data)
 {
 	if (info) {
@@ -865,18 +870,22 @@
 		struct _refresh_folders_msg *m;
 		struct _send_info *sinfo = data;
 
-		get_folders(store, folders, info);
-
 		m = mail_msg_new(&refresh_folders_info);
 		m->store = store;
 		camel_object_ref(store);
 		m->folders = folders;
 		m->info = sinfo;
+		m->finfo = info;
 
 		mail_msg_unordered_push (m);
+
+		/* do not free folder info, we will free it later */
+		return FALSE;
 	} else {
 		receive_done ("", data);
 	}
+
+	return TRUE;
 }
 
 static void



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]