if (!_is_initialized)
return TRUE;
- if (gnome_vfs_initialized()) /* apparently, this returns TRUE, even after a shutdown */
- gnome_vfs_shutdown ();
-
if (!modest_runtime_uninit())
g_printerr ("modest: failed to uninit runtime\n");
if (!modest_platform_uninit())
g_printerr ("modest: failed to uninit platform\n");
+ if (gnome_vfs_initialized()) /* apparently, this returns TRUE, even after a shutdown */
+ gnome_vfs_shutdown ();
+
_is_initialized = FALSE;
return TRUE;
}
GMutex *queue_lock;
guint op_id;
guint queue_empty_handler;
+ gboolean running_final_sync;
};
#define MODEST_MAIL_OPERATION_QUEUE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), \
MODEST_TYPE_MAIL_OPERATION_QUEUE, \
priv->queue_lock = g_mutex_new ();
priv->op_id = 0;
priv->queue_empty_handler = 0;
+ priv->running_final_sync = FALSE;
}
static void
priv = MODEST_MAIL_OPERATION_QUEUE_GET_PRIVATE(self);
+ priv->running_final_sync = (modest_mail_operation_get_type_operation (mail_op) == MODEST_MAIL_OPERATION_TYPE_SHUTDOWN);
+
g_mutex_lock (priv->queue_lock);
g_queue_push_tail (priv->op_queue, g_object_ref (mail_op));
g_mutex_unlock (priv->queue_lock);
return str;
}
+
+gboolean
+modest_mail_operation_queue_running_shutdown (ModestMailOperationQueue *self)
+{
+ ModestMailOperationQueuePrivate *priv;
+
+ g_return_val_if_fail (MODEST_IS_MAIL_OPERATION_QUEUE (self), FALSE);
+
+ priv = MODEST_MAIL_OPERATION_QUEUE_GET_PRIVATE(self);
+ return priv->running_final_sync;
+}
+
+void
+modest_mail_operation_queue_set_running_shutdown (ModestMailOperationQueue *self)
+{
+ ModestMailOperationQueuePrivate *priv;
+
+ g_return_if_fail (MODEST_IS_MAIL_OPERATION_QUEUE (self));
+
+ priv = MODEST_MAIL_OPERATION_QUEUE_GET_PRIVATE(self);
+ priv->running_final_sync = TRUE;
+}
**/
gchar* modest_mail_operation_queue_to_string (ModestMailOperationQueue *self);
+/**
+ * modest_mail_operation_queue_set_running_shutdown:
+ * @self: a #ModestMailOperationQueue
+ *
+ * Mark the queue as running the final sync.
+ *
+ */
+void
+modest_mail_operation_queue_set_running_shutdown (ModestMailOperationQueue *self);
+
+/**
+ * modest_mail_operation_queue_running_shutdown:
+ * @self: a #ModestMailOperationQueue
+ *
+ * Is the last operation queued a shutdown operation?
+ *
+ * Returns: a #gboolean, %TRUE if the last queued operation is
+ * a shutdown, %FALSE otherwise
+ */
+gboolean
+modest_mail_operation_queue_running_shutdown (ModestMailOperationQueue *self);
+
G_END_DECLS
#endif /* __MODEST_MAIL_OPERATION_QUEUE_H__ */
g_signal_handlers_disconnect_by_func (queue, run_queue_stop, self);
g_object_unref (self);
}
+
void
modest_mail_operation_run_queue (ModestMailOperation *self,
ModestTnySendQueue *queue)
}
static void
+shutdown_callback (ModestTnyAccountStore *account_store, gpointer userdata)
+{
+ ModestMailOperation *self = (ModestMailOperation *) userdata;
+ ModestMailOperationPrivate *priv;
+
+ g_return_if_fail (MODEST_IS_MAIL_OPERATION (self));
+ g_return_if_fail (MODEST_IS_TNY_ACCOUNT_STORE (account_store));
+ priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
+
+ priv->status = MODEST_MAIL_OPERATION_STATUS_SUCCESS;
+
+ modest_mail_operation_notify_end (self);
+ g_object_unref (self);
+}
+
+void
+modest_mail_operation_shutdown (ModestMailOperation *self, ModestTnyAccountStore *account_store)
+{
+ ModestMailOperationPrivate *priv;
+
+ g_return_if_fail (MODEST_IS_MAIL_OPERATION (self));
+ g_return_if_fail (MODEST_IS_TNY_ACCOUNT_STORE (account_store));
+ priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
+
+ modest_mail_operation_queue_set_running_shutdown (modest_runtime_get_mail_operation_queue ());
+
+ priv->status = MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS;
+ priv->account = NULL;
+ priv->op_type = MODEST_MAIL_OPERATION_TYPE_SHUTDOWN;
+
+ modest_mail_operation_notify_start (self);
+ g_object_ref (self);
+ modest_tny_account_store_shutdown (account_store, shutdown_callback, self);
+}
+
+static void
sync_folder_finish_callback (TnyFolder *self,
gboolean cancelled,
GError *err,
#include <tny-folder-store.h>
#include <widgets/modest-msg-edit-window.h>
#include <modest-tny-send-queue.h>
+#include <modest-tny-account-store.h>
G_BEGIN_DECLS
MODEST_MAIL_OPERATION_TYPE_INFO,
MODEST_MAIL_OPERATION_TYPE_RUN_QUEUE,
MODEST_MAIL_OPERATION_TYPE_SYNC_FOLDER,
+ MODEST_MAIL_OPERATION_TYPE_SHUTDOWN,
MODEST_MAIL_OPERATION_TYPE_UNKNOWN,
} ModestMailOperationTypeOperation;
void modest_mail_operation_sync_folder (ModestMailOperation *self,
TnyFolder *folder, gboolean expunge);
+/**
+ * modest_mail_operation_shutdown:
+ * @self: a #ModestMailOperation
+ * @account_store: a #ModestTnyAccountStore
+ *
+ * disconnects all accounts in the account store (doing the proper syncs).
+ */
+void modest_mail_operation_shutdown (ModestMailOperation *self,
+ ModestTnyAccountStore *account_store);
+
/* Functions to control mail operations */
/**
* modest_mail_operation_get_task_done:
on_idle_exit_modest (gpointer data)
{
MainSignalHandlers *handlers;
+ ModestMailOperationQueue *mail_op_queue;
/* Protect the Gtk calls */
gdk_threads_enter ();
-
- /* Disconnect signals. Will be freed by the destroy notify */
- handlers = (MainSignalHandlers *) data;
- g_signal_handler_disconnect (modest_runtime_get_mail_operation_queue (),
- handlers->queue_handler);
- g_signal_handler_disconnect (modest_runtime_get_window_mgr (),
- handlers->window_list_handler);
-
- /* Wait for remaining tasks */
- while (gtk_events_pending ())
- gtk_main_iteration ();
-
- gtk_main_quit ();
-
+ mail_op_queue = modest_runtime_get_mail_operation_queue ();
+
+ if (modest_mail_operation_queue_running_shutdown (mail_op_queue)) {
+
+ /* Disconnect signals. Will be freed by the destroy notify */
+ handlers = (MainSignalHandlers *) data;
+ g_signal_handler_disconnect (modest_runtime_get_mail_operation_queue (),
+ handlers->queue_handler);
+ g_signal_handler_disconnect (modest_runtime_get_window_mgr (),
+ handlers->window_list_handler);
+ /* Wait for remaining tasks */
+ while (gtk_events_pending ())
+ gtk_main_iteration ();
+
+ g_free (handlers);
+
+ gtk_main_quit ();
+ } else {
+ ModestMailOperation *mail_op;
+ mail_op = modest_mail_operation_new (NULL);
+ modest_mail_operation_queue_add (mail_op_queue, mail_op);
+ modest_mail_operation_shutdown (mail_op, modest_runtime_get_account_store ());
+ g_object_unref (mail_op);
+ }
+
gdk_threads_leave ();
return FALSE;
windows. We can exit as well if the main window is hidden
and it's the only one */
if (modest_window_mgr_num_windows (mgr) == 0)
- g_idle_add_full (G_PRIORITY_LOW, on_idle_exit_modest, user_data, g_free);
+ g_idle_add_full (G_PRIORITY_LOW, on_idle_exit_modest, user_data, NULL);
}
static void
/* Exit if there are no more windows and the queue is empty */
if (modest_mail_operation_queue_num_elements (queue) == 0)
- g_idle_add_full (G_PRIORITY_LOW, on_idle_exit_modest, user_data, g_free);
+ g_idle_add_full (G_PRIORITY_LOW, on_idle_exit_modest, user_data, NULL);
}
int
/* disconnect the list of TnyAccounts */
static void
-account_disconnect (TnyAccount *account)
-{
- g_return_if_fail (account && TNY_IS_ACCOUNT(account));
-
- if (TNY_IS_STORE_ACCOUNT (account) &&
- !modest_tny_folder_store_is_remote (TNY_FOLDER_STORE (account)))
- return;
-
- tny_camel_account_set_online (TNY_CAMEL_ACCOUNT(account), FALSE, NULL, NULL);
-}
-
-
-/* disconnect the list of TnyAccounts */
-static void
account_verify_last_ref (TnyAccount *account, const gchar *str)
{
gchar *txt;
/* Destroy all accounts. Disconnect all accounts before they are destroyed */
if (priv->store_accounts) {
- tny_list_foreach (priv->store_accounts, (GFunc)account_disconnect, NULL);
tny_list_foreach (priv->store_accounts, (GFunc)account_verify_last_ref, "store");
g_object_unref (priv->store_accounts);
priv->store_accounts = NULL;
}
if (priv->transport_accounts) {
- tny_list_foreach (priv->transport_accounts, (GFunc)account_disconnect, NULL);
tny_list_foreach (priv->transport_accounts, (GFunc)account_verify_last_ref, "transport");
g_object_unref (priv->transport_accounts);
priv->transport_accounts = NULL;
}
}
+
+typedef struct {
+ ModestTnyAccountStore *account_store;
+ ModestTnyAccountStoreShutdownCallback callback;
+ gpointer userdata;
+ gint pending;
+} ShutdownOpData;
+
+static void
+account_shutdown_callback (TnyCamelAccount *account, gboolean canceled, GError *err, gpointer userdata)
+{
+ ShutdownOpData *op_data = (ShutdownOpData *) userdata;
+ op_data->pending--;
+ if (op_data->pending == 0) {
+ if (op_data->callback)
+ op_data->callback (op_data->account_store, op_data->userdata);
+ g_object_unref (op_data->account_store);
+ g_free (op_data);
+ }
+}
+
+static void
+account_shutdown (TnyAccount *account, ShutdownOpData *op_data)
+{
+ g_return_if_fail (account && TNY_IS_ACCOUNT(account));
+
+ if (TNY_IS_STORE_ACCOUNT (account) &&
+ !modest_tny_folder_store_is_remote (TNY_FOLDER_STORE (account)))
+ return;
+
+ op_data->pending++;
+
+ tny_camel_account_set_online (TNY_CAMEL_ACCOUNT(account), FALSE, account_shutdown_callback, op_data);
+}
+
+
+void
+modest_tny_account_store_shutdown (ModestTnyAccountStore *self,
+ ModestTnyAccountStoreShutdownCallback callback,
+ gpointer userdata)
+{
+ ShutdownOpData *op_data = g_new0 (ShutdownOpData, 1);
+ ModestTnyAccountStorePrivate *priv = MODEST_TNY_ACCOUNT_STORE_GET_PRIVATE (self);
+ op_data->callback = callback;
+ op_data->userdata = userdata;
+ op_data->pending = 0;
+ op_data->account_store = g_object_ref (self);
+
+ /* Destroy all accounts. Disconnect all accounts before they are destroyed */
+ if (priv->store_accounts) {
+ tny_list_foreach (priv->store_accounts, (GFunc)account_shutdown, op_data);
+ }
+
+ if (priv->transport_accounts) {
+ tny_list_foreach (priv->transport_accounts, (GFunc)account_shutdown, op_data);
+ }
+
+ if (op_data->pending == 0) {
+ if (op_data->callback)
+ op_data->callback (op_data->account_store, op_data->userdata);
+ g_object_unref (op_data->account_store);
+ g_free (op_data);
+ }
+}
GtkWidget *modest_tny_account_store_show_account_settings_dialog (ModestTnyAccountStore *self,
const gchar *account_name);
+typedef void (*ModestTnyAccountStoreShutdownCallback) (ModestTnyAccountStore *account_store, gpointer userdata);
+
+/**
+ * modest_tny_account_store_shutdown:
+ * @self: a #ModestTnyAccountStore
+ * @callback: a #ModestTnyAccountStoreShutdownCallback
+ * @userdata: a #gpointer
+ *
+ * Disconnects all registered accounts (forcing syncs for all of them).
+ */
+void modest_tny_account_store_shutdown (ModestTnyAccountStore *self,
+ ModestTnyAccountStoreShutdownCallback callback,
+ gpointer userdata);
+
+
G_END_DECLS
#endif /* __MODEST_TNY_ACCOUNT_STORE_H__ */