X-Git-Url: http://git.maemo.org/git/?p=modest;a=blobdiff_plain;f=src%2Fmodest-mail-operation-queue.c;h=02b1f1a3016c296d837feb632c44c5479dc5319b;hp=7bf680bc813f3c1e41382f292e73b66025cf39f3;hb=8b08d2fd3eebc0584a5c49abdcd26c52b65737f0;hpb=cd1ae71abedf78491c1f34d1fb1a772064d87b8e diff --git a/src/modest-mail-operation-queue.c b/src/modest-mail-operation-queue.c index 7bf680b..02b1f1a 100644 --- a/src/modest-mail-operation-queue.c +++ b/src/modest-mail-operation-queue.c @@ -31,6 +31,7 @@ #include "modest-marshal.h" #include "modest-mail-operation-queue.h" #include "modest-runtime.h" +#include "modest-debug.h" /* 'private'/'protected' functions */ static void modest_mail_operation_queue_class_init (ModestMailOperationQueueClass *klass); @@ -38,13 +39,13 @@ static void modest_mail_operation_queue_init (ModestMailOperationQueue *ob static void modest_mail_operation_queue_finalize (GObject *obj); static void -on_progress_changed (ModestMailOperation *mail_op, - ModestMailOperationState *state, - gpointer user_data); +on_operation_finished (ModestMailOperation *mail_op, + gpointer user_data); /* list my signals */ enum { QUEUE_CHANGED_SIGNAL, + QUEUE_EMPTY_SIGNAL, NUM_SIGNALS }; @@ -116,6 +117,23 @@ modest_mail_operation_queue_class_init (ModestMailOperationQueueClass *klass) NULL, NULL, modest_marshal_VOID__POINTER_INT, G_TYPE_NONE, 2, G_TYPE_POINTER, G_TYPE_INT); + + /** + * ModestMailOperationQueue::queue-empty + * @self: the #ModestMailOperationQueue that emits the signal + * @user_data: user data set when the signal handler was connected + * + * Issued whenever the queue is empty + */ + signals[QUEUE_EMPTY_SIGNAL] = + g_signal_new ("queue-empty", + G_TYPE_FROM_CLASS (gobject_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (ModestMailOperationQueueClass, queue_empty), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + } static void @@ -131,6 +149,16 @@ modest_mail_operation_queue_init (ModestMailOperationQueue *obj) } static void +print_queue_item (ModestMailOperation *op, const gchar* prefix) +{ + gchar *op_str = modest_mail_operation_to_string (op); + g_debug ("%s: %s", + prefix ? prefix : "", + op_str); + g_free (op_str); +} + +static void on_finalize_foreach(gpointer op, gpointer user_data) { @@ -145,8 +173,10 @@ on_finalize_foreach(gpointer op, /* Simply remove from queue, but without emitting a * QUEUE_CHANGED_SIGNAL because we are in finalize anyway and have * the lock acquired. */ - g_signal_handlers_disconnect_by_func (mail_op, G_CALLBACK (on_progress_changed), user_data); + g_signal_handlers_disconnect_by_func (mail_op, G_CALLBACK (on_operation_finished), user_data); + MODEST_DEBUG_BLOCK (print_queue_item (mail_op, "cancel/remove");); + modest_mail_operation_cancel (mail_op); g_queue_remove (priv->op_queue, mail_op); g_object_unref (G_OBJECT (mail_op)); @@ -161,6 +191,13 @@ modest_mail_operation_queue_finalize (GObject *obj) g_mutex_lock (priv->queue_lock); + MODEST_DEBUG_BLOCK ( + g_debug ("%s; items in queue: %d", + __FUNCTION__, g_queue_get_length (priv->op_queue)); + g_queue_foreach (priv->op_queue, (GFunc)print_queue_item, "in queue"); + ); + + if (priv->op_queue) { /* Cancel all */ if (!g_queue_is_empty (priv->op_queue)) { @@ -187,17 +224,12 @@ modest_mail_operation_queue_new (void) } static void -on_progress_changed (ModestMailOperation *mail_op, - ModestMailOperationState *state, - gpointer user_data) +on_operation_finished (ModestMailOperation *mail_op, + gpointer user_data) { - ModestMailOperationQueue *queue; - - if(!state->finished) - return; + ModestMailOperationQueue *queue = MODEST_MAIL_OPERATION_QUEUE (user_data); /* Remove operation from queue when finished */ - queue = MODEST_MAIL_OPERATION_QUEUE (user_data); modest_mail_operation_queue_remove (queue, mail_op); } @@ -214,12 +246,18 @@ modest_mail_operation_queue_add (ModestMailOperationQueue *self, g_mutex_lock (priv->queue_lock); g_queue_push_tail (priv->op_queue, g_object_ref (mail_op)); - modest_mail_operation_set_id (mail_op, priv->op_id++); g_mutex_unlock (priv->queue_lock); + + MODEST_DEBUG_BLOCK (print_queue_item (mail_op, "add");); - /* Get notified when the operation ends to remove it from the queue */ - g_signal_connect (G_OBJECT (mail_op), "progress_changed", - G_CALLBACK (on_progress_changed), self); + /* Get notified when the operation ends to remove it from the + queue. We connect it using the *after* because we want to + let the other handlers for the finish function happen + before this */ + g_signal_connect_after (G_OBJECT (mail_op), + "operation-finished", + G_CALLBACK (on_operation_finished), + self); /* Notify observers */ g_signal_emit (self, signals[QUEUE_CHANGED_SIGNAL], 0, @@ -242,8 +280,10 @@ modest_mail_operation_queue_remove (ModestMailOperationQueue *self, g_queue_remove (priv->op_queue, mail_op); g_mutex_unlock (priv->queue_lock); + MODEST_DEBUG_BLOCK (print_queue_item (mail_op, "remove");); + g_signal_handlers_disconnect_by_func (G_OBJECT (mail_op), - G_CALLBACK (on_progress_changed), + G_CALLBACK (on_operation_finished), self); /* Notify observers */ @@ -278,6 +318,9 @@ modest_mail_operation_queue_remove (ModestMailOperationQueue *self, * 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); } guint @@ -308,6 +351,8 @@ modest_mail_operation_queue_cancel (ModestMailOperationQueue *self, priv = MODEST_MAIL_OPERATION_QUEUE_GET_PRIVATE(self); + MODEST_DEBUG_BLOCK (print_queue_item (mail_op, "cancel");); + /* This triggers a progess_changed signal in which we remove * the operation from the queue. */ modest_mail_operation_cancel (mail_op); @@ -353,3 +398,46 @@ modest_mail_operation_queue_cancel_all (ModestMailOperationQueue *self) g_slist_free(operations_to_cancel); } + +typedef struct +{ + GSList **new_list; + GObject *source; +} FindBySourceInfo; + +static void +on_find_by_source_foreach (gpointer op, gpointer data) +{ + FindBySourceInfo *info = (FindBySourceInfo*) data; + + if ( info->source == modest_mail_operation_get_source (MODEST_MAIL_OPERATION (op))) { + g_object_ref (G_OBJECT (op)); + *(info->new_list) = g_slist_prepend (*(info->new_list), MODEST_MAIL_OPERATION (op)); + } +} + +GSList* +modest_mail_operation_queue_get_by_source ( + ModestMailOperationQueue *self, + GObject *source) +{ + ModestMailOperationQueuePrivate *priv; + GSList* found_operations= NULL; + FindBySourceInfo *info = g_new0 (FindBySourceInfo, 1); + + g_return_val_if_fail (MODEST_IS_MAIL_OPERATION_QUEUE (self), NULL); + g_return_val_if_fail (source != NULL, NULL); + + priv = MODEST_MAIL_OPERATION_QUEUE_GET_PRIVATE(self); + + info->new_list = &found_operations; + info->source = source; + + g_mutex_lock (priv->queue_lock); + g_queue_foreach (priv->op_queue, (GFunc) on_find_by_source_foreach, info); + g_mutex_unlock (priv->queue_lock); + + g_free (info); + + return found_operations; +}