From 5c10a6a7b752651d4700639f7ee3139a2476dbe0 Mon Sep 17 00:00:00 2001 From: Sergio Villar Senin Date: Thu, 21 May 2009 18:13:37 +0200 Subject: [PATCH] Fixes a stack overflow caused by the recent commit that was pre-creating the send queues --- src/modest-main.c | 8 ++++- src/modest-tny-account-store.c | 67 ++++++++++++++++++++++++++++++---------- src/modest-tny-account-store.h | 10 ++++++ 3 files changed, 67 insertions(+), 18 deletions(-) diff --git a/src/modest-main.c b/src/modest-main.c index 1d6bde6..62d2e69 100644 --- a/src/modest-main.c +++ b/src/modest-main.c @@ -123,6 +123,7 @@ main (int argc, char *argv[]) gboolean show_ui_without_top_application_method = FALSE; int retval = 0; MainSignalHandlers *handlers; + ModestTnyAccountStore *acc_store; GError *error; GOptionContext *context; @@ -166,6 +167,11 @@ main (int argc, char *argv[]) goto cleanup; } + + /* Create the account store & launch send queues */ + acc_store = modest_runtime_get_account_store (); + modest_tny_account_store_start_send_queues (acc_store); + handlers = g_malloc0 (sizeof (MainSignalHandlers)); /* Connect to the "queue-emtpy" signal */ handlers->queue_handler = @@ -183,7 +189,7 @@ main (int argc, char *argv[]) /* Connect to the "password-requested" signal */ handlers->get_password_handler = - g_signal_connect (modest_runtime_get_account_store (), + g_signal_connect (acc_store, "password_requested", G_CALLBACK (modest_ui_actions_on_password_requested), NULL); diff --git a/src/modest-tny-account-store.c b/src/modest-tny-account-store.c index 6b05564..ec3dc04 100644 --- a/src/modest-tny-account-store.c +++ b/src/modest-tny-account-store.c @@ -85,7 +85,7 @@ static void add_existing_accounts (ModestTnyAccountStore *self); static void insert_account (ModestTnyAccountStore *self, const gchar *account, - gboolean notify); + gboolean is_new); static void on_account_removed (ModestAccountMgr *acc_mgr, const gchar *account, @@ -943,24 +943,24 @@ modest_tny_account_store_new (ModestAccountMgr *account_mgr, local_account = modest_tny_account_new_for_local_folders (priv->account_mgr, priv->session, NULL); tny_list_append (priv->store_accounts, G_OBJECT(local_account)); - g_object_unref (local_account); + g_object_unref (local_account); /* Add the other remote accounts. Do this after adding the local account, because we need to add our outboxes to the global OUTBOX hosted in the local account */ add_existing_accounts (MODEST_TNY_ACCOUNT_STORE (obj)); - + /* Add connection-specific transport accounts if there are any accounts available */ if (!only_local_accounts (MODEST_TNY_ACCOUNT_STORE(obj))) add_connection_specific_transport_accounts (MODEST_TNY_ACCOUNT_STORE(obj)); - + /* This is a singleton, so it does not need to be unrefed. */ if (volume_path_is_mounted (g_getenv (MODEST_MMC1_VOLUMEPATH_ENV))) { /* It is mounted: */ - add_mmc_account (MODEST_TNY_ACCOUNT_STORE (obj), FALSE /* don't emit the insert signal. */); + add_mmc_account (MODEST_TNY_ACCOUNT_STORE (obj), FALSE /* don't emit the insert signal. */); } - + return MODEST_TNY_ACCOUNT_STORE(obj); } @@ -1634,22 +1634,21 @@ add_outbox_from_transport_account_to_global_outbox (ModestTnyAccountStore *self, static void insert_account (ModestTnyAccountStore *self, const gchar *account, - gboolean notify) + gboolean is_new) { ModestTnyAccountStorePrivate *priv = NULL; TnyAccount *store_account = NULL, *transport_account = NULL; - ModestTnySendQueue *send_queue; priv = MODEST_TNY_ACCOUNT_STORE_GET_PRIVATE(self); /* Get the server and the transport account */ - store_account = create_tny_account (self, account, TNY_ACCOUNT_TYPE_STORE, notify); + store_account = create_tny_account (self, account, TNY_ACCOUNT_TYPE_STORE, is_new); if (!store_account || !TNY_IS_ACCOUNT(store_account)) { g_warning ("%s: failed to create store account", __FUNCTION__); return; } - transport_account = create_tny_account (self, account, TNY_ACCOUNT_TYPE_TRANSPORT, notify); + transport_account = create_tny_account (self, account, TNY_ACCOUNT_TYPE_TRANSPORT, is_new); if (!transport_account || !TNY_IS_ACCOUNT(transport_account)) { g_warning ("%s: failed to create transport account", __FUNCTION__); g_object_unref (store_account); @@ -1663,17 +1662,20 @@ insert_account (ModestTnyAccountStore *self, /* Create a new pseudo-account with an outbox for this transport account and add it to the global outbox in the local account */ - add_outbox_from_transport_account_to_global_outbox (self, account, transport_account); + add_outbox_from_transport_account_to_global_outbox (self, account, transport_account); /* Force the creation of the send queue, this way send queues will automatically send missing emails when the connections become active */ - send_queue = modest_runtime_get_send_queue ((TnyTransportAccount *) transport_account, TRUE); - /* Notify the observers. We do it after everything is created */ - if (notify) { - g_signal_emit (G_OBJECT (self), signals [ACCOUNT_INSERTED_SIGNAL], 0, store_account); + if (is_new) { + /* We only have to do this for new accounts, already + existing accounts at boot time are instantiated by + modest_tny_account_store_start_send_queues */ + modest_runtime_get_send_queue ((TnyTransportAccount *) transport_account, TRUE); + + g_signal_emit (G_OBJECT (self), signals [ACCOUNT_INSERTED_SIGNAL], 0, store_account); g_signal_emit (G_OBJECT (self), signals [ACCOUNT_INSERTED_SIGNAL], 0, transport_account); } @@ -1696,7 +1698,7 @@ on_account_inserted (ModestAccountMgr *acc_mgr, gboolean add_specific; add_specific = only_local_accounts (MODEST_TNY_ACCOUNT_STORE (user_data)); - + /* Insert the account and notify the observers */ insert_account (MODEST_TNY_ACCOUNT_STORE (user_data), account, TRUE); @@ -2215,11 +2217,42 @@ count_remote_accounts (gpointer data, gpointer user_data) guint modest_tny_account_store_get_num_remote_accounts (ModestTnyAccountStore *self) { - ModestTnyAccountStorePrivate *priv = MODEST_TNY_ACCOUNT_STORE_GET_PRIVATE (self); + ModestTnyAccountStorePrivate *priv; gint count = 0; + g_return_val_if_fail (MODEST_IS_TNY_ACCOUNT_STORE (self), 0); + /* Count remote accounts */ + priv = MODEST_TNY_ACCOUNT_STORE_GET_PRIVATE (self); tny_list_foreach (priv->store_accounts, (GFunc) count_remote_accounts, &count); return count; } + +static void +init_send_queue (TnyAccount *account, gpointer user_data) +{ + modest_runtime_get_send_queue ((TnyTransportAccount *) account, TRUE); +} + +void +modest_tny_account_store_start_send_queues (ModestTnyAccountStore *self) +{ + ModestTnyAccountStorePrivate *priv; + TnyList *tmp; + + g_return_if_fail (MODEST_IS_TNY_ACCOUNT_STORE (self)); + + priv = MODEST_TNY_ACCOUNT_STORE_GET_PRIVATE (self); + + /* We need to create a copy of the list because if the send + queues are created they'll directly access to the TnyList + of transport accounts, and thus we'll end up blocked in the + mutex the TnyList uses to synchronize accesses */ + tmp = tny_list_copy (priv->transport_accounts); + + /* Just instantiate them. They'll begin to listen for + connection changes to send messages ASAP */ + tny_list_foreach (tmp, (GFunc) init_send_queue, NULL); + g_object_unref (tmp); +} diff --git a/src/modest-tny-account-store.h b/src/modest-tny-account-store.h index 239deb4..30d3f0a 100644 --- a/src/modest-tny-account-store.h +++ b/src/modest-tny-account-store.h @@ -273,6 +273,16 @@ void modest_tny_account_store_set_send_mail_blocked (ModestTnyAccountStore *self guint modest_tny_account_store_get_num_remote_accounts (ModestTnyAccountStore *self); +/** + * modest_tny_account_store_start_send_queues: + * @self: a #ModestTnyAccountStore + * + * Instantiates the send queues for the available transport + * accounts. Note that send queues will start to listen to + * connection-changed signals to try to send pending emails ASAP + **/ +void modest_tny_account_store_start_send_queues (ModestTnyAccountStore *self); + G_END_DECLS #endif /* __MODEST_TNY_ACCOUNT_STORE_H__ */ -- 1.7.9.5