These changes fix bug NB#78736.
authorJose Dapena Paz <jdapena@igalia.com>
Thu, 24 Jan 2008 10:16:12 +0000 (10:16 +0000)
committerJose Dapena Paz <jdapena@igalia.com>
Thu, 24 Jan 2008 10:16:12 +0000 (10:16 +0000)
* src/modest-mail-operation.[ch]:
        * New mail operation run_queue. This mail operation runs when
          the send queue is looping through messages. This is used to
          warrant that we don't kill modest while we're sending
          messages, in a safer way (we were trying to detect the mail
          send attempt result, and it was not warranted to happen).
        * Remove all the code to process sent and error signals in
          send queue to finish send mail operations.
        * Now both update_account and send_mail operations notify end
          after setting up the send queue, not after knowing the send
          queue has sent the message. This way we rely now on the
          autoconfigured mail operation that lives with the send queue
          runnings.
* src/modest-tny-send-queue.c:
        * Now we hook on queue-start signal. This is for creating a mail
          operation that lives while we're trying to send messages.

pmo-trunk-r4083

src/modest-mail-operation.c
src/modest-mail-operation.h
src/modest-tny-send-queue.c

index 9ae6218..790d162 100644 (file)
@@ -143,20 +143,6 @@ typedef struct {
        gint total_bytes;
 } GetMsgInfo;
 
        gint total_bytes;
 } GetMsgInfo;
 
