** 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
This commit is contained in:
@ -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
|
||||
|
||||
@ -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. */
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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 */
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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 */
|
||||
|
||||
@ -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
|
||||
|
||||
Reference in New Issue
Block a user