[evolution-data-server/gnome-2-30] Bug 622719 - Fix lifetime issues with CamelIMAPXServer w.r.t. disconnection (cherry picked from comm
- From: David Woodhouse <dwmw2 src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-data-server/gnome-2-30] Bug 622719 - Fix lifetime issues with CamelIMAPXServer w.r.t. disconnection (cherry picked from comm
- Date: Sat, 31 Jul 2010 15:27:40 +0000 (UTC)
commit 51920efa6ea9a3c82a22827088c618207cd90e02
Author: David Woodhouse <David Woodhouse intel com>
Date: Sat Jul 31 16:03:08 2010 +0200
Bug 622719 - Fix lifetime issues with CamelIMAPXServer w.r.t. disconnection
(cherry picked from commit 6e49273e99bfe8f5e1ed080a454d0e3aeacae4f8)
Note contents of imapx_server_dispose() from HEAD have moved to
imapx_server_finalize() in gnome-2-30 because CamelObjects don't have a
separate dispose() method.
camel/providers/imapx/camel-imapx-folder.c | 60 +++++++++----
camel/providers/imapx/camel-imapx-server.c | 81 ++++++++++-------
camel/providers/imapx/camel-imapx-server.h | 2 +-
camel/providers/imapx/camel-imapx-store.c | 132 ++++++++++++++++++++++------
camel/providers/imapx/camel-imapx-store.h | 1 +
5 files changed, 197 insertions(+), 79 deletions(-)
---
diff --git a/camel/providers/imapx/camel-imapx-folder.c b/camel/providers/imapx/camel-imapx-folder.c
index 3d9b0c0..bdd398d 100644
--- a/camel/providers/imapx/camel-imapx-folder.c
+++ b/camel/providers/imapx/camel-imapx-folder.c
@@ -129,25 +129,33 @@ static void
imapx_refresh_info (CamelFolder *folder, CamelException *ex)
{
CamelIMAPXStore *istore = (CamelIMAPXStore *)folder->parent_store;
+ CamelIMAPXServer *server;
if (CAMEL_OFFLINE_STORE (istore)->state == CAMEL_OFFLINE_STORE_NETWORK_UNAVAIL)
return;
camel_service_connect((CamelService *)istore, ex);
- if (istore->server && camel_imapx_server_connect (istore->server, TRUE, ex))
- camel_imapx_server_refresh_info(istore->server, folder, ex);
+ server = camel_imapx_store_get_server(istore, ex);
+ if (server) {
+ camel_imapx_server_refresh_info(server, folder, ex);
+ camel_object_unref(server);
+ }
}
static void
imapx_expunge (CamelFolder *folder, CamelException *ex)
{
CamelIMAPXStore *is = (CamelIMAPXStore *)folder->parent_store;
+ CamelIMAPXServer *server;
if (CAMEL_OFFLINE_STORE (is)->state == CAMEL_OFFLINE_STORE_NETWORK_UNAVAIL)
return;
- if (is->server && camel_imapx_server_connect (is->server, TRUE, ex))
- camel_imapx_server_expunge(is->server, folder, ex);
+ server = camel_imapx_store_get_server(is, ex);
+ if (server) {
+ camel_imapx_server_expunge(server, folder, ex);
+ camel_object_unref(server);
+ }
}
@@ -155,6 +163,7 @@ static void
imapx_sync (CamelFolder *folder, gboolean expunge, CamelException *ex)
{
CamelIMAPXStore *is = (CamelIMAPXStore *)folder->parent_store;
+ CamelIMAPXServer *server;
CamelException eex = CAMEL_EXCEPTION_INITIALISER;
if (CAMEL_OFFLINE_STORE (is)->state == CAMEL_OFFLINE_STORE_NETWORK_UNAVAIL)
@@ -163,17 +172,20 @@ imapx_sync (CamelFolder *folder, gboolean expunge, CamelException *ex)
if (!ex)
ex = &eex;
- if (is->server && camel_imapx_server_connect (is->server, TRUE, ex))
- camel_imapx_server_sync_changes (is->server, folder, ex);
+ server = camel_imapx_store_get_server(is, ex);
+ if (server)
+ camel_imapx_server_sync_changes (server, folder, ex);
/* Sync twice - make sure deleted flags are written out,
then sync again incase expunge changed anything */
camel_exception_clear(ex);
- if (is->server && expunge) {
- camel_imapx_server_expunge(is->server, folder, ex);
+ if (server && expunge) {
+ camel_imapx_server_expunge(server, folder, ex);
camel_exception_clear(ex);
}
+ if (server)
+ camel_object_unref(server);
}
static CamelMimeMessage *
@@ -183,6 +195,7 @@ imapx_get_message (CamelFolder *folder, const gchar *uid, CamelException *ex)
CamelStream *stream = NULL;
CamelIMAPXStore *istore = (CamelIMAPXStore *)folder->parent_store;
CamelIMAPXFolder *ifolder = (CamelIMAPXFolder *) folder;
+ CamelIMAPXServer *server;
const gchar *path = NULL;
gboolean offline_message = FALSE;
@@ -203,9 +216,12 @@ imapx_get_message (CamelFolder *folder, const gchar *uid, CamelException *ex)
if (CAMEL_OFFLINE_STORE (istore)->state == CAMEL_OFFLINE_STORE_NETWORK_UNAVAIL)
return NULL;
- if (istore->server && camel_imapx_server_connect (istore->server, TRUE, ex)) {
- stream = camel_imapx_server_get_message(istore->server, folder, uid, ex);
+ server = camel_imapx_store_get_server(istore, ex);
+ if (server) {
+ stream = camel_imapx_server_get_message(server, folder, uid, ex);
+ camel_object_unref(server);
} else {
+ /* It should _always_ be set */
if (!camel_exception_is_set (ex))
camel_exception_setv(ex, 1, "not authenticated");
return NULL;
@@ -231,12 +247,16 @@ static void
imapx_sync_message (CamelFolder *folder, const gchar *uid, CamelException *ex)
{
CamelIMAPXStore *istore = (CamelIMAPXStore *)folder->parent_store;
+ CamelIMAPXServer *server;
if (CAMEL_OFFLINE_STORE (istore)->state == CAMEL_OFFLINE_STORE_NETWORK_UNAVAIL)
return;
- if (istore->server && camel_imapx_server_connect (istore->server, TRUE, ex))
- camel_imapx_server_sync_message (istore->server, folder, uid, ex);
+ server = camel_imapx_store_get_server(istore, ex);
+ if (server) {
+ camel_imapx_server_sync_message (server, folder, uid, ex);
+ camel_object_unref(server);
+ }
}
static void
@@ -245,12 +265,16 @@ imapx_transfer_messages_to (CamelFolder *source, GPtrArray *uids,
gboolean delete_originals, CamelException *ex)
{
CamelIMAPXStore *istore = (CamelIMAPXStore *) source->parent_store;
+ CamelIMAPXServer *server;
if (CAMEL_OFFLINE_STORE (istore)->state == CAMEL_OFFLINE_STORE_NETWORK_UNAVAIL)
return;
- if (istore->server && camel_imapx_server_connect (istore->server, TRUE, ex))
- camel_imapx_server_copy_message (istore->server, source, dest, uids, delete_originals, ex);
+ server = camel_imapx_store_get_server(istore, ex);
+ if (server) {
+ camel_imapx_server_copy_message (server, source, dest, uids, delete_originals, ex);
+ camel_object_unref(server);
+ }
imapx_refresh_info (dest, ex);
}
@@ -259,6 +283,7 @@ static void
imapx_append_message(CamelFolder *folder, CamelMimeMessage *message, const CamelMessageInfo *info, gchar **appended_uid, CamelException *ex)
{
CamelIMAPXStore *istore = (CamelIMAPXStore *)folder->parent_store;
+ CamelIMAPXServer *server;
if (CAMEL_OFFLINE_STORE (istore)->state == CAMEL_OFFLINE_STORE_NETWORK_UNAVAIL)
return;
@@ -266,8 +291,11 @@ imapx_append_message(CamelFolder *folder, CamelMimeMessage *message, const Camel
if (appended_uid)
*appended_uid = NULL;
- if (istore->server && camel_imapx_server_connect (istore->server, TRUE, ex))
- camel_imapx_server_append_message(istore->server, folder, message, info, ex);
+ server = camel_imapx_store_get_server(istore, ex);
+ if (server) {
+ camel_imapx_server_append_message(server, folder, message, info, ex);
+ camel_object_unref(server);
+ }
}
gchar *
diff --git a/camel/providers/imapx/camel-imapx-server.c b/camel/providers/imapx/camel-imapx-server.c
index 70f3cea..fd87c67 100644
--- a/camel/providers/imapx/camel-imapx-server.c
+++ b/camel/providers/imapx/camel-imapx-server.c
@@ -170,6 +170,7 @@ static gboolean imapx_is_command_queue_empty (CamelIMAPXServer *is);
/* states for the connection? */
enum {
IMAPX_DISCONNECTED,
+ IMAPX_SHUTDOWN,
IMAPX_CONNECTED,
IMAPX_AUTHENTICATED,
IMAPX_INITIALISED,
@@ -1013,6 +1014,15 @@ imapx_command_queue(CamelIMAPXServer *is, CamelIMAPXCommand *ic)
QUEUE_LOCK(is);
+ if (is->state == IMAPX_SHUTDOWN) {
+ c(printf("refuse to queue job on disconnected server\n"));
+ camel_exception_set(ic->ex, 1, "Server disconnected");
+ QUEUE_UNLOCK(is);
+ if (ic->complete)
+ ic->complete(is, ic);
+ return;
+ }
+
scan = (CamelIMAPXCommand *)is->queue.head;
if (scan->next == NULL)
camel_dlist_addtail(&is->queue, (CamelDListNode *)ic);
@@ -1530,7 +1540,8 @@ imapx_untagged(CamelIMAPXServer *imap, CamelException *ex)
c(printf("BYE: %s\n", token));
camel_exception_setv(ex, 1, "IMAP server said BYE: %s", token);
}
- break;
+ imap->state = IMAPX_SHUTDOWN;
+ return -1;
}
case IMAPX_PREAUTH:
c(printf("preauthenticated\n"));
@@ -4301,7 +4312,7 @@ imapx_parser_thread (gpointer d)
errno = EINTR;
}
- if (camel_application_is_exiting || is->parser_quit) {
+ if (is->parser_quit) {
camel_exception_setv (&ex, CAMEL_EXCEPTION_USER_CANCEL, "Operation Cancelled: %s", g_strerror(errno));
break;
}
@@ -4320,11 +4331,11 @@ imapx_parser_thread (gpointer d)
}
}
- imapx_disconnect (is);
- cancel_all_jobs (is, &ex);
+ QUEUE_LOCK(is);
+ is->state = IMAPX_SHUTDOWN;
+ QUEUE_UNLOCK(is);
- if (imapx_idle_supported (is))
- imapx_exit_idle (is);
+ cancel_all_jobs (is, &ex);
camel_exception_clear (&ex);
@@ -4378,11 +4389,29 @@ imapx_server_init(CamelIMAPXServer *is, CamelIMAPXServerClass *isclass)
static void
imapx_server_finalise(CamelIMAPXServer *is, CamelIMAPXServerClass *isclass)
{
+ e(printf("imapx_server_finalise\n"));
+
+ QUEUE_LOCK(is);
+ is->state = IMAPX_SHUTDOWN;
+ QUEUE_UNLOCK(is);
+
+ is->parser_quit = TRUE;
+ camel_operation_cancel (is->op);
+
+ if (is->parser_thread)
+ g_thread_join (is->parser_thread);
+
+ if (imapx_idle_supported (is))
+ imapx_exit_idle (is);
+
+ imapx_disconnect (is);
+
g_static_rec_mutex_free(&is->queue_lock);
g_static_rec_mutex_free (&is->ostream_lock);
g_hash_table_destroy (is->uid_eflags);
camel_folder_change_info_free (is->changes);
+
}
CamelType
@@ -4463,39 +4492,23 @@ imapx_disconnect (CamelIMAPXServer *is)
/* Client commands */
gboolean
-camel_imapx_server_connect (CamelIMAPXServer *is, gboolean connect, CamelException *ex)
+camel_imapx_server_connect (CamelIMAPXServer *is, CamelException *ex)
{
- gboolean ret = FALSE;
-
- CAMEL_SERVICE_REC_LOCK (is->store, connect_lock);
- if (connect) {
- if (is->state >= IMAPX_INITIALISED) {
- ret = TRUE;
- goto exit;
- }
+ if (is->state == IMAPX_SHUTDOWN)
+ return FALSE;
- g_static_rec_mutex_lock (&is->ostream_lock);
- imapx_reconnect (is, ex);
- g_static_rec_mutex_unlock (&is->ostream_lock);
+ if (is->state >= IMAPX_INITIALISED)
+ return TRUE;
- if (camel_exception_is_set (ex)) {
- ret = FALSE;
- goto exit;
- }
+ g_static_rec_mutex_lock (&is->ostream_lock);
+ imapx_reconnect (is, ex);
+ g_static_rec_mutex_unlock (&is->ostream_lock);
- is->parser_thread = g_thread_create((GThreadFunc) imapx_parser_thread, is, TRUE, NULL);
- ret = TRUE;
- } else {
- is->parser_quit = TRUE;
- camel_operation_cancel (is->op);
- if (is->parser_thread)
- g_thread_join (is->parser_thread);
- ret = TRUE;
- }
+ if (camel_exception_is_set (ex))
+ return FALSE;
-exit:
- CAMEL_SERVICE_REC_UNLOCK (is->store, connect_lock);
- return ret;
+ is->parser_thread = g_thread_create((GThreadFunc) imapx_parser_thread, is, TRUE, NULL);
+ return TRUE;
}
static CamelStream *
diff --git a/camel/providers/imapx/camel-imapx-server.h b/camel/providers/imapx/camel-imapx-server.h
index 502769d..e72a245 100644
--- a/camel/providers/imapx/camel-imapx-server.h
+++ b/camel/providers/imapx/camel-imapx-server.h
@@ -116,7 +116,7 @@ struct _CamelIMAPXServerClass {
CamelType camel_imapx_server_get_type (void);
CamelIMAPXServer *camel_imapx_server_new(struct _CamelStore *store, struct _CamelURL *url);
-gboolean camel_imapx_server_connect(CamelIMAPXServer *is, gint state, CamelException *ex);
+gboolean camel_imapx_server_connect(CamelIMAPXServer *is, CamelException *ex);
gboolean imapx_connect_to_server (CamelIMAPXServer *is, CamelException *ex);
GPtrArray *camel_imapx_server_list(CamelIMAPXServer *is, const gchar *top, guint32 flags, const gchar *ext, CamelException *ex);
diff --git a/camel/providers/imapx/camel-imapx-store.c b/camel/providers/imapx/camel-imapx-store.c
index 5d12bd2..90b4780 100644
--- a/camel/providers/imapx/camel-imapx-store.c
+++ b/camel/providers/imapx/camel-imapx-store.c
@@ -204,16 +204,48 @@ imapx_get_name (CamelService *service, gboolean brief)
service->url->user, service->url->host);
}
+CamelIMAPXServer *
+camel_imapx_store_get_server(CamelIMAPXStore *store, CamelException *ex)
+{
+ CamelIMAPXServer *server = NULL;
+
+ CAMEL_SERVICE_REC_LOCK (store, connect_lock);
+
+ if (store->server && camel_imapx_server_connect(store->server, ex)) {
+ camel_object_ref(store->server);
+ server = store->server;
+ } else {
+ if (store->server) {
+ camel_object_unref(store->server);
+ store->server = NULL;
+ }
+
+ server = camel_imapx_server_new(CAMEL_STORE(store), CAMEL_SERVICE(store)->url);
+ if (camel_imapx_server_connect(server, ex)) {
+ store->server = server;
+ camel_object_ref(server);
+ } else {
+ camel_object_unref(server);
+ server = NULL;
+ }
+ }
+ CAMEL_SERVICE_REC_UNLOCK (store, connect_lock);
+ return server;
+}
+
static gboolean
imapx_connect (CamelService *service, CamelException *ex)
{
CamelIMAPXStore *istore = (CamelIMAPXStore *)service;
+ CamelIMAPXServer *server;
- /* We never really are 'connected' or 'disconnected' */
- if (istore->server == NULL)
- istore->server = camel_imapx_server_new((CamelStore *)istore, service->url);
+ server = camel_imapx_store_get_server(istore, ex);
+ if (server) {
+ camel_object_unref(server);
+ return TRUE;
+ }
- return camel_imapx_server_connect (istore->server, TRUE, ex);
+ return FALSE;
}
static gboolean
@@ -223,8 +255,14 @@ imapx_disconnect (CamelService *service, gboolean clean, CamelException *ex)
CAMEL_SERVICE_CLASS (parent_class)->disconnect (service, clean, ex);
- if (istore->server)
- camel_imapx_server_connect(istore->server, FALSE, ex);
+ CAMEL_SERVICE_REC_LOCK (service, connect_lock);
+
+ if (istore->server) {
+ camel_object_unref(istore->server);
+ istore->server = NULL;
+ }
+
+ CAMEL_SERVICE_REC_UNLOCK (service, connect_lock);
return TRUE;
}
@@ -267,12 +305,16 @@ static void
imapx_noop (CamelStore *store, CamelException *ex)
{
CamelIMAPXStore *istore = (CamelIMAPXStore *) store;
+ CamelIMAPXServer *server;
if (CAMEL_OFFLINE_STORE(store)->state == CAMEL_OFFLINE_STORE_NETWORK_UNAVAIL)
return;
- if (istore->server && camel_imapx_server_connect (istore->server, TRUE, ex))
- camel_imapx_server_noop (istore->server, NULL, ex);
+ server = camel_imapx_store_get_server(istore, ex);
+ if (server) {
+ camel_imapx_server_noop (server, NULL, ex);
+ camel_object_unref(server);
+ }
}
static guint
@@ -528,12 +570,17 @@ static void
imapx_subscribe_folder (CamelStore *store, const gchar *folder_name, gboolean emit_signal, CamelException *ex)
{
CamelIMAPXStore *istore = (CamelIMAPXStore *) store;
+ CamelIMAPXServer *server;
if (CAMEL_OFFLINE_STORE(store)->state == CAMEL_OFFLINE_STORE_NETWORK_UNAVAIL)
return;
- if (istore->server && camel_imapx_server_connect (istore->server, TRUE, ex))
- camel_imapx_server_manage_subscription (istore->server, folder_name, TRUE, ex);
+ server = camel_imapx_store_get_server(istore, ex);
+ if (!server)
+ return;
+
+ camel_imapx_server_manage_subscription (server, folder_name, TRUE, ex);
+ camel_object_unref(server);
if (!camel_exception_is_set (ex))
imapx_mark_folder_subscribed (istore, folder_name, emit_signal, ex);
@@ -543,12 +590,17 @@ static void
imapx_unsubscribe_folder (CamelStore *store, const gchar *folder_name, gboolean emit_signal, CamelException *ex)
{
CamelIMAPXStore *istore = (CamelIMAPXStore *) store;
+ CamelIMAPXServer *server;
if (CAMEL_OFFLINE_STORE(store)->state == CAMEL_OFFLINE_STORE_NETWORK_UNAVAIL)
return;
- if (istore->server && camel_imapx_server_connect (istore->server, TRUE, ex))
- camel_imapx_server_manage_subscription (istore->server, folder_name, FALSE, ex);
+ server = camel_imapx_store_get_server(istore, ex);
+ if (!server)
+ return;
+
+ camel_imapx_server_manage_subscription (server, folder_name, FALSE, ex);
+ camel_object_unref(server);
if (!camel_exception_is_set (ex))
imapx_unmark_folder_subscribed (istore, folder_name, emit_signal, ex);
@@ -614,15 +666,19 @@ static void
imapx_delete_folder (CamelStore *store, const gchar *folder_name, CamelException *ex)
{
CamelIMAPXStore *istore = (CamelIMAPXStore *) store;
+ CamelIMAPXServer *server;
if (CAMEL_OFFLINE_STORE (store)->state == CAMEL_OFFLINE_STORE_NETWORK_UNAVAIL) {
camel_exception_set (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
_("You must be working online to complete this operation"));
return;
}
+ server = camel_imapx_store_get_server(istore, ex);
+ if (!server)
+ return;
- if (istore->server && camel_imapx_server_connect (istore->server, TRUE, ex))
- camel_imapx_server_delete_folder (istore->server, folder_name, ex);
+ camel_imapx_server_delete_folder (server, folder_name, ex);
+ camel_object_unref(server);
if (!camel_exception_is_set (ex))
imapx_delete_folder_from_cache (istore, folder_name, ex);
@@ -665,6 +721,7 @@ static void
imapx_rename_folder (CamelStore *store, const gchar *old, const gchar *new, CamelException *ex)
{
CamelIMAPXStore *istore = (CamelIMAPXStore *) store;
+ CamelIMAPXServer *server;
gchar *oldpath, *newpath, *storage_path;
if (CAMEL_OFFLINE_STORE (store)->state == CAMEL_OFFLINE_STORE_NETWORK_UNAVAIL) {
@@ -676,8 +733,11 @@ imapx_rename_folder (CamelStore *store, const gchar *old, const gchar *new, Came
if (istore->rec_options & IMAPX_SUBSCRIPTIONS)
imapx_unsubscribe_folder (store, old, FALSE, ex);
- if (istore->server && camel_imapx_server_connect (istore->server, TRUE, ex))
- camel_imapx_server_rename_folder (istore->server, old, new, ex);
+ server = camel_imapx_store_get_server(istore, ex);
+ if (server) {
+ camel_imapx_server_rename_folder (server, old, new, ex);
+ camel_object_unref(server);
+ }
if (camel_exception_is_set (ex)) {
imapx_subscribe_folder (store, old, FALSE, ex);
@@ -711,6 +771,7 @@ imapx_create_folder (CamelStore *store, const gchar *parent_name, const gchar *f
CamelStoreInfo *si;
CamelIMAPXStoreNamespace *ns;
CamelIMAPXStore *istore = (CamelIMAPXStore *) store;
+ CamelIMAPXServer *server;
gchar *real_name, *full_name, *parent_real;
CamelFolderInfo *fi = NULL;
gchar dir_sep;
@@ -721,7 +782,8 @@ imapx_create_folder (CamelStore *store, const gchar *parent_name, const gchar *f
return NULL;
}
- if (!(istore->server && camel_imapx_server_connect (istore->server, TRUE, ex)))
+ server = camel_imapx_store_get_server(istore, ex);
+ if (!server)
return NULL;
if (!parent_name)
@@ -737,6 +799,7 @@ imapx_create_folder (CamelStore *store, const gchar *parent_name, const gchar *f
camel_exception_setv (ex, CAMEL_EXCEPTION_FOLDER_INVALID_PATH,
_("The folder name \"%s\" is invalid because it contains the character \"%c\""),
folder_name, dir_sep);
+ camel_object_unref(server);
return NULL;
}
@@ -744,6 +807,7 @@ imapx_create_folder (CamelStore *store, const gchar *parent_name, const gchar *f
if (parent_real == NULL) {
camel_exception_setv(ex, CAMEL_EXCEPTION_FOLDER_INVALID_STATE,
_("Unknown parent folder: %s"), parent_name);
+ camel_object_unref(server);
return NULL;
}
@@ -751,6 +815,7 @@ imapx_create_folder (CamelStore *store, const gchar *parent_name, const gchar *f
if (si && si->flags & CAMEL_STORE_INFO_FOLDER_NOINFERIORS) {
camel_exception_set (ex, CAMEL_EXCEPTION_FOLDER_INVALID_STATE,
_("The parent folder is not allowed to contain subfolders"));
+ camel_object_unref(server);
return NULL;
}
@@ -761,7 +826,8 @@ imapx_create_folder (CamelStore *store, const gchar *parent_name, const gchar *f
full_name = imapx_concat (istore, parent_real, real_name);
g_free(real_name);
- camel_imapx_server_create_folder (istore->server, full_name, ex);
+ camel_imapx_server_create_folder (server, full_name, ex);
+ camel_object_unref(server);
if (!camel_exception_is_set (ex)) {
CamelIMAPXStoreInfo *si;
@@ -886,7 +952,7 @@ get_folder_info_offline (CamelStore *store, const gchar *top,
}
static void
-add_folders_to_summary (CamelIMAPXStore *istore, GPtrArray *folders, GHashTable *table, gboolean subscribed)
+add_folders_to_summary (CamelIMAPXStore *istore, CamelIMAPXServer *server, GPtrArray *folders, GHashTable *table, gboolean subscribed)
{
gint i = 0;
@@ -909,8 +975,10 @@ add_folders_to_summary (CamelIMAPXStore *istore, GPtrArray *folders, GHashTable
}
si = camel_imapx_store_summary_add_from_full (istore->summary, li->name, li->separator);
- if (!si)
+ if (!si) {
+ camel_object_unref(server);
continue;
+ }
new_flags = (si->info.flags & (CAMEL_STORE_INFO_FOLDER_SUBSCRIBED | CAMEL_STORE_INFO_FOLDER_CHECK_FOR_NEW)) |
(li->flags & ~CAMEL_STORE_INFO_FOLDER_SUBSCRIBED);
@@ -969,15 +1037,16 @@ imapx_get_folders_free(gpointer k, gpointer v, gpointer d)
}
static void
-fetch_folders_for_pattern (CamelIMAPXStore *istore, const gchar *pattern, guint32 flags, const gchar *ext, GHashTable *table, CamelException *ex)
+fetch_folders_for_pattern (CamelIMAPXStore *istore, CamelIMAPXServer *server, const gchar *pattern, guint32 flags,
+ const gchar *ext, GHashTable *table, CamelException *ex)
{
GPtrArray *folders = NULL;
- folders = camel_imapx_server_list (istore->server, pattern, flags, ext, ex);
+ folders = camel_imapx_server_list (server, pattern, flags, ext, ex);
if (camel_exception_is_set (ex))
return;
- add_folders_to_summary (istore, folders, table, (flags & CAMEL_STORE_FOLDER_INFO_SUBSCRIBED));
+ add_folders_to_summary (istore, server, folders, table, (flags & CAMEL_STORE_FOLDER_INFO_SUBSCRIBED));
g_ptr_array_foreach (folders, free_list, folders);
g_ptr_array_free (folders, TRUE);
@@ -1004,9 +1073,14 @@ get_namespaces (CamelIMAPXStore *istore)
static GHashTable *
fetch_folders_for_namespaces (CamelIMAPXStore *istore, const gchar *pattern, gboolean sync, CamelException *ex)
{
+ CamelIMAPXServer *server;
GHashTable *folders = NULL;
GSList *namespaces = NULL, *l;
+ server = camel_imapx_store_get_server(istore, ex);
+ if (!server)
+ return NULL;
+
folders = g_hash_table_new (folder_hash, folder_eq);
namespaces = get_namespaces (istore);
@@ -1030,11 +1104,11 @@ fetch_folders_for_namespaces (CamelIMAPXStore *istore, const gchar *pattern, gbo
if (sync)
flags |= CAMEL_STORE_FOLDER_INFO_SUBSCRIPTION_LIST;
- if (istore->server->cinfo->capa & IMAPX_CAPABILITY_LIST_EXTENDED)
+ if (server->cinfo->capa & IMAPX_CAPABILITY_LIST_EXTENDED)
list_ext = "RETURN (SUBSCRIBED)";
flags |= CAMEL_STORE_FOLDER_INFO_RECURSIVE;
- fetch_folders_for_pattern (istore, pat, flags, list_ext, folders, ex);
+ fetch_folders_for_pattern (istore, server, pat, flags, list_ext, folders, ex);
if (camel_exception_is_set (ex)) {
g_free (pat);
goto exception;
@@ -1043,7 +1117,7 @@ fetch_folders_for_namespaces (CamelIMAPXStore *istore, const gchar *pattern, gbo
/* If the server doesn't support LIST-EXTENDED then we have to
issue LSUB to list the subscribed folders separately */
flags |= CAMEL_STORE_FOLDER_INFO_SUBSCRIBED;
- fetch_folders_for_pattern (istore, pat, flags, NULL, folders, ex);
+ fetch_folders_for_pattern (istore, server, pat, flags, NULL, folders, ex);
if (camel_exception_is_set (ex)) {
g_free (pat);
goto exception;
@@ -1052,15 +1126,17 @@ fetch_folders_for_namespaces (CamelIMAPXStore *istore, const gchar *pattern, gbo
g_free (pat);
if (pattern)
- return folders;
+ goto out;
ns = ns->next;
}
}
-
+ out:
+ camel_object_unref(server);
return folders;
exception:
+ camel_object_unref(server);
g_hash_table_destroy (folders);
return NULL;
}
diff --git a/camel/providers/imapx/camel-imapx-store.h b/camel/providers/imapx/camel-imapx-store.h
index fa08ab9..3cb1227 100644
--- a/camel/providers/imapx/camel-imapx-store.h
+++ b/camel/providers/imapx/camel-imapx-store.h
@@ -79,6 +79,7 @@ typedef struct {
/* Standard Camel function */
CamelType camel_imapx_store_get_type (void);
+struct _CamelIMAPXServer *camel_imapx_store_get_server(CamelIMAPXStore *store, CamelException *ex);
#ifdef __cplusplus
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]