-typedef struct {
-       ModestMailOperation *mail_op;
-       TnyMsg *msg;
-       gulong msg_sent_handler;
-       gulong error_happened_handler;
-} SendMsgInfo;
-
-static void     send_mail_msg_sent_handler (TnySendQueue *queue, TnyHeader *header, TnyMsg *msg,
-                                           guint nth, guint total, gpointer userdata);
-static void     send_mail_error_happened_handler (TnySendQueue *queue, TnyHeader *header, TnyMsg *msg,
-                                                 GError *error, gpointer userdata);
-static void     common_send_mail_operation_end (TnySendQueue *queue, TnyMsg *msg, 
-                                               SendMsgInfo *info);
-
 typedef struct _RefreshAsyncHelper {   
        ModestMailOperation *mail_op;
        RefreshAsyncUserCallback user_callback; 
 typedef struct _RefreshAsyncHelper {   
        ModestMailOperation *mail_op;
        RefreshAsyncUserCallback user_callback; 
@@ -617,7 +603,6 @@ modest_mail_operation_send_mail (ModestMailOperation *self,
 {
        TnySendQueue *send_queue = NULL;
        ModestMailOperationPrivate *priv;
 {
        TnySendQueue *send_queue = NULL;
        ModestMailOperationPrivate *priv;
-       SendMsgInfo *info;
        
        g_return_if_fail (self && MODEST_IS_MAIL_OPERATION (self));
        g_return_if_fail (transport_account && TNY_IS_TRANSPORT_ACCOUNT (transport_account));
        
        g_return_if_fail (self && MODEST_IS_MAIL_OPERATION (self));
        g_return_if_fail (transport_account && TNY_IS_TRANSPORT_ACCOUNT (transport_account));
@@ -643,91 +628,12 @@ modest_mail_operation_send_mail (ModestMailOperation *self,
                /* Add the msg to the queue */
                modest_mail_operation_notify_start (self);
 
                /* Add the msg to the queue */
                modest_mail_operation_notify_start (self);
 
-               info = g_slice_new0 (SendMsgInfo);
-
-               info->mail_op = g_object_ref (self);
-               info->msg = g_object_ref (msg);
-               info->msg_sent_handler = g_signal_connect (G_OBJECT (send_queue), "msg-sent",
-                               G_CALLBACK (send_mail_msg_sent_handler), info);
-               info->error_happened_handler = g_signal_connect (G_OBJECT (send_queue), "error-happened",
-                               G_CALLBACK (send_mail_error_happened_handler), info);
-
                tny_send_queue_add_async (send_queue, msg, NULL, NULL, NULL);
 
                tny_send_queue_add_async (send_queue, msg, NULL, NULL, NULL);
 
-               priv->status = MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS;
-       }
-
-}
-
-static void
-common_send_mail_operation_end (TnySendQueue *queue, TnyMsg *msg,
-                               SendMsgInfo *info)
-{
-       g_signal_handler_disconnect (queue, info->msg_sent_handler);
-       g_signal_handler_disconnect (queue, info->error_happened_handler);
-
-       g_object_unref (info->msg);
-       modest_mail_operation_notify_end (info->mail_op);
-       g_object_unref (info->mail_op);
-
-       g_slice_free (SendMsgInfo, info);
-}
-
-static void     
-send_mail_msg_sent_handler (TnySendQueue *queue, TnyHeader *header, TnyMsg *msg,
-                           guint nth, guint total, gpointer userdata)
-{
-       SendMsgInfo *info = (SendMsgInfo *) userdata;
-       TnyHeader *hdr1, *hdr2;
-       const char *msgid1, *msgid2;
-       hdr1 = tny_msg_get_header(msg);
-       hdr2 = tny_msg_get_header(info->msg);
-       msgid1 = tny_header_get_message_id(hdr1);
-       msgid2 = tny_header_get_message_id(hdr2);
-       if (msgid1 == NULL) msgid1 = "(null)";
-       if (msgid2 == NULL) msgid2 = "(null)";
-
-       if (!strcmp (msgid1, msgid2)) {
-               ModestMailOperationPrivate *priv = MODEST_MAIL_OPERATION_GET_PRIVATE (info->mail_op);
                priv->status = MODEST_MAIL_OPERATION_STATUS_SUCCESS;
                priv->status = MODEST_MAIL_OPERATION_STATUS_SUCCESS;
-
-               common_send_mail_operation_end (queue, msg, info);
-       }
-       g_object_unref(G_OBJECT(hdr1));
-       g_object_unref(G_OBJECT(hdr2));
-}
-
-static void     
-send_mail_error_happened_handler (TnySendQueue *queue, TnyHeader *header, TnyMsg *msg,
-                                 GError *error, gpointer userdata)
-{
-       SendMsgInfo *info = (SendMsgInfo *) userdata;
-       TnyHeader *hdr1, *hdr2;
-       const char *msgid1, *msgid2;
-
-       if (!TNY_IS_MSG(msg)) {
-               g_warning ("%s: did not receive a valid msg", __FUNCTION__);
-               return;
+               modest_mail_operation_notify_end (self);
        }
        }
-       
-       hdr1 = tny_msg_get_header(msg);
-       hdr2 = tny_msg_get_header(info->msg);
-       msgid1 = tny_header_get_message_id(hdr1);
-       msgid2 = tny_header_get_message_id(hdr2);
-       if (msgid1 == NULL) msgid1 = "(null)";
-       if (msgid2 == NULL) msgid2 = "(null)";
-
-       if (!strcmp (msgid1, msgid2)) {
-               ModestMailOperationPrivate *priv = MODEST_MAIL_OPERATION_GET_PRIVATE (info->mail_op);
-               priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED;
-               g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
-                            MODEST_MAIL_OPERATION_ERROR_OPERATION_CANCELED,
-                            "modest: send mail failed\n");
 
 
-               common_send_mail_operation_end (queue, msg, info);
-       }
-       g_object_unref(G_OBJECT(hdr1));
-       g_object_unref(G_OBJECT(hdr2));
 }
 
 
 }
 
 
@@ -1308,62 +1214,6 @@ update_account_get_msg_async_cb (TnyFolder *folder,
        g_slice_free (GetMsgInfo, msg_info);
 }
 
        g_slice_free (GetMsgInfo, msg_info);
 }
 
