* Fixes NB#85964, do not crash when opening Drafts in memory full condition
[modest] / src / modest-mail-operation.c
index 3098926..8b38cd6 100644 (file)
@@ -510,7 +510,8 @@ modest_mail_operation_cancel (ModestMailOperation *self)
                                                       TRUE);
 
                /* Cancel the sending of the following next messages */
-               tny_send_queue_cancel (TNY_SEND_QUEUE (queue), TNY_SEND_QUEUE_CANCEL_ACTION_SUSPEND, NULL);
+               if (TNY_IS_SEND_QUEUE (queue))
+                       tny_send_queue_cancel (TNY_SEND_QUEUE (queue), TNY_SEND_QUEUE_CANCEL_ACTION_SUSPEND, NULL);
        }
        
        return canceled;
@@ -1440,24 +1441,26 @@ inbox_refreshed_cb (TnyFolder *inbox,
                send_queue = modest_runtime_get_send_queue (transport_account, TRUE);
                g_object_unref (transport_account);
 
-               /* Get outbox folder */
-               outbox = tny_send_queue_get_outbox (TNY_SEND_QUEUE (send_queue));
-               if (outbox) { /* this could fail in some cases */
-                       num_messages = tny_folder_get_all_count (outbox);
-                       g_object_unref (outbox);
-               } else {
-                       g_warning ("%s: could not get outbox", __FUNCTION__);
-                       num_messages = 0;
-               }
+               if (TNY_IS_SEND_QUEUE (send_queue)) {
+                       /* Get outbox folder */
+                       outbox = tny_send_queue_get_outbox (TNY_SEND_QUEUE (send_queue));
+                       if (outbox) { /* this could fail in some cases */
+                               num_messages = tny_folder_get_all_count (outbox);
+                               g_object_unref (outbox);
+                       } else {
+                               g_warning ("%s: could not get outbox", __FUNCTION__);
+                               num_messages = 0;
+                       }
                
-               if (num_messages != 0) {
-                       /* Reenable suspended items */
-                       modest_tny_send_queue_wakeup (MODEST_TNY_SEND_QUEUE (send_queue));
-
-                       /* Try to send */
-                       tny_camel_send_queue_flush (TNY_CAMEL_SEND_QUEUE (send_queue));
-                       modest_tny_send_queue_set_requested_send_receive (MODEST_TNY_SEND_QUEUE (send_queue), 
-                                                                         info->interactive);
+                       if (num_messages != 0) {
+                               /* Reenable suspended items */
+                               modest_tny_send_queue_wakeup (MODEST_TNY_SEND_QUEUE (send_queue));
+                               
+                               /* Try to send */
+                               tny_camel_send_queue_flush (TNY_CAMEL_SEND_QUEUE (send_queue));
+                               modest_tny_send_queue_set_requested_send_receive (MODEST_TNY_SEND_QUEUE (send_queue), 
+                                                                                 info->interactive);
+                       }
                }
        }
 
@@ -2607,22 +2610,25 @@ modest_mail_operation_remove_msgs (ModestMailOperation *self,
                if (traccount) {
                        ModestTnySendQueueStatus status;
                        ModestTnySendQueue *send_queue = modest_runtime_get_send_queue(traccount, TRUE);
-                       TnyIterator *iter = tny_list_create_iterator(headers);
-                       g_object_unref(remove_headers);
-                       remove_headers = TNY_LIST(tny_simple_list_new());
-                       while (!tny_iterator_is_done(iter)) {
-                               char *msg_id;
-                               TnyHeader *hdr = TNY_HEADER(tny_iterator_get_current(iter));
-                               msg_id = modest_tny_send_queue_get_msg_id (hdr);
-                               status = modest_tny_send_queue_get_msg_status(send_queue, msg_id);
-                               if (status != MODEST_TNY_SEND_QUEUE_SENDING) {
-                                       tny_list_append(remove_headers, G_OBJECT(hdr));
+
+                       if (TNY_IS_SEND_QUEUE (send_queue)) {
+                               TnyIterator *iter = tny_list_create_iterator(headers);
+                               g_object_unref(remove_headers);
+                               remove_headers = TNY_LIST(tny_simple_list_new());
+                               while (!tny_iterator_is_done(iter)) {
+                                       char *msg_id;
+                                       TnyHeader *hdr = TNY_HEADER(tny_iterator_get_current(iter));
+                                       msg_id = modest_tny_send_queue_get_msg_id (hdr);
+                                       status = modest_tny_send_queue_get_msg_status(send_queue, msg_id);
+                                       if (status != MODEST_TNY_SEND_QUEUE_SENDING) {
+                                               tny_list_append(remove_headers, G_OBJECT(hdr));
+                                       }
+                                       g_object_unref(hdr);
+                                       g_free(msg_id);
+                                       tny_iterator_next(iter);
                                }
-                               g_object_unref(hdr);
-                               g_free(msg_id);
-                               tny_iterator_next(iter);
+                               g_object_unref(iter);
                        }
-                       g_object_unref(iter);
                        g_object_unref(traccount);
                }
        }
@@ -2721,6 +2727,35 @@ transfer_msgs_status_cb (GObject *obj,
                                              &(helper->sum_total_bytes), helper->total_bytes, TRUE);
 }
 
+static void
+transfer_msgs_sync_folder_cb (TnyFolder *self, 
+                             gboolean cancelled, 
+                             GError *err, 
+                             gpointer user_data)
+{
+       XFerMsgsAsyncHelper *helper;
+       /* We don't care here about the results of the
+          synchronization */
+       helper = (XFerMsgsAsyncHelper *) user_data;
+
+       /* Notify about operation end */
+       modest_mail_operation_notify_end (helper->mail_op);
+
+       /* If user defined callback function was defined, call it */
+       if (helper->user_callback)
+               helper->user_callback (helper->mail_op, helper->user_data);
+       
+       /* Free */
+       if (helper->more_msgs)
+               g_object_unref (helper->more_msgs);
+       if (helper->headers)
+               g_object_unref (helper->headers);
+       if (helper->dest_folder)
+               g_object_unref (helper->dest_folder);
+       if (helper->mail_op)
+               g_object_unref (helper->mail_op);
+       g_slice_free (XFerMsgsAsyncHelper, helper);
+}
 
 static void
 transfer_msgs_cb (TnyFolder *folder, gboolean cancelled, GError *err, gpointer user_data)
@@ -2762,34 +2797,13 @@ transfer_msgs_cb (TnyFolder *folder, gboolean cancelled, GError *err, gpointer u
        }
 
        if (finished) {
-
-               /* Update folder counts */
-               tny_folder_poke_status (folder);
-               tny_folder_poke_status (helper->dest_folder);
-
-               /* Notify about operation end */
-               modest_mail_operation_notify_end (self);
-
-               /* If user defined callback function was defined, call it */
-               if (helper->user_callback) {
-                       /* This is not a GDK lock because we are a Tinymail callback and
-                        * Tinymail already acquires the Gdk lock */
-
-                       /* no gdk_threads_enter (), CHECKED */
-                       helper->user_callback (self, helper->user_data);
-                       /* no gdk_threads_leave (), CHECKED */
-               }
-
-               /* Free */
-               if (helper->more_msgs)
-                       g_object_unref (helper->more_msgs);
-               if (helper->headers)
-                       g_object_unref (helper->headers);
-               if (helper->dest_folder)
-                       g_object_unref (helper->dest_folder);
-               if (helper->mail_op)
-                       g_object_unref (helper->mail_op);
-               g_slice_free (XFerMsgsAsyncHelper, helper);
+               /* Synchronize the source folder contents. This should
+                  be done by tinymail but the camel_folder_sync it's
+                  actually disabled in transfer_msgs_thread_clean
+                  because it's supposed to cause hangs */
+               tny_folder_sync_async (folder, helper->delete, 
+                                      transfer_msgs_sync_folder_cb, 
+                                      NULL, helper);
        } else {
                /* Transfer more messages */
                tny_folder_transfer_msgs_async (folder,
@@ -3124,6 +3138,7 @@ run_queue_stop (ModestTnySendQueue *queue,
        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)
@@ -3144,6 +3159,42 @@ modest_mail_operation_run_queue (ModestMailOperation *self,
 }
 
 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,