From 5be19f3d421a5531ac9344971a31e381364bf049 Mon Sep 17 00:00:00 2001 From: Sergio Villar Senin Date: Tue, 12 Dec 2006 17:32:10 +0000 Subject: [PATCH] * Rewritten some async calls * Update account does not longer hang pmo-trunk-r551 --- src/gtk/modest-main-window.c | 53 +++++++++++++------------ src/modest-mail-operation.c | 81 ++++++++++++++++++++------------------ src/widgets/modest-header-view.c | 34 ++++++++-------- tests/check_update-account.c | 10 ----- 4 files changed, 88 insertions(+), 90 deletions(-) diff --git a/src/gtk/modest-main-window.c b/src/gtk/modest-main-window.c index 2613689..c458eed 100644 --- a/src/gtk/modest-main-window.c +++ b/src/gtk/modest-main-window.c @@ -91,6 +91,7 @@ typedef struct _GetMsgAsyncHelper { ModestMailOperationReplyType reply_type; ModestMailOperationForwardType forward_type; gchar *from; + TnyIterator *iter; } GetMsgAsyncHelper; /* globals */ @@ -238,9 +239,9 @@ get_msg_cb (TnyFolder *folder, TnyMsg *msg, GError **err, gpointer user_data) GetMsgAsyncHelper *helper; helper = (GetMsgAsyncHelper *) (user_data); - priv = helper->main_window_private; /* FIXME: select proper action */ + priv = helper->main_window_private; new_msg = NULL; switch (helper->action) { case 1: @@ -268,6 +269,7 @@ get_msg_cb (TnyFolder *folder, TnyMsg *msg, GError **err, gpointer user_data) /* Set from */ new_header = tny_msg_get_header (new_msg); tny_header_set_from (new_header, helper->from); + g_object_unref (G_OBJECT (new_header)); /* Show edit window */ msg_win = modest_edit_msg_window_new (priv->widget_factory, @@ -278,6 +280,17 @@ get_msg_cb (TnyFolder *folder, TnyMsg *msg, GError **err, gpointer user_data) /* Clean and go on */ g_object_unref (new_msg); } + + tny_iterator_next (helper->iter); + if (tny_iterator_is_done (helper->iter)) { + TnyList *headers; + headers = tny_iterator_get_list (helper->iter); + g_object_unref (G_OBJECT (headers)); + g_object_unref (G_OBJECT (helper->iter)); + g_slice_free (GetMsgAsyncHelper, helper); + } else + tny_folder_get_msg_async (folder, TNY_HEADER (tny_iterator_get_current (helper->iter)), + get_msg_cb, helper); } static void @@ -286,13 +299,11 @@ on_menu_reply_forward (ModestMainWindow *self, guint action, GtkWidget *widget) ModestMainWindowPrivate *priv; ModestHeaderView *header_view; TnyList *header_list; - TnyIterator *iter; gchar *reply_key, *forward_key; ModestMailOperationReplyType reply_type; ModestMailOperationForwardType forward_type; ModestConf *conf; GError *error; - GetMsgAsyncHelper *helper; priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self); conf = modest_tny_platform_factory_get_modest_conf_instance (priv->factory); @@ -331,6 +342,7 @@ on_menu_reply_forward (ModestMainWindow *self, guint action, GtkWidget *widget) TnyFolder *folder; gchar *from, *email_key; const gchar *account_name; + GetMsgAsyncHelper *helper; /* We assume that we can only select messages of the same folder and that we reply all of them from the @@ -340,34 +352,25 @@ on_menu_reply_forward (ModestMainWindow *self, guint action, GtkWidget *widget) email_key = g_strdup_printf ("%s/%s/%s", MODEST_ACCOUNT_NAMESPACE, account_name, MODEST_ACCOUNT_EMAIL); from = modest_conf_get_string (conf, email_key, NULL); + if (!from) + from = g_strdup ("Invalid"); g_free (email_key); - iter = tny_list_create_iterator (header_list); - header = TNY_HEADER (tny_iterator_get_current (iter)); - folder = tny_header_get_folder (header); + helper = g_slice_new0 (GetMsgAsyncHelper); + helper->main_window_private = priv; + helper->reply_type = reply_type; + helper->forward_type = forward_type; + helper->action = action; + helper->from = from; + helper->iter = tny_list_create_iterator (header_list); - do { - /* Since it's not an object, we need to create - it each time due to it's not a GObject and - we can not do a g_object_ref. No need to - free it, tinymail will do it for us. */ - helper = g_slice_new0 (GetMsgAsyncHelper); - helper->main_window_private = priv; - helper->reply_type = reply_type; - helper->forward_type = forward_type; - helper->action = action; - helper->from = from; - - /* Get msg from header */ - header = TNY_HEADER (tny_iterator_get_current (iter)); - tny_folder_get_msg_async (folder, header, get_msg_cb, helper); - tny_iterator_next (iter); + header = TNY_HEADER (tny_iterator_get_current (helper->iter)); + folder = tny_header_get_folder (header); - } while (!tny_iterator_is_done (iter)); + /* The callback will call it per each header */ + tny_folder_get_msg_async (folder, header, get_msg_cb, helper); /* Clean */ - g_free (from); - g_object_unref (G_OBJECT (iter)); g_object_unref (G_OBJECT (folder)); } } diff --git a/src/modest-mail-operation.c b/src/modest-mail-operation.c index d655730..8c23dd6 100644 --- a/src/modest-mail-operation.c +++ b/src/modest-mail-operation.c @@ -114,11 +114,8 @@ enum _ModestMailOperationSignals typedef struct _ModestMailOperationPrivate ModestMailOperationPrivate; struct _ModestMailOperationPrivate { - guint failed; - guint canceled; guint done; guint total; - GMutex *cb_lock; ModestMailOperationStatus status; GError *error; }; @@ -126,6 +123,15 @@ struct _ModestMailOperationPrivate { MODEST_TYPE_MAIL_OPERATION, \ ModestMailOperationPrivate)) +typedef struct _RefreshFolderAsyncHelper +{ + ModestMailOperation *mail_op; + TnyIterator *iter; + guint failed; + guint canceled; + +} RefreshFolderAsyncHelper; + /* some utility functions */ static char * get_content_type(const gchar *s); static gboolean is_ascii(const gchar *s); @@ -191,10 +197,7 @@ modest_mail_operation_init (ModestMailOperation *obj) priv->status = MODEST_MAIL_OPERATION_STATUS_INVALID; priv->error = NULL; priv->done = 0; - priv->failed = 0; - priv->canceled = 0; priv->total = 0; - priv->cb_lock = g_mutex_new (); } static void @@ -209,8 +212,6 @@ modest_mail_operation_finalize (GObject *obj) priv->error = NULL; } - g_mutex_free (priv->cb_lock); - G_OBJECT_CLASS(parent_class)->finalize (obj); } @@ -446,7 +447,6 @@ modest_mail_operation_create_reply_mail (TnyMsg *msg, if (cc) g_string_append_printf (tmp, ",%s",cc); if (bcc) g_string_append_printf (tmp, ",%s",bcc); - /* Remove my own address from the cc list. TODO: remove also the To: of the new message, needed due to the new reply_to feature */ @@ -480,17 +480,17 @@ folder_refresh_cb (TnyFolder *folder, gboolean canceled, GError **err, gpointer { ModestMailOperation *mail_op = NULL; ModestMailOperationPrivate *priv = NULL; + RefreshFolderAsyncHelper *helper; - mail_op = MODEST_MAIL_OPERATION (user_data); + helper = (RefreshFolderAsyncHelper *) user_data; + mail_op = MODEST_MAIL_OPERATION (helper->mail_op); priv = MODEST_MAIL_OPERATION_GET_PRIVATE(mail_op); - g_mutex_lock (priv->cb_lock); - if ((canceled && *err) || *err) { priv->error = g_error_copy (*err); - priv->failed++; + helper->failed++; } else if (canceled) { - priv->canceled++; + helper->canceled++; set_error (mail_op, MODEST_MAIL_OPERATION_ERROR_OPERATION_CANCELED, _("Error trying to refresh folder %s. Operation canceled"), @@ -501,16 +501,27 @@ folder_refresh_cb (TnyFolder *folder, gboolean canceled, GError **err, gpointer if (priv->done == priv->total) priv->status = MODEST_MAIL_OPERATION_STATUS_SUCCESS; - else if ((priv->done + priv->canceled + priv->failed) == priv->total) - if (priv->failed == priv->total) + else if ((priv->done + helper->canceled + helper->failed) == priv->total) + if (helper->failed == priv->total) priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED; - else if (priv->failed == priv->total) + else if (helper->failed == priv->total) priv->status = MODEST_MAIL_OPERATION_STATUS_CANCELED; else priv->status = MODEST_MAIL_OPERATION_STATUS_FINISHED_WITH_ERRORS; - g_mutex_unlock (priv->cb_lock); - + tny_iterator_next (helper->iter); + if (tny_iterator_is_done (helper->iter)) { + TnyList *list; + list = tny_iterator_get_list (helper->iter); + g_object_unref (G_OBJECT (helper->iter)); + g_object_unref (G_OBJECT (list)); + g_slice_free (RefreshFolderAsyncHelper, helper); + } else { + tny_folder_refresh_async (TNY_FOLDER (tny_iterator_get_current (helper->iter)), + folder_refresh_cb, + status_update_cb, + helper); + } g_signal_emit (G_OBJECT (mail_op), signals[PROGRESS_CHANGED_SIGNAL], 0, NULL); } @@ -521,31 +532,26 @@ update_folders_cb (TnyFolderStore *self, TnyList *list, GError **err, gpointer u ModestMailOperation *mail_op; ModestMailOperationPrivate *priv; TnyList *folders; - TnyIterator *ifolders; - TnyFolder *cur_folder; + RefreshFolderAsyncHelper *helper; mail_op = MODEST_MAIL_OPERATION (user_data); priv = MODEST_MAIL_OPERATION_GET_PRIVATE (mail_op); - ifolders = tny_list_create_iterator (list); priv->total = tny_list_get_length (list); priv->done = 0; priv->status = MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS; - /* Async refresh folders. Reference the mail_op because - tinymail destroys the user_data */ - for (tny_iterator_first (ifolders); - !tny_iterator_is_done (ifolders); - tny_iterator_next (ifolders)) { - - cur_folder = TNY_FOLDER (tny_iterator_get_current (ifolders)); - tny_folder_refresh_async (cur_folder, - folder_refresh_cb, - status_update_cb, g_object_ref (mail_op)); - } - - g_object_unref (G_OBJECT (ifolders)); - g_object_unref (G_OBJECT (list)); + helper = g_slice_new0 (RefreshFolderAsyncHelper); + helper->mail_op = mail_op; + helper->iter = tny_list_create_iterator (list); + helper->failed = 0; + helper->canceled = 0; + + /* Async refresh folders */ + tny_folder_refresh_async (TNY_FOLDER (tny_iterator_get_current (helper->iter)), + folder_refresh_cb, + status_update_cb, + helper); } gboolean @@ -638,8 +644,6 @@ modest_mail_operation_is_finished (ModestMailOperation *mail_op) priv = MODEST_MAIL_OPERATION_GET_PRIVATE (mail_op); - g_mutex_lock (priv->cb_lock); - if (priv->status == MODEST_MAIL_OPERATION_STATUS_SUCCESS || priv->status == MODEST_MAIL_OPERATION_STATUS_FAILED || priv->status == MODEST_MAIL_OPERATION_STATUS_CANCELED || @@ -648,7 +652,6 @@ modest_mail_operation_is_finished (ModestMailOperation *mail_op) } else { retval = FALSE; } - g_mutex_unlock (priv->cb_lock); return retval; } diff --git a/src/widgets/modest-header-view.c b/src/widgets/modest-header-view.c index bdb40f8..0ec08ee 100644 --- a/src/widgets/modest-header-view.c +++ b/src/widgets/modest-header-view.c @@ -68,7 +68,7 @@ struct _ModestHeaderViewPrivate { ModestHeaderViewPrivate)) typedef struct _GetMsgAsyncHelper { - ModestHeaderView *view; + ModestHeaderView *self; TnyHeader *header; } GetMsgAsyncHelper; @@ -894,18 +894,19 @@ get_msg_cb (TnyFolder *folder, TnyMsg *msg, GError **err, gpointer user_data) helper = (GetMsgAsyncHelper *) user_data; - if (!msg) { - g_signal_emit (G_OBJECT(helper->view), signals[ITEM_NOT_FOUND_SIGNAL], 0, - MODEST_ITEM_TYPE_MESSAGE); - return; - } - - g_signal_emit (G_OBJECT(helper->view), signals[MESSAGE_SELECTED_SIGNAL], 0, - msg); + if (msg) { + g_signal_emit (G_OBJECT(helper->self), signals[MESSAGE_SELECTED_SIGNAL], 0, + msg); - /* mark message as seen; _set_flags crashes, bug in tinymail? */ - header_flags = tny_header_get_flags (helper->header); - tny_header_set_flags (helper->header, header_flags | TNY_HEADER_FLAG_SEEN); + /* mark message as seen; _set_flags crashes, bug in tinymail? */ + header_flags = tny_header_get_flags (helper->header); + tny_header_set_flags (helper->header, header_flags | TNY_HEADER_FLAG_SEEN); + } else + g_signal_emit (G_OBJECT(helper->self), signals[ITEM_NOT_FOUND_SIGNAL], 0, + MODEST_ITEM_TYPE_MESSAGE); + + /* Frees */ + g_slice_free (GetMsgAsyncHelper, helper); } static void @@ -945,14 +946,15 @@ on_selection_changed (GtkTreeSelection *sel, gpointer user_data) } helper = g_slice_new0 (GetMsgAsyncHelper); - helper->view = self; + helper->self = self; helper->header = header; /* Get message asynchronously. The callback will issue a signal if the message was retrieved correctly and then will - set the header flags as read. Tinymail will free the helper */ - tny_folder_get_msg_async (TNY_FOLDER(folder), header, get_msg_cb, helper); + set the header flags as read. */ + tny_folder_get_msg_async (TNY_FOLDER(folder), + header, get_msg_cb, helper); - /* Free */ + /* Frees */ g_object_unref (G_OBJECT (folder)); } diff --git a/tests/check_update-account.c b/tests/check_update-account.c index 87b3862..6290707 100644 --- a/tests/check_update-account.c +++ b/tests/check_update-account.c @@ -105,14 +105,6 @@ func (gpointer_data) return FALSE; } -static void -quit (gpointer data) -{ - _exit (0); -} - - - int main (int argc, char **argv) { @@ -124,8 +116,6 @@ main (int argc, char **argv) main_loop = g_main_loop_new (NULL, FALSE); id = g_timeout_add(1000, func, main_loop); - g_timeout_add (5000, quit, main_loop); /* quit after 5 seconds */ - g_main_loop_run(main_loop); return 0; -- 1.7.9.5