Re: Patch for the send queue
- From: Sergio Villar Senin <svillar igalia com>
- To: tinymail-devel-list gnome org
- Subject: Re: Patch for the send queue
- Date: Mon, 21 Jan 2008 11:47:38 +0100
Sergio Villar Senin wrote:
> Sergio Villar Senin wrote:
>> Hi,
>>
>> this patch does two things:
>> * makes the queue wait until the user finishes the process of the
>> error_happened notification
>> * allows the queue to go on even if the sending of one of the
>> messages in the outbox failed
>
> Second version of the patch, I missed a couple of strdup's.
And third version.
This patch changes the API, it replaces a gboolean by an enum type. Now
Tinymail could do two different things when tny_send_queue_cancel is called:
* using flag tinymail will remove the messages in the outbox
* using flag tinymail will set all the headers as SUSPENDED, this will
prevent the send queue from sending them but it'll keep the messages there
Br
Index: libtinymail-camel/tny-camel-send-queue.c
===================================================================
--- libtinymail-camel/tny-camel-send-queue.c (revision 3282)
+++ libtinymail-camel/tny-camel-send-queue.c (working copy)
@@ -57,6 +57,9 @@
TnyHeader *header;
GError *error;
gint i, total;
+ GCond *condition;
+ GMutex *mutex;
+ gboolean had_callback;
} ErrorInfo;
typedef struct {
@@ -114,8 +117,13 @@
g_object_unref (info->self);
if (info->error)
g_error_free (info->error);
- g_slice_free (ErrorInfo, info);
+
+ g_mutex_lock (info->mutex);
+ g_cond_broadcast (info->condition);
+ info->had_callback = TRUE;
+ g_mutex_unlock (info->mutex);
+
return;
}
@@ -134,9 +142,23 @@
info->header = TNY_HEADER (g_object_ref (header));
info->i = i;
info->total = total;
+ info->had_callback = FALSE;
+ info->mutex = g_mutex_new ();
+ info->condition = g_cond_new ();
+
g_idle_add_full (G_PRIORITY_DEFAULT_IDLE,
emit_error_on_mainloop, info, destroy_error_info);
+ g_mutex_lock (info->mutex);
+ if (!info->had_callback)
+ g_cond_wait (info->condition, info->mutex);
+ g_mutex_unlock (info->mutex);
+
+ g_mutex_free (info->mutex);
+ g_cond_free (info->condition);
+
+ g_slice_free (ErrorInfo, info);
+
return;
}
@@ -274,6 +296,7 @@
guint i = 0, length = 0;
TnyList *list = NULL;
TnyDevice *device = info->device;
+ GHashTable *failed_headers;
priv->is_running = TRUE;
list = tny_simple_list_new ();
@@ -316,9 +339,9 @@
g_object_unref (list);
- priv->do_continue = TRUE;
+ failed_headers = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
- while (length > 0 && priv->do_continue && tny_device_is_online (device))
+ while ((length - g_hash_table_size (failed_headers)) > 0 && tny_device_is_online (device))
{
TnyHeader *header = NULL;
TnyMsg *msg = NULL;
@@ -368,6 +391,21 @@
}
g_object_unref (giter);
+ /* Some code to remove the previously failed items */
+ giter = tny_list_create_iterator (headers);
+ while (!tny_iterator_is_done (giter))
+ {
+ TnyHeader *curhdr = TNY_HEADER (tny_iterator_get_current (giter));
+
+ if (g_hash_table_lookup_extended (failed_headers, tny_header_get_uid (curhdr),
+ NULL, NULL))
+ to_remove = g_list_prepend (to_remove, curhdr);
+
+ g_object_unref (curhdr);
+ tny_iterator_next (giter);
+ }
+ g_object_unref (giter);
+
while (to_remove) {
tny_list_remove (headers, G_OBJECT (to_remove->data));
to_remove = g_list_next (to_remove);
@@ -412,11 +450,13 @@
if (err != NULL) {
emit_error (self, header, msg, err, i, priv->total);
- priv->do_continue = FALSE;
+ g_hash_table_insert (failed_headers,
+ g_strdup (tny_header_get_uid (header)), NULL);
}
} else {
emit_error (self, header, msg, err, i, priv->total);
- priv->do_continue = FALSE;
+ g_hash_table_insert (failed_headers,
+ g_strdup (tny_header_get_uid (header)), NULL);
}
g_mutex_lock (priv->todo_lock);
@@ -427,10 +467,8 @@
priv->cur_i = i;
tny_header_set_flag (header, TNY_HEADER_FLAG_SEEN);
tny_folder_transfer_msgs (outbox, hassent, sentbox, TRUE, &newerr);
- if (newerr != NULL)
- {
+ if (newerr != NULL) {
emit_error (self, header, msg, newerr, i, priv->total);
- priv->do_continue = FALSE;
g_error_free (newerr);
}
priv->total--;
@@ -465,12 +503,12 @@
}
- priv->is_running = FALSE;
-
errorhandler:
priv->is_running = FALSE;
+ g_hash_table_destroy (failed_headers);
+
g_object_unref (sentbox);
g_object_unref (outbox);
@@ -506,66 +544,65 @@
static void
-tny_camel_send_queue_cancel (TnySendQueue *self, gboolean remove, GError **err)
+tny_camel_send_queue_cancel (TnySendQueue *self, TnySendQueueCancelAction cancel_action, GError **err)
{
- TNY_CAMEL_SEND_QUEUE_GET_CLASS (self)->cancel_func (self, remove, err);
+ TNY_CAMEL_SEND_QUEUE_GET_CLASS (self)->cancel_func (self, cancel_action, err);
}
static void
-tny_camel_send_queue_cancel_default (TnySendQueue *self, gboolean remove, GError **err)
+tny_camel_send_queue_cancel_default (TnySendQueue *self, TnySendQueueCancelAction cancel_action, GError **err)
{
TnyCamelSendQueuePriv *priv = TNY_CAMEL_SEND_QUEUE_GET_PRIVATE (self);
+ TnyFolder *outbox;
+ TnyList *headers = tny_simple_list_new ();
+ TnyIterator *iter;
g_mutex_lock (priv->sending_lock);
priv->is_running = FALSE;
- priv->do_continue = FALSE;
- if (remove)
+ outbox = tny_send_queue_get_outbox (self);
+
+ tny_folder_get_headers (outbox, headers, TRUE, err);
+
+ if (err != NULL && *err != NULL)
{
- TnyFolder *outbox;
- TnyList *headers = tny_simple_list_new ();
- TnyIterator *iter;
+ g_object_unref (headers);
+ g_object_unref (outbox);
+ g_mutex_unlock (priv->sending_lock);
+ return;
+ }
- outbox = tny_send_queue_get_outbox (self);
+ iter = tny_list_create_iterator (headers);
+ while (!tny_iterator_is_done (iter))
+ {
+ TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
- tny_folder_get_headers (outbox, headers, TRUE, err);
-
+ /* Remove or suspend the message */
+ if (cancel_action == TNY_SEND_QUEUE_CANCEL_ACTION_REMOVE)
+ tny_folder_remove_msg (outbox, header, err);
+ else if (cancel_action == TNY_SEND_QUEUE_CANCEL_ACTION_SUSPEND)
+ tny_header_set_flag (header, TNY_HEADER_FLAG_SUSPENDED);
+
if (err != NULL && *err != NULL)
{
+ g_object_unref (header);
+ g_object_unref (iter);
g_object_unref (headers);
g_object_unref (outbox);
g_mutex_unlock (priv->sending_lock);
return;
}
- iter = tny_list_create_iterator (headers);
+ g_object_unref (header);
+ tny_iterator_next (iter);
+ }
+ g_object_unref (iter);
+ g_object_unref (headers);
- while (!tny_iterator_is_done (iter))
- {
- TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
- tny_folder_remove_msg (outbox, header, err);
+ tny_folder_sync (outbox, TRUE, err);
+ g_object_unref (outbox);
- if (err != NULL && *err != NULL)
- {
- g_object_unref (header);
- g_object_unref (iter);
- g_object_unref (headers);
- g_object_unref (outbox);
- g_mutex_unlock (priv->sending_lock);
- return;
- }
-
- g_object_unref (header);
- tny_iterator_next (iter);
- }
- g_object_unref (iter);
- g_object_unref (headers);
-
- tny_folder_sync (outbox, TRUE, err);
- g_object_unref (outbox);
- }
-
g_mutex_unlock (priv->sending_lock);
return;
@@ -1052,7 +1089,6 @@
priv->outbox_cache = NULL;
priv->todo_lock = g_mutex_new ();
priv->sending_lock = g_mutex_new ();
- priv->do_continue = FALSE;
priv->is_running = FALSE;
priv->thread = NULL;
Index: libtinymail/tny-send-queue.c
===================================================================
--- libtinymail/tny-send-queue.c (revision 3282)
+++ libtinymail/tny-send-queue.c (working copy)
@@ -38,7 +38,7 @@
/**
* tny_send_queue_cancel:
* @self: a #TnySendQueue
- * @remove: also remove queued messages
+ * @cancel_action: a #TnySendQueueCancelAction, it could remove messages or just mark them as suspended
* @err: (null-ok): a #GError or NULL
*
* Cancels the current operation
@@ -47,14 +47,14 @@
* audience: application-developer
**/
void
-tny_send_queue_cancel (TnySendQueue *self, gboolean remove, GError **err)
+tny_send_queue_cancel (TnySendQueue *self, TnySendQueueCancelAction cancel_action, GError **err)
{
#ifdef DBC /* require */
g_assert (TNY_IS_SEND_QUEUE (self));
g_assert (TNY_SEND_QUEUE_GET_IFACE (self)->cancel_func != NULL);
#endif
- TNY_SEND_QUEUE_GET_IFACE (self)->cancel_func (self, remove, err);
+ TNY_SEND_QUEUE_GET_IFACE (self)->cancel_func (self, cancel_action, err);
return;
}
Index: libtinymail/tny-send-queue.h
===================================================================
--- libtinymail/tny-send-queue.h (revision 3282)
+++ libtinymail/tny-send-queue.h (working copy)
@@ -48,6 +48,12 @@
TNY_SEND_QUEUE_LAST_SIGNAL
};
+typedef enum
+{
+ TNY_SEND_QUEUE_CANCEL_ACTION_SUSPEND,
+ TNY_SEND_QUEUE_CANCEL_ACTION_REMOVE
+} TnySendQueueCancelAction;
+
extern guint tny_send_queue_signals[TNY_SEND_QUEUE_LAST_SIGNAL];
@@ -64,7 +70,7 @@
void (*add_func) (TnySendQueue *self, TnyMsg *msg, GError **err);
TnyFolder* (*get_sentbox_func) (TnySendQueue *self);
TnyFolder* (*get_outbox_func) (TnySendQueue *self);
- void (*cancel_func) (TnySendQueue *self, gboolean remove, GError **err);
+ void (*cancel_func) (TnySendQueue *self, TnySendQueueCancelAction cancel_action, GError **err);
};
@@ -73,7 +79,7 @@
void tny_send_queue_add (TnySendQueue *self, TnyMsg *msg, GError **err);
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);
+void tny_send_queue_cancel (TnySendQueue *self, TnySendQueueCancelAction cancel_action, GError **err);
G_END_DECLS
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]