* Rewritten some async calls
authorSergio Villar Senin <svillar@igalia.com>
Tue, 12 Dec 2006 17:32:10 +0000 (17:32 +0000)
committerSergio Villar Senin <svillar@igalia.com>
Tue, 12 Dec 2006 17:32:10 +0000 (17:32 +0000)
* Update account does not longer hang

pmo-trunk-r551

src/gtk/modest-main-window.c
src/modest-mail-operation.c
src/widgets/modest-header-view.c
tests/check_update-account.c

index 2613689..c458eed 100644 (file)
@@ -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));
        }
 }
index d655730..8c23dd6 100644 (file)
@@ -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;
 }
index bdb40f8..0ec08ee 100644 (file)
@@ -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));
 }
index 87b3862..6290707 100644 (file)
@@ -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;