-typedef struct {
-       guint error_handler;
-       guint sent_handler;
-       ModestMailOperation *mail_op;
-} UpdateAccountSendQueueFlushInfo;
-
-static void
-update_account_finalize (TnySendQueue *queue,
-                        UpdateAccountSendQueueFlushInfo *info)
-{
-       ModestMailOperationPrivate *priv;
-
-       priv = MODEST_MAIL_OPERATION_GET_PRIVATE (info->mail_op);
-       priv->done++;
-
-       /* The last one finish the mail operation */
-       if (priv->done == priv->total) {
-               /* Notify end */
-               modest_mail_operation_notify_end (info->mail_op);
-               
-               /* Free */
-               g_object_unref (info->mail_op);
-               g_signal_handler_disconnect (queue, info->error_handler);
-               g_signal_handler_disconnect (queue, info->sent_handler);
-               g_slice_free (UpdateAccountSendQueueFlushInfo, info);
-       }
-}
-
-static void
-update_account_on_msg_sent_cb (TnySendQueue *queue, 
-                              TnyHeader *header, 
-                              TnyMsg *msg,
-                              guint nth, 
-                              guint total, 
-                              gpointer user_data)
-{
-       UpdateAccountSendQueueFlushInfo *info;
-       info = (UpdateAccountSendQueueFlushInfo *) user_data;
-
-       update_account_finalize (queue, info);
-}
-
-static void     
-update_account_on_error_happened_cb (TnySendQueue *queue, 
-                                    TnyHeader *header, 
-                                    TnyMsg *msg,
-                                    GError *error, 
-                                    gpointer user_data)
-{
-       UpdateAccountSendQueueFlushInfo *info;
-       info = (UpdateAccountSendQueueFlushInfo *) user_data;
-
-       update_account_finalize (queue, info);
-}
-
-
 static void
 inbox_refreshed_cb (TnyFolder *inbox, 
                    gboolean canceled, 
 static void
 inbox_refreshed_cb (TnyFolder *inbox, 
                    gboolean canceled, 
@@ -1380,7 +1230,6 @@ inbox_refreshed_cb (TnyFolder *inbox,
        TnyList *new_headers = NULL;
        gboolean headers_only, ignore_limit;
        TnyTransportAccount *transport_account;
        TnyList *new_headers = NULL;
        gboolean headers_only, ignore_limit;
        TnyTransportAccount *transport_account;
-       gboolean end_operation;
 
        info = (UpdateAccountInfo *) user_data;
        priv = MODEST_MAIL_OPERATION_GET_PRIVATE (info->mail_op);
 
        info = (UpdateAccountInfo *) user_data;
        priv = MODEST_MAIL_OPERATION_GET_PRIVATE (info->mail_op);
@@ -1508,27 +1357,9 @@ inbox_refreshed_cb (TnyFolder *inbox,
                num_messages = tny_folder_get_all_count (outbox);
                g_object_unref (outbox);
 
                num_messages = tny_folder_get_all_count (outbox);
                g_object_unref (outbox);
 
-               if (num_messages == 0) {
-                       end_operation = TRUE;
-               } else {
-                       UpdateAccountSendQueueFlushInfo *send_info;
-
-                       end_operation = FALSE;
+               if (num_messages != 0) {
                        /* Send mails */
                        /* Send mails */
-                       priv->done = 0;
-                       priv->total = num_messages;
                        g_object_unref (priv->account);
                        g_object_unref (priv->account);
-                       priv->account = TNY_ACCOUNT (transport_account);
-
-                       /* Create the info object */
-                       send_info = g_slice_new (UpdateAccountSendQueueFlushInfo);
-                       send_info->error_handler = g_signal_connect (send_queue, "error-happened", 
-                                                                    G_CALLBACK (update_account_on_error_happened_cb), 
-                                                                    send_info);
-                       send_info->sent_handler = g_signal_connect (send_queue, "msg-sent", 
-                                                                   G_CALLBACK (update_account_on_msg_sent_cb), 
-                                                                   send_info);
-                       send_info->mail_op = g_object_ref (info->mail_op);
 
                        /* Reenable suspended items */
                        modest_tny_send_queue_wakeup (MODEST_TNY_SEND_QUEUE (send_queue));
 
                        /* Reenable suspended items */
                        modest_tny_send_queue_wakeup (MODEST_TNY_SEND_QUEUE (send_queue));
@@ -1536,9 +1367,7 @@ inbox_refreshed_cb (TnyFolder *inbox,
                        /* Try to send */
                        tny_camel_send_queue_flush (TNY_CAMEL_SEND_QUEUE (send_queue));
                }
                        /* Try to send */
                        tny_camel_send_queue_flush (TNY_CAMEL_SEND_QUEUE (send_queue));
                }
-       } else {
-               end_operation = TRUE;
-       }
+       } 
 
        /* Check if the operation was a success */
        if (!priv->error)
 
        /* Check if the operation was a success */
        if (!priv->error)
@@ -1552,8 +1381,7 @@ inbox_refreshed_cb (TnyFolder *inbox,
                info->callback (info->mail_op, new_headers, info->user_data);
 
        /* Notify about operation end */
                info->callback (info->mail_op, new_headers, info->user_data);
 
        /* Notify about operation end */
-       if (end_operation)
-               modest_mail_operation_notify_end (info->mail_op);
+       modest_mail_operation_notify_end (info->mail_op);
 
        /* Frees */
        if (new_headers)
 
        /* Frees */
        if (new_headers)
@@ -3038,6 +2866,40 @@ modest_mail_operation_refresh_folder  (ModestMailOperation *self,
                                  helper);
 }
 
                                  helper);
 }
 
+static void
+run_queue_stop (ModestTnySendQueue *queue,
+               ModestMailOperation *self)
+{
+       ModestMailOperationPrivate *priv;
+
+       g_return_if_fail (MODEST_IS_MAIL_OPERATION (self));
+       g_return_if_fail (MODEST_IS_TNY_SEND_QUEUE (queue));
+       priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
+
+       priv->status = MODEST_MAIL_OPERATION_STATUS_SUCCESS;
+
+       modest_mail_operation_notify_end (self);
+       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)
+{
+       ModestMailOperationPrivate *priv;
+
+       g_return_if_fail (MODEST_IS_MAIL_OPERATION (self));
+       g_return_if_fail (MODEST_IS_TNY_SEND_QUEUE (queue));
+       priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
+
+       priv->status = MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS;
+       priv->account = TNY_ACCOUNT (tny_camel_send_queue_get_transport_account (TNY_CAMEL_SEND_QUEUE (queue)));
+       priv->op_type = MODEST_MAIL_OPERATION_TYPE_RUN_QUEUE;
+
+       modest_mail_operation_notify_start (self);
+       g_object_ref (self);
+       g_signal_connect ((gpointer) queue, "queue-stop", G_CALLBACK (run_queue_stop), (gpointer) self);
+}
 
 static void
 modest_mail_operation_notify_start (ModestMailOperation *self)
 
 static void
 modest_mail_operation_notify_start (ModestMailOperation *self)
@@ -3135,6 +2997,7 @@ modest_mail_operation_to_string (ModestMailOperation *self)
        case MODEST_MAIL_OPERATION_TYPE_OPEN:    type= "OPEN";    break;
        case MODEST_MAIL_OPERATION_TYPE_DELETE:  type= "DELETE";  break;
        case MODEST_MAIL_OPERATION_TYPE_INFO:    type= "INFO";    break;
        case MODEST_MAIL_OPERATION_TYPE_OPEN:    type= "OPEN";    break;
        case MODEST_MAIL_OPERATION_TYPE_DELETE:  type= "DELETE";  break;
        case MODEST_MAIL_OPERATION_TYPE_INFO:    type= "INFO";    break;
+       case MODEST_MAIL_OPERATION_TYPE_RUN_QUEUE: type= "RUN-QUEUE"; break;
        case MODEST_MAIL_OPERATION_TYPE_UNKNOWN: type= "UNKNOWN"; break;
        default: type = "UNEXPECTED"; break;
        }
        case MODEST_MAIL_OPERATION_TYPE_UNKNOWN: type= "UNKNOWN"; break;
        default: type = "UNEXPECTED"; break;
        }
