New API function: tny_send_queue_add_async
- From: Javier Fernandez <jfernandez igalia com>
- To: tinymail-devel-list gnome org
- Subject: New API function: tny_send_queue_add_async
- Date: Sat, 1 Sep 2007 20:30:53 +0200
Hi,
This patch implements a new API function in TnySendQueue class, with
its
camel implementation of course.
The main purpose of this function is to provide an user callback for
adding message to OUTBOX. Current sync implementation uses
tny_folder_add_msg_async function to add message to OUTBOX in order
to avoid slow UI responses when big mails are sent. The problem is
that sync version of send_queue_add does not allow user callbacks, so
applications could not detect when messages is fully moved to OUTBOX.
--
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 2656)
+++ libtinymail-camel/tny-camel-send-queue.c (working copy)
@@ -28,6 +28,7 @@
#include <tny-folder.h>
#include <tny-error.h>
+#include <tny-camel-queue-priv.h>
#include <tny-camel-folder.h>
#include <tny-transport-account.h>
#include <tny-store-account.h>
@@ -64,6 +65,8 @@
guint signal_id;
} ControlInfo;
+
+
static gboolean
emit_error_on_mainloop (gpointer data)
{
@@ -173,8 +176,8 @@
info->total = total;
g_idle_add_full (G_PRIORITY_DEFAULT_IDLE,
- emit_control_signals_on_mainloop, info, destroy_control_info);
-
+ emit_control_signals_on_mainloop, info, destroy_control_info);
+
return;
}
@@ -298,6 +301,8 @@
/* 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);
+
+ sleep(45);
if (err == NULL)
{
@@ -480,23 +485,43 @@
typedef struct {
TnyMsg *msg;
TnySendQueue *self;
+ TnySendQueueAddCallback callback;
+ TnyStatusCallback status_callback;
+ TnyIdleStopper* stopper;
+ gboolean cancelled;
+ guint depth;
+ TnySessionCamel *session;
+ GCond* condition;
+ gboolean had_callback;
+ GMutex *mutex;
+ gpointer user_data;
} OnAddedInfo;
+
static void
on_added (TnyFolder *folder, gboolean cancelled, GError *err, gpointer user_data)
{
OnAddedInfo *info = (OnAddedInfo *) user_data;
TnyCamelSendQueuePriv *priv = TNY_CAMEL_SEND_QUEUE_GET_PRIVATE (info->self);
- if (err)
- emit_error (info->self, NULL, info->msg, err, priv->total, priv->total+1);
+ /* Call user callback after msg has beed added to OUTBOX, waiting to be sent*/
+ if (info->callback) {
+ info->callback (info->self, info->cancelled, info->msg, info->user_data, err);
+ }
+ if (err) {
+ emit_error (info->self, NULL, info->msg, err, priv->total, priv->total+1);
+ }
+
priv->total++;
if (priv->total >= 1 && !priv->is_running)
create_worker (info->self);
- g_object_unref (info->self);
- g_object_unref (info->msg);
+
+ if (info->self)
+ g_object_unref (info->self);
+ if (info->msg)
+ g_object_unref (info->msg);
g_slice_free (OnAddedInfo, info);
return;
@@ -556,6 +581,70 @@
}
+static void
+tny_camel_send_queue_add_async (TnySendQueue *self, TnyMsg *msg, TnySendQueueAddCallback callback, TnyStatusCallback status_callback, gpointer user_data)
+{
+ TNY_CAMEL_SEND_QUEUE_GET_CLASS (self)->add_async_func (self, msg, callback, status_callback, user_data);
+}
+
+
+static void
+tny_camel_send_queue_add_async_default (TnySendQueue *self, TnyMsg *msg, TnySendQueueAddCallback callback, TnyStatusCallback status_callback, gpointer user_data)
+{
+ TnyCamelSendQueuePriv *priv = TNY_CAMEL_SEND_QUEUE_GET_PRIVATE (self);
+ GError *err = NULL;
+
+ g_assert (TNY_IS_CAMEL_MSG (msg));
+
+ g_mutex_lock (priv->todo_lock);
+ {
+ TnyFolder *outbox;
+ TnyList *headers = tny_simple_list_new ();
+ OnAddedInfo *info = NULL;
+
+ outbox = tny_send_queue_get_outbox (self);
+
+ 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;
+ }
+
+ tny_folder_get_headers (outbox, headers, TRUE, &err);
+
+ if (err!= NULL)
+ {
+ g_object_unref (headers);
+ g_object_unref (outbox);
+ g_mutex_unlock (priv->todo_lock);
+ return;
+ }
+
+ priv->total = tny_list_get_length (headers);
+ g_object_unref (headers);
+
+ info = g_slice_new (OnAddedInfo);
+ info->msg = TNY_MSG (g_object_ref (msg));
+ info->self = TNY_SEND_QUEUE (g_object_ref (self));
+ info->callback = callback;
+ info->user_data = user_data;
+
+ tny_folder_add_msg_async (outbox, msg, on_added, NULL, info);
+
+ g_object_unref (outbox);
+ }
+ g_mutex_unlock (priv->todo_lock);
+
+ return;
+}
+
+
static TnyFolder*
create_maildir (TnySendQueue *self, const gchar *name)
{
@@ -823,6 +912,7 @@
TnySendQueueIface *klass = (TnySendQueueIface *)g;
klass->add_func = tny_camel_send_queue_add;
+ klass->add_async_func = tny_camel_send_queue_add_async;
klass->get_outbox_func = tny_camel_send_queue_get_outbox;
klass->get_sentbox_func = tny_camel_send_queue_get_sentbox;
klass->cancel_func = tny_camel_send_queue_cancel;
@@ -839,6 +929,7 @@
object_class = (GObjectClass*) class;
class->add_func = tny_camel_send_queue_add_default;
+ class->add_async_func = tny_camel_send_queue_add_async_default;
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;
Index: libtinymail-camel/tny-camel-send-queue.h
===================================================================
--- libtinymail-camel/tny-camel-send-queue.h (revision 2656)
+++ libtinymail-camel/tny-camel-send-queue.h (working copy)
@@ -50,6 +50,7 @@
/* virtual methods */
void (*add_func) (TnySendQueue *self, TnyMsg *msg, GError **err);
+ void (*add_async_func) (TnySendQueue *self, TnyMsg *msg, TnySendQueueAddCallback callback, TnyStatusCallback status_callback, gpointer user_data);
TnyFolder* (*get_sentbox_func) (TnySendQueue *self);
TnyFolder* (*get_outbox_func) (TnySendQueue *self);
void (*cancel_func) (TnySendQueue *self, gboolean remove, GError **err);
Index: libtinymail/tny-send-queue.c
===================================================================
--- libtinymail/tny-send-queue.c (revision 2656)
+++ libtinymail/tny-send-queue.c (working copy)
@@ -133,8 +133,31 @@
}
+/**
+ * tny_send_queue_add_async:
+ * @self: A #TnySendQueue instance
+ * @msg: a #TnyMsg instance
+ * @err: a #GError instance or NULL
+ *
+ * Add a message to the send queue.
+ *
+ **/
+void
+tny_send_queue_add_async (TnySendQueue *self, TnyMsg *msg, TnySendQueueAddCallback callback, TnyStatusCallback status_callback, gpointer user_data)
+{
+#ifdef DBC /* require */
+ g_assert (TNY_IS_SEND_QUEUE (self));
+ g_assert (msg);
+ g_assert (TNY_IS_MSG (msg));
+ g_assert (TNY_SEND_QUEUE_GET_IFACE (self)->add_async_func != NULL);
+#endif
+ TNY_SEND_QUEUE_GET_IFACE (self)->add_async_func (self, msg, callback, status_callback, user_data);
+ return;
+}
+
+
static void
tny_send_queue_base_init (gpointer g_class)
{
Index: libtinymail/tny-send-queue.h
===================================================================
--- libtinymail/tny-send-queue.h (revision 2656)
+++ libtinymail/tny-send-queue.h (working copy)
@@ -62,6 +62,7 @@
/* methods */
void (*add_func) (TnySendQueue *self, TnyMsg *msg, GError **err);
+ void (*add_async_func) (TnySendQueue *self, TnyMsg *msg, TnySendQueueAddCallback callback, TnyStatusCallback status_callback, gpointer user_data);
TnyFolder* (*get_sentbox_func) (TnySendQueue *self);
TnyFolder* (*get_outbox_func) (TnySendQueue *self);
void (*cancel_func) (TnySendQueue *self, gboolean remove, GError **err);
@@ -71,6 +72,7 @@
GType tny_send_queue_get_type (void);
void tny_send_queue_add (TnySendQueue *self, TnyMsg *msg, GError **err);
+void tny_send_queue_add_async (TnySendQueue *self, TnyMsg *msg, TnySendQueueAddCallback callback, TnyStatusCallback status_callback, gpointer user_data);
TnyFolder* tny_send_queue_get_sentbox (TnySendQueue *self);
TnyFolder* tny_send_queue_get_outbox (TnySendQueue *self);
void tny_send_queue_cancel (TnySendQueue *self, gboolean remove, GError **err);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]