X-Git-Url: http://git.maemo.org/git/?p=modest;a=blobdiff_plain;f=src%2Fmodest-mail-operation-queue.c;h=1ca44507d1f355f0dbb513ce340f16ff3295e7c6;hp=f00e992e36d55c1069b37de11c431db7bf726ea8;hb=8d4844a81a6d20c97f8916fd6a6a0e384d995ded;hpb=8c306434c896aedd04f74e98aaf80b22a1dc5506 diff --git a/src/modest-mail-operation-queue.c b/src/modest-mail-operation-queue.c index f00e992..1ca4450 100644 --- a/src/modest-mail-operation-queue.c +++ b/src/modest-mail-operation-queue.c @@ -54,6 +54,8 @@ struct _ModestMailOperationQueuePrivate { GQueue *op_queue; 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, \ @@ -146,6 +148,8 @@ modest_mail_operation_queue_init (ModestMailOperationQueue *obj) priv->op_queue = g_queue_new (); priv->queue_lock = g_mutex_new (); priv->op_id = 0; + priv->queue_empty_handler = 0; + priv->running_final_sync = FALSE; } static void @@ -244,6 +248,8 @@ modest_mail_operation_queue_add (ModestMailOperationQueue *self, 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); @@ -264,12 +270,45 @@ modest_mail_operation_queue_add (ModestMailOperationQueue *self, mail_op, MODEST_MAIL_OPERATION_QUEUE_OPERATION_ADDED); } +static gboolean +notify_queue_empty (gpointer user_data) +{ + ModestMailOperationQueue *self = (ModestMailOperationQueue *) user_data; + ModestMailOperationQueuePrivate *priv; + guint num_elements; + + priv = MODEST_MAIL_OPERATION_QUEUE_GET_PRIVATE(self); + + g_mutex_lock (priv->queue_lock); + num_elements = priv->op_queue->length; + g_mutex_unlock (priv->queue_lock); + + /* We re-check again that the queue is empty. It could happen + that we had issued a tny_send_queue_flush before the send + queue could add a mail operation to the queue as a response + to the "start-queue" signal, because that signal is issued + by tinymail in the main loop. Therefor it could happen that + we emit the queue-empty signal while a send-queue is still + waiting for the "start-queue" signal from tinymail, so the + send queue will never try to send the items because modest + is finalized before */ + if (num_elements == 0) { + gdk_threads_enter (); + g_signal_emit (self, signals[QUEUE_EMPTY_SIGNAL], 0); + gdk_threads_leave (); + } + + return FALSE; +} + + void modest_mail_operation_queue_remove (ModestMailOperationQueue *self, ModestMailOperation *mail_op) { ModestMailOperationQueuePrivate *priv; ModestMailOperationStatus status; + guint num_elements; g_return_if_fail (MODEST_IS_MAIL_OPERATION_QUEUE (self)); g_return_if_fail (MODEST_IS_MAIL_OPERATION (mail_op)); @@ -278,6 +317,7 @@ modest_mail_operation_queue_remove (ModestMailOperationQueue *self, g_mutex_lock (priv->queue_lock); g_queue_remove (priv->op_queue, mail_op); + num_elements = priv->op_queue->length; g_mutex_unlock (priv->queue_lock); MODEST_DEBUG_BLOCK (print_queue_item (mail_op, "remove");); @@ -292,7 +332,8 @@ modest_mail_operation_queue_remove (ModestMailOperationQueue *self, /* Check errors */ status = modest_mail_operation_get_status (mail_op); - if (status != MODEST_MAIL_OPERATION_STATUS_SUCCESS) { + if (status != MODEST_MAIL_OPERATION_STATUS_SUCCESS && + status != MODEST_MAIL_OPERATION_STATUS_INVALID) { /* This is a sanity check. Shouldn't be needed, but prevent possible application crashes. It's useful also for detecting mail operations with invalid @@ -311,16 +352,19 @@ modest_mail_operation_queue_remove (ModestMailOperationQueue *self, } /* Free object */ - - /* We do not own the last reference when this operation is deleted - * as response to a progress changed signal from the mail operation - * itself, in which case the glib signal system owns a reference - * until the signal emission is complete. armin. */ - /* modest_runtime_verify_object_last_ref (mail_op, ""); */ g_object_unref (G_OBJECT (mail_op)); - /* Emit the queue empty-signal */ - g_signal_emit (self, signals[QUEUE_EMPTY_SIGNAL], 0); + /* Emit the queue empty-signal. See the function to know why + we emit it in an idle */ + if (num_elements == 0) { + if (priv->queue_empty_handler) { + g_source_remove (priv->queue_empty_handler); + priv->queue_empty_handler = 0; + } + priv->queue_empty_handler = g_idle_add_full (G_PRIORITY_LOW, + notify_queue_empty, + self, NULL); + } } guint @@ -387,7 +431,7 @@ modest_mail_operation_queue_cancel_all (ModestMailOperationQueue *self) g_queue_foreach (priv->op_queue, (GFunc) on_cancel_all_foreach, &operations_to_cancel); g_mutex_unlock (priv->queue_lock); - /* TODO: Reverse the list, to remove operations in order? */ + operations_to_cancel = g_slist_reverse (operations_to_cancel); for(cur = operations_to_cancel; cur != NULL; cur = cur->next) { if (!MODEST_IS_MAIL_OPERATION(cur->data)) @@ -472,3 +516,25 @@ modest_mail_operation_queue_to_string (ModestMailOperationQueue *self) 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; +}