index a3fac9c..41ef7ab 100644 (file)
@@ -33,6 +33,7 @@
 #include <tny-transport-account.h>
 #include <tny-folder-store.h>
 #include <widgets/modest-msg-edit-window.h>
 #include <tny-transport-account.h>
 #include <tny-folder-store.h>
 #include <widgets/modest-msg-edit-window.h>
+#include <modest-tny-send-queue.h>
 
 G_BEGIN_DECLS
 
 
 G_BEGIN_DECLS
 
@@ -74,6 +75,7 @@ typedef enum {
        MODEST_MAIL_OPERATION_TYPE_OPEN,
        MODEST_MAIL_OPERATION_TYPE_DELETE,
        MODEST_MAIL_OPERATION_TYPE_INFO,
        MODEST_MAIL_OPERATION_TYPE_OPEN,
        MODEST_MAIL_OPERATION_TYPE_DELETE,
        MODEST_MAIL_OPERATION_TYPE_INFO,
+       MODEST_MAIL_OPERATION_TYPE_RUN_QUEUE,
        MODEST_MAIL_OPERATION_TYPE_UNKNOWN,
 } ModestMailOperationTypeOperation;
 
        MODEST_MAIL_OPERATION_TYPE_UNKNOWN,
 } ModestMailOperationTypeOperation;
 
