Re: Experimental patch to implement sent and sending signal on tny-camel-send-queue
- From: Javier Fernandez <jfernandez igalia com>
- To: tinymail-devel-list gnome org
- Subject: Re: Experimental patch to implement sent and sending signal on tny-camel-send-queue
- Date: Thu, 21 Jun 2007 08:37:54 +0200
Another version of this patch.
--
Javier Fernández García-Boente
Ingeniero en Informática
mailto:jfernandez igalia com
Igalia http://www.igalia.com
Telf. +34 981 91 39 91
Fax. +34 981 91 39 49
Index: libtinymail-camel/tny-camel-send-queue.c
===================================================================
--- libtinymail-camel/tny-camel-send-queue.c (revision 2234)
+++ libtinymail-camel/tny-camel-send-queue.c (working copy)
@@ -28,6 +28,8 @@
#include <tny-folder.h>
#include <tny-error.h>
+
+#include <tny-folder-observer.h>
#include <tny-camel-folder.h>
#include <tny-transport-account.h>
@@ -53,6 +55,14 @@
gint i, total;
} ErrorInfo;
+typedef struct {
+ TnySendQueue *self;
+ TnyMsg *msg;
+ TnyHeader *header;
+ gint i, total;
+ guint signal_id;
+} ControlInfo;
+
static gboolean
emit_error_on_mainloop (gpointer data)
{
@@ -62,6 +72,15 @@
return FALSE;
}
+static gboolean
+emit_control_signals_on_mainloop (gpointer data)
+{
+ ControlInfo *info = data;
+ g_signal_emit (info->self, tny_send_queue_signals [info->signal_id],
+ 0, info->header, info->msg, info->i, info->total);
+ return FALSE;
+}
+
static void
destroy_error_info (gpointer data)
{
@@ -78,6 +97,20 @@
}
static void
+destroy_control_info (gpointer data)
+{
+ ControlInfo *info = data;
+
+ if (info->msg)
+ g_object_unref (G_OBJECT (info->msg));
+ if (info->header)
+ g_object_unref (G_OBJECT (info->header));
+ if (info->self)
+ g_object_unref (G_OBJECT (info->self));
+
+ g_slice_free (ControlInfo, info);
+}
+
emit_error (TnySendQueue *self, TnyHeader *header, TnyMsg *msg, GError *error, int i, int total)
{
ErrorInfo *info = g_slice_new0 (ErrorInfo);
@@ -100,6 +133,28 @@
return;
}
+static void
+emit_control (TnySendQueue *self, TnyHeader *header, TnyMsg *msg, guint signal_id, int i, int total)
+{
+ ControlInfo *info = g_slice_new0 (ControlInfo);
+
+ if (self)
+ info->self = TNY_SEND_QUEUE (g_object_ref (G_OBJECT (self)));
+ if (msg)
+ info->msg = TNY_MSG (g_object_ref (G_OBJECT (msg)));
+ if (header)
+ info->header = TNY_HEADER (g_object_ref (G_OBJECT (header)));
+
+ info->signal_id = signal_id;
+ info->i = i;
+ info->total = total;
+
+ g_idle_add_full (G_PRIORITY_DEFAULT_IDLE,
+ emit_control_signals_on_mainloop, info, destroy_control_info);
+
+ return;
+}
+
static gpointer
thread_main (gpointer data)
{
@@ -131,8 +186,8 @@
goto errorhandler;
}
+ /* I dont expect total is being changed */
length = tny_list_get_length (list);
- priv->total = length;
}
g_mutex_unlock (priv->todo_lock);
@@ -165,10 +220,9 @@
goto errorhandler;
}
+ /* I dont expect total is being changed */
length = tny_list_get_length (headers);
- priv->total = length;
-
if (length <= 0)
{
g_object_unref (G_OBJECT (headers));
@@ -185,7 +239,6 @@
}
g_mutex_unlock (priv->todo_lock);
-
if (header && TNY_IS_HEADER (header))
{
TnyList *hassent = tny_simple_list_new ();
@@ -194,6 +247,9 @@
tny_list_prepend (hassent, G_OBJECT (header));
msg = tny_folder_get_msg (outbox, header, &err);
+ /* Emits msg-sending signal to inform a new msg is being sent */
+ emit_control (self, header, msg, TNY_SEND_QUEUE_MSG_SENDING, i, priv->total);
+
/* hassent is owner now */
g_object_unref (G_OBJECT (header));
@@ -222,9 +278,12 @@
priv->do_continue = FALSE;
g_error_free (newerr);
}
- priv->total--;
}
}
+
+ /* Emits msg-sent signal to inform msg has been sent */
+ emit_control (self, header, msg, TNY_SEND_QUEUE_MSG_SENT, i, priv->total);
+
g_mutex_unlock (priv->todo_lock);
g_object_unref (G_OBJECT (hassent));
@@ -352,61 +411,67 @@
static void
tny_camel_send_queue_add_default (TnySendQueue *self, TnyMsg *msg, GError **err)
{
- TnyCamelSendQueuePriv *priv = TNY_CAMEL_SEND_QUEUE_GET_PRIVATE (self);
+ TnyFolder *outbox = tny_send_queue_get_outbox (self);
g_assert (TNY_IS_CAMEL_MSG (msg));
- g_mutex_lock (priv->todo_lock);
- {
- TnyFolder *outbox;
- TnyList *headers = tny_simple_list_new ();
+ if (!outbox || !TNY_IS_FOLDER (outbox)) {
+ g_set_error (err, TNY_SEND_QUEUE_ERROR,
+ TNY_SEND_QUEUE_ERROR_ADD,
+ "Operating can't continue: send queue not ready "
+ "because it does not have a valid outbox. "
+ "This problem indicates a bug in the software.");
+ return;
+ }
- outbox = tny_send_queue_get_outbox (self);
+ tny_folder_add_msg (outbox, msg, err);
- if (!outbox || !TNY_IS_FOLDER (outbox))
- {
- g_set_error (err, TNY_SEND_QUEUE_ERROR,
- TNY_SEND_QUEUE_ERROR_ADD,
- "Operating can't continue: send queue not ready "
- "because it does not have a valid outbox. "
- "This problem indicates a bug in the software.");
- g_object_unref (headers);
- g_mutex_unlock (priv->todo_lock);
- return;
- }
+ g_object_unref (outbox);
+ return;
+}
- tny_folder_get_headers (outbox, headers, TRUE, err);
+static void
+tny_camel_send_queue_update (TnyFolderObserver *self, TnyFolderChange *change)
+{
+ TNY_CAMEL_SEND_QUEUE_GET_CLASS (self)->update_func (self, change);
+ return;
+}
- if (err!= NULL && *err != NULL)
- {
- g_object_unref (G_OBJECT (headers));
- g_object_unref (G_OBJECT (outbox));
- g_mutex_unlock (priv->todo_lock);
- return;
- }
+static void
+tny_camel_send_queue_update_default (TnyFolderObserver *self, TnyFolderChange *change)
+{
+ TnyCamelSendQueuePriv *priv = TNY_CAMEL_SEND_QUEUE_GET_PRIVATE (self);
+ TnyFolder *outbox;
+ TnyFolderChangeChanged changed;
+ ErrorInfo *info;
+ TnyList *headers;
+ gint i = 0;
- priv->total = tny_list_get_length (headers);
- g_object_unref (G_OBJECT (headers));
+ g_mutex_lock (priv->todo_lock);
- tny_folder_add_msg (outbox, msg, err);
+ changed = tny_folder_change_get_changed (change);
- if (err!= NULL && *err != NULL)
- {
- g_object_unref (G_OBJECT (outbox));
- g_mutex_unlock (priv->todo_lock);
- return;
- }
+ if (changed & TNY_FOLDER_CHANGE_CHANGED_ADDED_HEADERS) {
+ outbox = tny_send_queue_get_outbox (TNY_SEND_QUEUE (self));
- priv->total++;
+ /* The added headers */
+ headers = tny_simple_list_new ();
+ tny_folder_change_get_added_headers (change, headers);
+ priv->total = tny_list_get_length (headers);
+ g_object_unref (G_OBJECT (headers));
+
if (priv->total >= 1 && !priv->thread && !priv->creating_spin)
- create_worker (self);
+ create_worker (TNY_SEND_QUEUE(self));
g_object_unref (G_OBJECT (outbox));
}
+
g_mutex_unlock (priv->todo_lock);
-
+
return;
+
+
}
@@ -684,9 +749,9 @@
class->get_outbox_func = tny_camel_send_queue_get_outbox_default;
class->get_sentbox_func = tny_camel_send_queue_get_sentbox_default;
class->cancel_func = tny_camel_send_queue_cancel_default;
+ class->update_func = tny_camel_send_queue_update_default;
object_class->finalize = tny_camel_send_queue_finalize;
-
g_type_class_add_private (object_class, sizeof (TnyCamelSendQueuePriv));
return;
@@ -710,6 +775,12 @@
return;
}
+static void
+tny_folder_observer_init (TnyFolderObserverIface *klass)
+{
+ klass->update_func = tny_camel_send_queue_update;
+}
+
/**
* tny_camel_send_queue_get_type:
*
@@ -754,6 +825,13 @@
NULL /* interface_data */
};
+ static const GInterfaceInfo tny_folder_observer_info = {
+ (GInterfaceInitFunc) tny_folder_observer_init,
+ NULL,
+ NULL
+ };
+
+
type = g_type_register_static (G_TYPE_OBJECT,
"TnyCamelSendQueue",
&info, 0);
@@ -761,6 +839,9 @@
g_type_add_interface_static (type, TNY_TYPE_SEND_QUEUE,
&tny_send_queue_info);
+
+ g_type_add_interface_static (type, TNY_TYPE_FOLDER_OBSERVER,
+ &tny_folder_observer_info);
}
return type;
Index: libtinymail-camel/tny-camel-send-queue.h
===================================================================
--- libtinymail-camel/tny-camel-send-queue.h (revision 2234)
+++ libtinymail-camel/tny-camel-send-queue.h (working copy)
@@ -53,6 +53,7 @@
TnyFolder* (*get_sentbox_func) (TnySendQueue *self);
TnyFolder* (*get_outbox_func) (TnySendQueue *self);
void (*cancel_func) (TnySendQueue *self, gboolean remove, GError **err);
+ void (*update_func) (TnyFolderObserver *self, TnyFolderChange *change);
};
GType tny_camel_send_queue_get_type (void);
Index: libtinymail-queues/tny-generic-send-queue.c
===================================================================
--- libtinymail-queues/tny-generic-send-queue.c (revision 2234)
+++ libtinymail-queues/tny-generic-send-queue.c (working copy)
@@ -182,6 +182,10 @@
info->self = TNY_GENERIC_SEND_QUEUE (g_object_ref (self));
info->msg = tny_folder_get_msg (outbox, header, &err);
+ /* Emits msg-sending signal to inform a new msg is being sent */
+ g_signal_emit (self, tny_send_queue_signals [TNY_SEND_QUEUE_MSG_SENDING],
+ 0, info->msg, err, i, total);
+
if (err != NULL)
{
emit_error (TNY_SEND_QUEUE (self), NULL, err, info->i, info->total);
@@ -205,7 +209,11 @@
tny_queue_task_set_callback (task, generic_send_callback);
item = tny_queue_add_task (priv->queue, task);
-
+
+ /* Emits msg-sent signal to inform msg has been sent */
+ g_signal_emit (self, tny_send_queue_signals [TNY_SEND_QUEUE_MSG_SENT],
+ 0, info->msg, err, i, total);
+
g_object_unref (header);
tny_iterator_next (iter);
i++;
Index: libtinymail/tny-signals-marshal.list
===================================================================
--- libtinymail/tny-signals-marshal.list (revision 2234)
+++ libtinymail/tny-signals-marshal.list (working copy)
@@ -1 +1,2 @@
VOID:OBJECT,OBJECT,POINTER
+VOID:OBJECT,OBJECT,INT,INT
Index: libtinymail/tny-send-queue.c
===================================================================
--- libtinymail/tny-send-queue.c (revision 2234)
+++ libtinymail/tny-send-queue.c (working copy)
@@ -143,6 +143,26 @@
if (!initialized)
{
/**
+ * TnySendQueue::msg-sending
+ * @self: the object on which the signal is emitted
+ * @arg1: The message that is being
+ * @arg2: The current nth number of the message that is being sending
+ * @arg3: The total amount of messages currently being processed
+ *
+ * API WARNING: This API might change
+ *
+ * Emitted when a message is being proccessed to sending it
+ **/
+ tny_send_queue_signals[TNY_SEND_QUEUE_MSG_SENDING] =
+ g_signal_new ("msg_sending",
+ TNY_TYPE_SEND_QUEUE,
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (TnySendQueueIface, msg_sending),
+ NULL, NULL,
+ tny_marshal_VOID__OBJECT_OBJECT_INT_INT,
+ G_TYPE_NONE, 4, TNY_TYPE_HEADER, TNY_TYPE_MSG, G_TYPE_UINT, G_TYPE_UINT);
+
+/**
* TnySendQueue::msg-sent
* @self: the object on which the signal is emitted
* @arg1: The message that got sent
@@ -151,13 +171,13 @@
* Emitted when a message got sent
**/
tny_send_queue_signals[TNY_SEND_QUEUE_MSG_SENT] =
- g_signal_new ("msg_sent",
- TNY_TYPE_SEND_QUEUE,
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (TnySendQueueIface, msg_sent),
- NULL, NULL,
- g_cclosure_marshal_VOID__POINTER,
- G_TYPE_NONE, 1, TNY_TYPE_MSG);
+ g_signal_new ("msg_sent",
+ TNY_TYPE_SEND_QUEUE,
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (TnySendQueueIface, msg_sent),
+ NULL, NULL,
+ tny_marshal_VOID__OBJECT_OBJECT_INT_INT,
+ G_TYPE_NONE, 4, TNY_TYPE_HEADER, TNY_TYPE_MSG, G_TYPE_UINT, G_TYPE_UINT);
/**
* TnySendQueue::error-happened
@@ -171,14 +191,14 @@
* Emitted when a message didn't get sent because of an error
**/
tny_send_queue_signals[TNY_SEND_QUEUE_ERROR_HAPPENED] =
- g_signal_new ("error_happened",
- TNY_TYPE_SEND_QUEUE,
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (TnySendQueueIface, error_happened),
- NULL, NULL,
- tny_marshal_VOID__OBJECT_OBJECT_POINTER,
- G_TYPE_NONE, 3, TNY_TYPE_HEADER, TNY_TYPE_MSG, G_TYPE_POINTER);
-
+ g_signal_new ("error_happened",
+ TNY_TYPE_SEND_QUEUE,
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (TnySendQueueIface, error_happened),
+ NULL, NULL,
+ tny_marshal_VOID__OBJECT_OBJECT_POINTER,
+ G_TYPE_NONE, 3, TNY_TYPE_HEADER, TNY_TYPE_MSG, G_TYPE_POINTER);
+
initialized = TRUE;
}
}
Index: libtinymail/tny-send-queue.h
===================================================================
--- libtinymail/tny-send-queue.h (revision 2234)
+++ libtinymail/tny-send-queue.h (working copy)
@@ -40,6 +40,7 @@
enum _TnySendQueueSignal
{
+ TNY_SEND_QUEUE_MSG_SENDING,
TNY_SEND_QUEUE_MSG_SENT,
TNY_SEND_QUEUE_ERROR_HAPPENED,
TNY_SEND_QUEUE_LAST_SIGNAL
@@ -53,7 +54,8 @@
GTypeInterface parent;
/* Signals */
- void (*msg_sent) (TnySendQueue *self, TnyMsg *msg, gpointer user_data);
+ void (*msg_sending) (TnySendQueue *self, TnyHeader *header, TnyMsg *msg, guint nth, guint total);
+ void (*msg_sent) (TnySendQueue *self, TnyHeader *header, TnyMsg *msg, guint nth, guint total);
void (*error_happened) (TnySendQueue *self, TnyHeader *header, TnyMsg *msg, GError *err, gpointer user_data);
/* methods */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]