[evolution-data-server] Bug 622719 - Fix lifetime issues with CamelIMAPXServer w.r.t. disconnection
- From: David Woodhouse <dwmw2 src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-data-server] Bug 622719 - Fix lifetime issues with CamelIMAPXServer w.r.t. disconnection
- Date: Mon, 28 Jun 2010 11:09:53 +0000 (UTC)
commit 6e49273e99bfe8f5e1ed080a454d0e3aeacae4f8
Author: David Woodhouse <David Woodhouse intel com>
Date: Sat Jun 26 14:47:25 2010 +0100
Bug 622719 - Fix lifetime issues with CamelIMAPXServer w.r.t. disconnection
camel/providers/imapx/camel-imapx-folder.c | 61 +++++++++----
camel/providers/imapx/camel-imapx-server.c | 87 +++++++++++-------
camel/providers/imapx/camel-imapx-server.h | 1 -
camel/providers/imapx/camel-imapx-store.c | 137 +++++++++++++++++++++-------
camel/providers/imapx/camel-imapx-store.h | 1 +
5 files changed, 202 insertions(+), 85 deletions(-)
---
diff --git a/camel/providers/imapx/camel-imapx-folder.c b/camel/providers/imapx/camel-imapx-folder.c
index 5b32cdc..53c647e 100644
--- a/camel/providers/imapx/camel-imapx-folder.c
+++ b/camel/providers/imapx/camel-imapx-folder.c
@@ -152,6 +152,7 @@ imapx_refresh_info (CamelFolder *folder, CamelException *ex)
{
CamelStore *parent_store;
CamelIMAPXStore *istore;
+ CamelIMAPXServer *server;
parent_store = camel_folder_get_parent_store (folder);
istore = CAMEL_IMAPX_STORE (parent_store);
@@ -160,8 +161,11 @@ imapx_refresh_info (CamelFolder *folder, CamelException *ex)
return TRUE;
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);
+ g_object_unref(server);
+ }
return !camel_exception_is_set (ex);
}
@@ -171,6 +175,7 @@ imapx_expunge (CamelFolder *folder, CamelException *ex)
{
CamelStore *parent_store;
CamelIMAPXStore *is;
+ CamelIMAPXServer *server;
parent_store = camel_folder_get_parent_store (folder);
is = CAMEL_IMAPX_STORE (parent_store);
@@ -178,8 +183,11 @@ imapx_expunge (CamelFolder *folder, CamelException *ex)
if (CAMEL_OFFLINE_STORE (is)->state == CAMEL_OFFLINE_STORE_NETWORK_UNAVAIL)
return TRUE;
- 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);
+ g_object_unref(server);
+ }
return !camel_exception_is_set (ex);
}
@@ -189,6 +197,7 @@ imapx_sync (CamelFolder *folder, gboolean expunge, CamelException *ex)
{
CamelStore *parent_store;
CamelIMAPXStore *is;
+ CamelIMAPXServer *server;
CamelException eex = CAMEL_EXCEPTION_INITIALISER;
parent_store = camel_folder_get_parent_store (folder);
@@ -200,17 +209,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)
+ g_object_unref(server);
return !camel_exception_is_set (ex);
}
@@ -223,6 +235,7 @@ imapx_get_message (CamelFolder *folder, const gchar *uid, CamelException *ex)
CamelStore *parent_store;
CamelIMAPXStore *istore;
CamelIMAPXFolder *ifolder = (CamelIMAPXFolder *) folder;
+ CamelIMAPXServer *server;
const gchar *path = NULL;
gboolean offline_message = FALSE;
@@ -246,9 +259,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);
+ g_object_unref(server);
} else {
+ /* It should _always_ be set */
if (!camel_exception_is_set (ex))
camel_exception_setv(ex, 1, "not authenticated");
return NULL;
@@ -275,6 +291,7 @@ imapx_sync_message (CamelFolder *folder, const gchar *uid, CamelException *ex)
{
CamelStore *parent_store;
CamelIMAPXStore *istore;
+ CamelIMAPXServer *server;
parent_store = camel_folder_get_parent_store (folder);
istore = CAMEL_IMAPX_STORE (parent_store);
@@ -282,9 +299,11 @@ imapx_sync_message (CamelFolder *folder, const gchar *uid, CamelException *ex)
if (CAMEL_OFFLINE_STORE (istore)->state == CAMEL_OFFLINE_STORE_NETWORK_UNAVAIL)
return TRUE;
- 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);
+ g_object_unref(server);
+ }
return !camel_exception_is_set (ex);
}
@@ -295,6 +314,7 @@ imapx_transfer_messages_to (CamelFolder *source, GPtrArray *uids,
{
CamelStore *parent_store;
CamelIMAPXStore *istore;
+ CamelIMAPXServer *server;
parent_store = camel_folder_get_parent_store (source);
istore = CAMEL_IMAPX_STORE (parent_store);
@@ -302,8 +322,11 @@ imapx_transfer_messages_to (CamelFolder *source, GPtrArray *uids,
if (CAMEL_OFFLINE_STORE (istore)->state == CAMEL_OFFLINE_STORE_NETWORK_UNAVAIL)
return TRUE;
- 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);
+ g_object_unref(server);
+ }
imapx_refresh_info (dest, ex);
@@ -315,6 +338,7 @@ imapx_append_message(CamelFolder *folder, CamelMimeMessage *message, const Camel
{
CamelStore *parent_store;
CamelIMAPXStore *istore;
+ CamelIMAPXServer *server;
parent_store = camel_folder_get_parent_store (folder);
istore = CAMEL_IMAPX_STORE (parent_store);
@@ -325,8 +349,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);
+ g_object_unref(server);
+ }
return !camel_exception_is_set (ex);
}
diff --git a/camel/providers/imapx/camel-imapx-server.c b/camel/providers/imapx/camel-imapx-server.c
index 060825e..c17c5c8 100644
--- a/camel/providers/imapx/camel-imapx-server.c
+++ b/camel/providers/imapx/camel-imapx-server.c
@@ -148,6 +148,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,
@@ -1002,6 +1003,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);
@@ -1527,7 +1537,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"));
@@ -4368,7 +4379,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;
}
@@ -4387,11 +4398,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);
@@ -4435,6 +4446,29 @@ imapx_server_constructed (GObject *object)
if (class->tagprefix > 'Z')
class->tagprefix = 'A';
}
+static void
+imapx_server_dispose (GObject *object)
+{
+ CamelIMAPXServer *server = CAMEL_IMAPX_SERVER (object);
+
+ QUEUE_LOCK(server);
+ server->state = IMAPX_SHUTDOWN;
+ QUEUE_UNLOCK(server);
+
+ server->parser_quit = TRUE;
+ camel_operation_cancel (server->op);
+
+ if (server->parser_thread)
+ g_thread_join (server->parser_thread);
+
+ if (imapx_idle_supported (server))
+ imapx_exit_idle (server);
+
+ imapx_disconnect (server);
+
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (camel_imapx_server_parent_class)->dispose (object);
+}
static void
camel_imapx_server_class_init(CamelIMAPXServerClass *class)
@@ -4444,6 +4478,7 @@ camel_imapx_server_class_init(CamelIMAPXServerClass *class)
object_class = G_OBJECT_CLASS (class);
object_class->finalize = imapx_server_finalize;
object_class->constructed = imapx_server_constructed;
+ object_class->dispose = imapx_server_dispose;
class->tagprefix = 'A';
}
@@ -4529,39 +4564,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_lock (CAMEL_SERVICE (is->store), CAMEL_SERVICE_REC_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_unlock (CAMEL_SERVICE (is->store), CAMEL_SERVICE_REC_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 0f63d94..82e82ad 100644
--- a/camel/providers/imapx/camel-imapx-server.h
+++ b/camel/providers/imapx/camel-imapx-server.h
@@ -135,7 +135,6 @@ CamelIMAPXServer *
camel_imapx_server_new (CamelStore *store,
CamelURL *url);
gboolean camel_imapx_server_connect (CamelIMAPXServer *is,
- gint state,
CamelException *ex);
gboolean imapx_connect_to_server (CamelIMAPXServer *is,
CamelException *ex);
diff --git a/camel/providers/imapx/camel-imapx-store.c b/camel/providers/imapx/camel-imapx-store.c
index af619b5..ba5fff8 100644
--- a/camel/providers/imapx/camel-imapx-store.c
+++ b/camel/providers/imapx/camel-imapx-store.c
@@ -209,16 +209,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_lock (CAMEL_SERVICE (store), CAMEL_SERVICE_REC_CONNECT_LOCK);
+
+ if (store->server && camel_imapx_server_connect(store->server, ex)) {
+ g_object_ref(store->server);
+ server = store->server;
+ } else {
+ if (store->server) {
+ g_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;
+ g_object_ref(server);
+ } else {
+ g_object_unref(server);
+ server = NULL;
+ }
+ }
+ camel_service_unlock (CAMEL_SERVICE (store), CAMEL_SERVICE_REC_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) {
+ g_object_unref(server);
+ return TRUE;
+ }
- return camel_imapx_server_connect (istore->server, TRUE, ex);
+ return FALSE;
}
static gboolean
@@ -230,8 +262,14 @@ imapx_disconnect (CamelService *service, gboolean clean, CamelException *ex)
service_class = CAMEL_SERVICE_CLASS (camel_imapx_store_parent_class);
service_class->disconnect (service, clean, ex);
- if (istore->server)
- camel_imapx_server_connect(istore->server, FALSE, ex);
+ camel_service_lock (service, CAMEL_SERVICE_REC_CONNECT_LOCK);
+
+ if (istore->server) {
+ g_object_unref(istore->server);
+ istore->server = NULL;
+ }
+
+ camel_service_unlock (service, CAMEL_SERVICE_REC_CONNECT_LOCK);
return TRUE;
}
@@ -284,17 +322,16 @@ static gboolean
imapx_noop (CamelStore *store, CamelException *ex)
{
CamelIMAPXStore *istore = (CamelIMAPXStore *) store;
+ CamelIMAPXServer *server;
if (CAMEL_OFFLINE_STORE(store)->state == CAMEL_OFFLINE_STORE_NETWORK_UNAVAIL)
return TRUE;
- if (istore->server) {
- if (!camel_imapx_server_connect (istore->server, TRUE, ex))
- return FALSE;
-
- 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);
+ g_object_unref(server);
}
-
return TRUE;
}
@@ -551,12 +588,17 @@ static gboolean
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 TRUE;
- 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 FALSE;
+
+ camel_imapx_server_manage_subscription (server, folder_name, TRUE, ex);
+ g_object_unref(server);
if (!camel_exception_is_set (ex)) {
imapx_mark_folder_subscribed (istore, folder_name, emit_signal, ex);
@@ -570,12 +612,17 @@ static gboolean
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 TRUE;
- 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 FALSE;
+
+ camel_imapx_server_manage_subscription (server, folder_name, FALSE, ex);
+ g_object_unref(server);
if (!camel_exception_is_set (ex)) {
imapx_unmark_folder_subscribed (istore, folder_name, emit_signal, ex);
@@ -645,15 +692,19 @@ static gboolean
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 FALSE;
}
+ server = camel_imapx_store_get_server(istore, ex);
+ if (!server)
+ return FALSE;
- 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);
+ g_object_unref(server);
if (!camel_exception_is_set (ex)) {
imapx_delete_folder_from_cache (istore, folder_name, ex);
@@ -700,6 +751,7 @@ static gboolean
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) {
@@ -711,8 +763,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);
+ g_object_unref(server);
+ }
if (camel_exception_is_set (ex)) {
imapx_subscribe_folder (store, old, FALSE, ex);
@@ -748,6 +803,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;
@@ -758,7 +814,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)
@@ -774,6 +831,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);
+ g_object_unref(server);
return NULL;
}
@@ -781,6 +839,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);
+ g_object_unref(server);
return NULL;
}
@@ -788,6 +847,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"));
+ g_object_unref(server);
return NULL;
}
@@ -798,7 +858,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);
+ g_object_unref(server);
if (!camel_exception_is_set (ex)) {
CamelIMAPXStoreInfo *si;
@@ -923,7 +984,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;
@@ -946,13 +1007,15 @@ 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) {
+ g_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);
- if (!(istore->server->cinfo->capa & IMAPX_CAPABILITY_NAMESPACE))
+ if (!(server->cinfo->capa & IMAPX_CAPABILITY_NAMESPACE))
istore->dir_sep = li->separator;
if (si->info.flags != new_flags) {
@@ -1006,15 +1069,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);
@@ -1041,9 +1105,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);
@@ -1067,11 +1136,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;
@@ -1080,7 +1149,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;
@@ -1089,15 +1158,17 @@ fetch_folders_for_namespaces (CamelIMAPXStore *istore, const gchar *pattern, gbo
g_free (pat);
if (pattern)
- return folders;
+ goto out;
ns = ns->next;
}
}
-
+ out:
+ g_object_unref(server);
return folders;
exception:
+ g_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 77f39c9..8ae1ffe 100644
--- a/camel/providers/imapx/camel-imapx-store.h
+++ b/camel/providers/imapx/camel-imapx-store.h
@@ -91,6 +91,7 @@ struct _CamelIMAPXStoreClass {
};
GType camel_imapx_store_get_type (void);
+CamelIMAPXServer *camel_imapx_store_get_server(CamelIMAPXStore *store, CamelException *ex);
G_END_DECLS
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]