@@ -631,6 +633,19 @@ void          modest_mail_operation_get_msgs_full   (ModestMailOperation *self,
                                                     gpointer user_data,
                                                     GDestroyNotify notify);
 
                                                     gpointer user_data,
                                                     GDestroyNotify notify);
 
+/**
+ * modest_mail_operation_run_queue:
+ * @self: a #ModestMailOperation
+ * @queue: a #ModestTnySendQueue
+ *
+ * This mail operation is special. It should be running every time the send queue
+ * is running (after queue-start), and we should notify end of the operation
+ * after queue-end. Then, we should only set this queue on queue-start signal, and
+ * it will clean up the operation (notify end) on queue-end.
+ */
+void          modest_mail_operation_run_queue       (ModestMailOperation *self,
+                                                    ModestTnySendQueue *queue);
+
 /* Functions to control mail operations */
 /**
  * modest_mail_operation_get_task_done:
 /* Functions to control mail operations */
 /**
  * modest_mail_operation_get_task_done:
index 43b9b7f..b1f8560 100644 (file)
@@ -70,11 +70,15 @@ static void _on_msg_error_happened (TnySendQueue *self,
                                    GError *err, 
                                    gpointer user_data);
 
                                    GError *err, 
                                    gpointer user_data);
 
+static void _on_queue_start        (TnySendQueue *self, 
+                                   gpointer user_data);
+
 static void modest_tny_send_queue_add_async (TnyCamelSendQueue *self, 
                                             TnyMsg *msg, 
                                             TnySendQueueAddCallback callback, 
                                             TnyStatusCallback status_callback, 
                                             gpointer user_data);
 static void modest_tny_send_queue_add_async (TnyCamelSendQueue *self, 
                                             TnyMsg *msg, 
                                             TnySendQueueAddCallback callback, 
                                             TnyStatusCallback status_callback, 
                                             gpointer user_data);
+
 static TnyFolder* modest_tny_send_queue_get_outbox  (TnySendQueue *self);
 static TnyFolder* modest_tny_send_queue_get_sentbox (TnySendQueue *self);
 
 static TnyFolder* modest_tny_send_queue_get_outbox  (TnySendQueue *self);
 static TnyFolder* modest_tny_send_queue_get_sentbox (TnySendQueue *self);
 
@@ -409,6 +413,9 @@ modest_tny_send_queue_new (TnyCamelTransportAccount *account)
        g_signal_connect (G_OBJECT(self), "error-happened",
                          G_CALLBACK(_on_msg_error_happened),
                          NULL);
        g_signal_connect (G_OBJECT(self), "error-happened",
                          G_CALLBACK(_on_msg_error_happened),
                          NULL);
+       g_signal_connect (G_OBJECT (self), "queue-start",
+                         G_CALLBACK (_on_queue_start),
+                         NULL);
 
        /* Set outbox and sentbox */
        priv = MODEST_TNY_SEND_QUEUE_GET_PRIVATE (self);
 
        /* Set outbox and sentbox */
        priv = MODEST_TNY_SEND_QUEUE_GET_PRIVATE (self);
@@ -614,6 +621,19 @@ _on_msg_error_happened (TnySendQueue *self,
 }
 
 static void 
 }
 
 static void 
+_on_queue_start (TnySendQueue *self,
+                gpointer data)
+{
+       ModestMailOperation *mail_op;
+
+       mail_op = modest_mail_operation_new (NULL);
+       modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
+                                        mail_op);
+       modest_mail_operation_run_queue (mail_op, MODEST_TNY_SEND_QUEUE (self));
+       g_object_unref (mail_op);
+}
+
+static void 
 fill_list_of_caches (gpointer key, gpointer value, gpointer userdata)
 {
        GSList **send_queues = (GSList **) userdata;
 fill_list_of_caches (gpointer key, gpointer value, gpointer userdata)
 {
        GSList **send_queues = (GSList **) userdata;