aboutsummaryrefslogtreecommitdiffstats
path: root/mail
diff options
context:
space:
mode:
authorMilan Crha <mcrha@redhat.com>2008-02-22 18:49:55 +0800
committerMilan Crha <mcrha@src.gnome.org>2008-02-22 18:49:55 +0800
commitefb45db411d5f64e95cc2eba2501ff3f73239cb3 (patch)
tree1b296f58812fe164aa0a9bd600dbe46a3fe30121 /mail
parentbdb224def86d58bde4218fa8ed21d689242923f9 (diff)
downloadgsoc2013-evolution-efb45db411d5f64e95cc2eba2501ff3f73239cb3.tar
gsoc2013-evolution-efb45db411d5f64e95cc2eba2501ff3f73239cb3.tar.gz
gsoc2013-evolution-efb45db411d5f64e95cc2eba2501ff3f73239cb3.tar.bz2
gsoc2013-evolution-efb45db411d5f64e95cc2eba2501ff3f73239cb3.tar.lz
gsoc2013-evolution-efb45db411d5f64e95cc2eba2501ff3f73239cb3.tar.xz
gsoc2013-evolution-efb45db411d5f64e95cc2eba2501ff3f73239cb3.tar.zst
gsoc2013-evolution-efb45db411d5f64e95cc2eba2501ff3f73239cb3.zip
** Fix for bug #512776
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. svn path=/trunk/; revision=35071
Diffstat (limited to 'mail')
-rw-r--r--mail/ChangeLog20
-rw-r--r--mail/mail-component.c4
-rw-r--r--mail/mail-folder-cache.c11
-rw-r--r--mail/mail-folder-cache.h5
-rw-r--r--mail/mail-ops.c11
-rw-r--r--mail/mail-ops.h2
-rw-r--r--mail/mail-send-recv.c49
7 files changed, 69 insertions, 33 deletions
diff --git a/mail/ChangeLog b/mail/ChangeLog
index 1ce93c3513..0c543da306 100644
--- a/mail/ChangeLog
+++ b/mail/ChangeLog
@@ -1,5 +1,23 @@
+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.
+
2008-02-22 Srinivasa Ragavan <sragavan@novell.com>
-
+
** Fix for BNC #358697
* em-folder-browser.c: (emfb_set_folder): Make sure the default search
diff --git a/mail/mail-component.c b/mail/mail-component.c
index 879c346494..0e5e19a398 100644
--- a/mail/mail-component.c
+++ b/mail/mail-component.c
@@ -206,7 +206,7 @@ store_info_unref(struct _store_info *si)
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 @@ mc_add_store_done(CamelStore *store, CamelFolderInfo *info, void *data)
}
store_info_unref(si);
+
+ return TRUE;
}
/* Utility functions. */
diff --git a/mail/mail-folder-cache.c b/mail/mail-folder-cache.c
index b88d8f79ac..417f115999 100644
--- a/mail/mail-folder-cache.c
+++ b/mail/mail-folder-cache.c
@@ -723,7 +723,7 @@ struct _update_data {
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 @@ mail_note_store_remove(CamelStore *store)
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 @@ update_folders(CamelStore *store, CamelFolderInfo *fi, void *data)
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 @@ store_online_cb (CamelStore *store, void *data)
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;
diff --git a/mail/mail-folder-cache.h b/mail/mail-folder-cache.h
index 656d97135b..3c16e8c54e 100644
--- a/mail/mail-folder-cache.h
+++ b/mail/mail-folder-cache.h
@@ -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 */
diff --git a/mail/mail-ops.c b/mail/mail-ops.c
index 894d4d8c2f..f11c2e0258 100644
--- a/mail/mail-ops.c
+++ b/mail/mail-ops.c
@@ -1042,8 +1042,9 @@ struct _get_folderinfo_msg {
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 @@ get_folderinfo_done (struct _get_folderinfo_msg *m)
}
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 @@ static MailMsgInfo get_folderinfo_info = {
};
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;
diff --git a/mail/mail-ops.h b/mail/mail-ops.h
index e23e775645..8b532e896f 100644
--- a/mail/mail-ops.h
+++ b/mail/mail-ops.h
@@ -103,7 +103,7 @@ void mail_empty_trash (EAccount *account,
/* 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 */
diff --git a/mail/mail-send-recv.c b/mail/mail-send-recv.c
index 5c4454d7cb..3b922c549b 100644
--- a/mail/mail-send-recv.c
+++ b/mail/mail-send-recv.c
@@ -778,12 +778,30 @@ receive_get_folder(CamelFilterDriver *d, const char *uri, void *data, CamelExcep
/* ********************************************************************** */
+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 @@ refresh_folders_exec (struct _refresh_folders_msg *m)
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 @@ refresh_folders_free (struct _refresh_folders_msg *m)
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 @@ static MailMsgInfo refresh_folders_info = {
(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 @@ receive_update_got_folderinfo(CamelStore *store, CamelFolderInfo *info, void *da
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