Re: Removal of depth



This is a new version of the refactor patch that makes cancelled items's
callback and destroyer happen exactly the same as for non-cancelled
items.

This is a different strategy from the original, but avoids us from
having to do dirty tricks like calculating the mainloop's depth in order
to know whether or not to throw the execution to the mainloop.

Now the execution would happen in the queue's thread, so we always throw
it to the mainloop. And now we can also securely wait for it just like
any other normal non-cancelled operation.

So this patch *does* change the behaviour, unlike the previous version
which didn't change behaviour itself, just merged reusable code
together, so please test this thoroughly! 



On Thu, 2007-11-22 at 10:02 +0100, Sergio Villar Senin wrote:
> Hi Philip,
> 
> I've just seen that you removed the depth. As I said in a recent mail 
> about a hang regarding account cancels, we need it in order not to 
> launch a g_idle while we're currently in the main loop.
> 
> Br
> _______________________________________________
> tinymail-devel-list mailing list
> tinymail-devel-list gnome org
> http://mail.gnome.org/mailman/listinfo/tinymail-devel-list
-- 
Philip Van Hoof, freelance software developer
home: me at pvanhoof dot be 
gnome: pvanhoof at gnome dot org 
http://pvanhoof.be/blog
http://codeminded.be



Index: libtinymail-camel/tny-camel-queue-priv.h
===================================================================
--- libtinymail-camel/tny-camel-queue-priv.h	(revision 2991)
+++ libtinymail-camel/tny-camel-queue-priv.h	(working copy)
@@ -35,13 +35,14 @@
 #define TNY_CAMEL_QUEUE_GET_CLASS(inst)  (G_TYPE_INSTANCE_GET_CLASS ((inst), TNY_TYPE_CAMEL_QUEUE, TnyCamelQueueClass))
 
 typedef struct _TnyCamelQueue TnyCamelQueue;
+typedef struct _TnyCamelQueueable TnyCamelQueueable;
 typedef struct _TnyCamelQueueClass TnyCamelQueueClass;
 
 struct _TnyCamelQueue
 {
 	GObject parent;
 
-	TnyCamelStoreAccount *account;
+	TnyCamelAccount *account;
 	GList *list;
 	GThread *thread;
 	GStaticRecMutex *lock;
@@ -54,6 +55,12 @@
 	GObjectClass parent;
 };
 
+struct _TnyCamelQueueable
+{
+	GCond* condition;
+	gboolean had_callback;
+	GMutex *mutex;
+};
 
 typedef enum {
 	TNY_CAMEL_QUEUE_NORMAL_ITEM = 1<<0,
@@ -66,9 +73,9 @@
 
 GType tny_camel_queue_get_type (void);
 
-TnyCamelQueue* _tny_camel_queue_new (TnyCamelStoreAccount *account);
-void _tny_camel_queue_launch_wflags (TnyCamelQueue *queue, GThreadFunc func, GSourceFunc callback, GDestroyNotify destroyer, gboolean *cancel_field, gpointer data, TnyCamelQueueItemFlags flags, const gchar *name);
-void _tny_camel_queue_launch (TnyCamelQueue *queue, GThreadFunc func, GSourceFunc callback, GDestroyNotify destroyer, gboolean *cancel_field, gpointer data, const gchar *name);
+TnyCamelQueue* _tny_camel_queue_new (TnyCamelAccount *account);
+void _tny_camel_queue_launch_wflags (TnyCamelQueue *queue, GThreadFunc func, GSourceFunc callback, GDestroyNotify destroyer, GSourceFunc cancel_callback, GDestroyNotify cancel_destroyer, gboolean *cancel_field, gpointer data, gsize data_size, TnyCamelQueueItemFlags flags, const gchar *name);
+void _tny_camel_queue_launch (TnyCamelQueue *queue, GThreadFunc func, GSourceFunc callback, GDestroyNotify destroyer, GSourceFunc cancel_callback, GDestroyNotify cancel_destroyer, gboolean *cancel_field, gpointer data, gsize data_size, const gchar *name);
 void _tny_camel_queue_remove_items (TnyCamelQueue *queue, TnyCamelQueueItemFlags flags);
 void _tny_camel_queue_cancel_remove_items (TnyCamelQueue *queue, TnyCamelQueueItemFlags flags);
 
Index: libtinymail-camel/tny-camel-folder.c
===================================================================
--- libtinymail-camel/tny-camel-folder.c	(revision 2991)
+++ libtinymail-camel/tny-camel-folder.c	(working copy)
@@ -89,27 +89,6 @@
 
 
 
-/* When using a #GMainLoop this method will execute a callback using
- * g_idle_add_full.  Note that without a #GMainLoop, the callbacks
- * could happen in a worker thread (depends on who call it) at an
- * unknown moment in time (check your locking in this case). */
-
-static void
-execute_callback (gint depth, 
-		  gint priority,
-		  GSourceFunc idle_func,
-		  gpointer data, 
-		  GDestroyNotify destroy_func)
-{
-	/* if (depth > 0){ */
-		g_idle_add_full (priority, idle_func, data, destroy_func);
-	/* } else {
-		idle_func (data);
-		destroy_func (data);
-	} */
-}
-
-
 typedef struct { 
 	GObject *self;
 	GObject *change; 
@@ -785,8 +764,9 @@
 	return !haderr;
 }
 
-typedef struct 
-{
+typedef struct {
+	TnyCamelQueueable parent;
+
 	TnyFolder *self;
 	TnyFolderCallback callback;
 	TnyStatusCallback status_callback;
@@ -794,15 +774,10 @@
 	TnyMsg *adding_msg;
 	gboolean cancelled;
 	TnyIdleStopper* stopper;
-	guint depth;
 	GError *err;
 	TnySessionCamel *session;
 	TnyFolderChange *change;
 
-	GCond* condition;
-	gboolean had_callback;
-	GMutex *mutex;
-
 } AddMsgFolderInfo;
 
 
@@ -826,13 +801,6 @@
 	tny_idle_stopper_destroy (info->stopper);
 	info->stopper = NULL;
 
-	if (info->condition) {
-		g_mutex_lock (info->mutex);
-		g_cond_broadcast (info->condition);
-		info->had_callback = TRUE;
-		g_mutex_unlock (info->mutex);
-	}
-
 	return;
 }
 
@@ -876,7 +844,7 @@
 		TNY_FOLDER_STATUS, TNY_FOLDER_STATUS_CODE_XFER_MSGS, what, sofar, 
 		oftotal, oinfo->stopper, oinfo->session->priv->ui_lock, oinfo->user_data);
 
-	execute_callback (oinfo->depth, G_PRIORITY_HIGH,
+	g_idle_add_full (G_PRIORITY_HIGH,
 		tny_progress_info_idle_func, info,
 		tny_progress_info_destroy);
 
@@ -918,25 +886,7 @@
 
 	g_static_rec_mutex_unlock (priv->folder_lock);
 
-	info->mutex = g_mutex_new ();
-	info->condition = g_cond_new ();
-	info->had_callback = FALSE;
 
-	execute_callback (info->depth, G_PRIORITY_DEFAULT, 
-		tny_camel_folder_add_msg_async_callback, info, 
-		tny_camel_folder_add_msg_async_destroyer);
-
-	/* Wait on the queue for the mainloop callback to be finished */
-	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 (AddMsgFolderInfo, thr_user_data);
-
 	return NULL;
 }
 
@@ -955,7 +905,7 @@
 
 	if (info->err)
 		g_error_free (info->err);
-	g_slice_free (AddMsgFolderInfo, thr_user_data);
+
 	return;
 }
 
@@ -993,8 +943,6 @@
 	info->callback = callback;
 	info->status_callback = status_callback;
 	info->user_data = user_data;
-	info->depth = g_main_depth ();
-	info->condition = NULL;
 	info->adding_msg = msg;
 	info->err = NULL;
 
@@ -1008,9 +956,12 @@
 
 	_tny_camel_queue_launch (TNY_FOLDER_PRIV_GET_QUEUE (priv), 
 		tny_camel_folder_add_msg_async_thread, 
+		tny_camel_folder_add_msg_async_callback,
+		tny_camel_folder_add_msg_async_destroyer, 
 		tny_camel_folder_add_msg_async_cancelled_callback,
-		tny_camel_folder_add_msg_async_cancelled_destroyer, &info->cancelled,
-		info, __FUNCTION__);
+		tny_camel_folder_add_msg_async_cancelled_destroyer, 
+		&info->cancelled,
+		info, sizeof (AddMsgFolderInfo), __FUNCTION__);
 
 	return;
 }
@@ -1429,20 +1380,17 @@
 
 typedef struct 
 {
+	TnyCamelQueueable parent;
+
 	TnyFolder *self;
 	TnyFolderCallback callback;
 	TnyStatusCallback status_callback;
 	gpointer user_data;
 	gboolean cancelled, expunge;
 	TnyIdleStopper* stopper;
-	guint depth;
 	GError *err;
 	TnySessionCamel *session;
 
-	GCond* condition;
-	gboolean had_callback;
-	GMutex *mutex;
-
 } SyncFolderInfo;
 
 
@@ -1463,13 +1411,6 @@
 	tny_idle_stopper_destroy (info->stopper);
 	info->stopper = NULL;
 
-	if (info->condition) {
-		g_mutex_lock (info->mutex);
-		g_cond_broadcast (info->condition);
-		info->had_callback = TRUE;
-		g_mutex_unlock (info->mutex);
-	}
-
 	return;
 }
 
@@ -1508,7 +1449,7 @@
 		TNY_FOLDER_STATUS, TNY_FOLDER_STATUS_CODE_SYNC, what, sofar, 
 		oftotal, oinfo->stopper, oinfo->session->priv->ui_lock, oinfo->user_data);
 
-	execute_callback (oinfo->depth, G_PRIORITY_HIGH,
+	g_idle_add_full (G_PRIORITY_HIGH,
 		tny_progress_info_idle_func, info,
 		tny_progress_info_destroy);
 
@@ -1527,7 +1468,6 @@
 
 	g_static_rec_mutex_lock (priv->folder_lock);
 
-
 	info->cancelled = FALSE;
 
 	_tny_camel_account_start_camel_operation (TNY_CAMEL_ACCOUNT (priv->account), 
@@ -1564,26 +1504,6 @@
 
 	g_static_rec_mutex_unlock (priv->folder_lock);
 
-	info->mutex = g_mutex_new ();
-	info->condition = g_cond_new ();
-	info->had_callback = FALSE;
-
-	execute_callback (info->depth, G_PRIORITY_DEFAULT, 
-		tny_camel_folder_sync_async_callback, info, 
-		tny_camel_folder_sync_async_destroyer);
-
-
-	/* Wait on the queue for the mainloop callback to be finished */
-	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 (SyncFolderInfo, thr_user_data);
-
 	return NULL;
 }
 
@@ -1599,7 +1519,7 @@
 
 	if (info->err)
 		g_error_free (info->err);
-	g_slice_free (SyncFolderInfo, thr_user_data);
+
 	return;
 }
 
@@ -1628,9 +1548,7 @@
 	info->callback = callback;
 	info->status_callback = status_callback;
 	info->user_data = user_data;
-	info->depth = g_main_depth ();
 	info->expunge = expunge;
-	info->condition = NULL;
 	info->err = NULL;
 
 	info->stopper = tny_idle_stopper_new();
@@ -1641,9 +1559,13 @@
 
 	_tny_camel_queue_launch_wflags (TNY_FOLDER_PRIV_GET_QUEUE (priv), 
 		tny_camel_folder_sync_async_thread, 
+		tny_camel_folder_sync_async_callback,
+		tny_camel_folder_sync_async_destroyer,
 		tny_camel_folder_sync_async_cancelled_callback,
-		tny_camel_folder_sync_async_cancelled_destroyer, &info->cancelled,
-		info, TNY_CAMEL_QUEUE_CANCELLABLE_ITEM|TNY_CAMEL_QUEUE_SYNC_ITEM, 
+		tny_camel_folder_sync_async_cancelled_destroyer, 
+		&info->cancelled,
+		info, sizeof (SyncFolderInfo), 
+		TNY_CAMEL_QUEUE_CANCELLABLE_ITEM|TNY_CAMEL_QUEUE_SYNC_ITEM, 
 		__FUNCTION__);
 }
 
@@ -1656,20 +1578,17 @@
 
 typedef struct 
 {
+	TnyCamelQueueable parent;
+
 	TnyFolder *self;
 	TnyFolderCallback callback;
 	TnyStatusCallback status_callback;
 	gpointer user_data;
 	gboolean cancelled;
 	TnyIdleStopper* stopper;
-	guint depth;
 	GError *err;
 	TnySessionCamel *session;
 
-	GCond* condition;
-	gboolean had_callback;
-	GMutex *mutex;
-
 } RefreshFolderInfo;
 
 
@@ -1693,13 +1612,6 @@
 	tny_idle_stopper_destroy (info->stopper);
 	info->stopper = NULL;
 
-	if (info->condition) {
-		g_mutex_lock (info->mutex);
-		g_cond_broadcast (info->condition);
-		info->had_callback = TRUE;
-		g_mutex_unlock (info->mutex);
-	}
-
 	return;
 }
 
@@ -1739,7 +1651,7 @@
 		oftotal, oinfo->stopper, oinfo->session->priv->ui_lock, 
 		oinfo->user_data);
 
-	execute_callback (oinfo->depth, G_PRIORITY_HIGH,
+	g_idle_add_full (G_PRIORITY_HIGH,
 		tny_progress_info_idle_func, info,
 		tny_progress_info_destroy);
 
@@ -1793,24 +1705,6 @@
 
 	g_static_rec_mutex_unlock (priv->folder_lock);
 
-	info->mutex = g_mutex_new ();
-	info->condition = g_cond_new ();
-	info->had_callback = FALSE;
-
-	execute_callback (info->depth, G_PRIORITY_DEFAULT, 
-		tny_camel_folder_refresh_async_callback, info, 
-		tny_camel_folder_refresh_async_destroyer);
-
-	/* Wait on the queue for the mainloop callback to be finished */
-	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 (RefreshFolderInfo, info);
-
 	return NULL;
 }
 
@@ -1832,7 +1726,6 @@
 	g_object_unref (info->self);
 	if (info->err)
 		g_error_free (info->err);
-	g_slice_free (RefreshFolderInfo, thr_user_data);
 	return;
 }
 
@@ -1876,8 +1769,6 @@
 	info->callback = callback;
 	info->status_callback = status_callback;
 	info->user_data = user_data;
-	info->depth = g_main_depth ();
-	info->condition = NULL;
 	info->err = NULL;
 
 	info->stopper = tny_idle_stopper_new();
@@ -1888,9 +1779,13 @@
 
 	_tny_camel_queue_launch_wflags (TNY_FOLDER_PRIV_GET_QUEUE (priv), 
 		tny_camel_folder_refresh_async_thread, 
+		tny_camel_folder_refresh_async_callback,
+		tny_camel_folder_refresh_async_destroyer, 
 		tny_camel_folder_refresh_async_cancelled_callback,
-		tny_camel_folder_refresh_async_cancelled_destroyer, &info->cancelled,
-		info, TNY_CAMEL_QUEUE_PRIORITY_ITEM|TNY_CAMEL_QUEUE_CANCELLABLE_ITEM, 
+		tny_camel_folder_refresh_async_cancelled_destroyer, 
+		&info->cancelled,
+		info, sizeof (RefreshFolderInfo), 
+		TNY_CAMEL_QUEUE_PRIORITY_ITEM|TNY_CAMEL_QUEUE_CANCELLABLE_ITEM, 
 		__FUNCTION__);
 
 	return;
@@ -1993,20 +1888,17 @@
 
 typedef struct 
 {
+	TnyCamelQueueable parent;
+
 	GError *err;
 	TnyFolder *self;
 	TnyList *headers;
 	gboolean refresh;
 	TnyGetHeadersCallback callback;
 	gpointer user_data;
-	guint depth; 
 	TnySessionCamel *session;
 	gboolean cancelled;
 
-	GCond* condition;
-	gboolean had_callback;
-	GMutex *mutex;
-
 } GetHeadersInfo;
 
 
@@ -2022,13 +1914,6 @@
 	if (info->err)
 		g_error_free (info->err);
 
-	if (info->condition) {
-		g_mutex_lock (info->mutex);
-		g_cond_broadcast (info->condition);
-		info->had_callback = TRUE;
-		g_mutex_unlock (info->mutex);
-	}
-
 	return;
 }
 
@@ -2057,25 +1942,6 @@
 			info->cancelled = TRUE;
 	}
 
-	info->mutex = g_mutex_new ();
-	info->condition = g_cond_new ();
-	info->had_callback = FALSE;
-
-	execute_callback (info->depth, G_PRIORITY_DEFAULT, 
-		tny_camel_folder_get_headers_async_callback, info, 
-		tny_camel_folder_get_headers_async_destroyer);
-
-	/* Wait on the queue for the mainloop callback to be finished */
-	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 (GetHeadersInfo, info);
-
 	return NULL;
 }
 
@@ -2087,7 +1953,6 @@
 		g_error_free (info->err);
 	g_object_unref (info->self);
 	g_object_unref (info->headers);
-	g_slice_free (GetHeadersInfo, info);
 	return;
 }
 
@@ -2125,8 +1990,6 @@
 	info->refresh = refresh;
 	info->callback = callback;
 	info->user_data = user_data;
-	info->depth = g_main_depth ();
-	info->condition = NULL;
 	info->err = NULL;
 
 	/* thread reference */
@@ -2138,10 +2001,14 @@
 
 	_tny_camel_queue_launch_wflags (TNY_FOLDER_PRIV_GET_QUEUE (priv), 
 		tny_camel_folder_get_headers_async_thread, 
+		tny_camel_folder_get_headers_async_callback,
+		tny_camel_folder_get_headers_async_destroyer, 
 		tny_camel_folder_get_headers_async_cancelled_callback,
-		tny_camel_folder_get_headers_async_cancelled_destroyer, &info->cancelled,
-		info, TNY_CAMEL_QUEUE_PRIORITY_ITEM|TNY_CAMEL_QUEUE_CANCELLABLE_ITEM|
-			TNY_CAMEL_QUEUE_GET_HEADERS_ITEM, __FUNCTION__);
+		tny_camel_folder_get_headers_async_cancelled_destroyer, 
+		&info->cancelled,
+		info, sizeof (GetHeadersInfo),
+		TNY_CAMEL_QUEUE_PRIORITY_ITEM|TNY_CAMEL_QUEUE_CANCELLABLE_ITEM|TNY_CAMEL_QUEUE_GET_HEADERS_ITEM, 
+		__FUNCTION__);
 
 	return;
 }
@@ -2223,22 +2090,19 @@
 
 typedef struct 
 {
+	TnyCamelQueueable parent;
+
 	TnyFolder *self;
 	TnyMsg *msg;
 	TnyHeader *header;
 	GError *err;
 	gpointer user_data;
-	guint depth;
 	TnyGetMsgCallback callback;
 	TnyStatusCallback status_callback;
 	TnySessionCamel *session;
 	TnyIdleStopper *stopper;
 	gboolean cancelled;
 
-	GCond* condition;
-	gboolean had_callback;
-	GMutex *mutex;
-
 } GetMsgInfo;
 
 
@@ -2258,13 +2122,6 @@
 	tny_idle_stopper_destroy (info->stopper);
 	info->stopper = NULL;
 
-	if (info->condition) {
-		g_mutex_lock (info->mutex);
-		g_cond_broadcast (info->condition);
-		info->had_callback = TRUE;
-		g_mutex_unlock (info->mutex);
-	}
-
 	return;
 }
 
@@ -2308,7 +2165,7 @@
 		TNY_FOLDER_STATUS, TNY_FOLDER_STATUS_CODE_GET_MSG, what, sofar, 
 		oftotal, oinfo->stopper, oinfo->session->priv->ui_lock, oinfo->user_data);
 
-	execute_callback (oinfo->depth, G_PRIORITY_HIGH, 
+	g_idle_add_full (G_PRIORITY_HIGH, 
 			  tny_progress_info_idle_func, info, 
 			  tny_progress_info_destroy);
 
@@ -2366,25 +2223,6 @@
 	/* thread reference header */
 	g_object_unref (info->header);
 
-	info->mutex = g_mutex_new ();
-	info->condition = g_cond_new ();
-	info->had_callback = FALSE;
-
-	execute_callback (info->depth, G_PRIORITY_DEFAULT, 
-		tny_camel_folder_get_msg_async_callback, info, 
-		tny_camel_folder_get_msg_async_destroyer);
-
-	/* Wait on the queue for the mainloop callback to be finished */
-	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 (GetMsgInfo, info);
-
 	return NULL;
 
 }
@@ -2402,7 +2240,6 @@
 	if (info->err)
 		g_error_free (info->err);
 
-	g_slice_free (GetMsgInfo, info);
 	return;
 }
 
@@ -2441,8 +2278,6 @@
 	info->callback = callback;
 	info->status_callback = status_callback;
 	info->user_data = user_data;
-	info->depth = g_main_depth ();
-	info->condition = NULL;
 	info->err = NULL;
 
 	info->stopper = tny_idle_stopper_new();
@@ -2456,9 +2291,13 @@
 
 	_tny_camel_queue_launch (TNY_FOLDER_PRIV_GET_MSG_QUEUE (priv), 
 		tny_camel_folder_get_msg_async_thread, 
+		tny_camel_folder_get_msg_async_callback,
+		tny_camel_folder_get_msg_async_destroyer, 
 		tny_camel_folder_get_msg_async_cancelled_callback,
-		tny_camel_folder_get_msg_async_cancelled_destroyer, &info->cancelled,
-		info, __FUNCTION__);
+		tny_camel_folder_get_msg_async_cancelled_destroyer, 
+		&info->cancelled,
+		info, sizeof (GetMsgInfo), 
+		__FUNCTION__);
 
 	return;
 }
@@ -3264,14 +3103,14 @@
 
 typedef struct 
 {
+	TnyCamelQueueable parent;
+
 	TnyFolder *self;
 	TnyFolderStore *into;
 	gchar *new_name;
 	gboolean delete_originals;
 	GError *err;
-
 	gpointer user_data;
-	guint depth;
 	TnyCopyFolderCallback callback;
 	TnyStatusCallback status_callback;
 	TnyFolder *new_folder;
@@ -3280,10 +3119,6 @@
 	gboolean cancelled;
 	GList *rems, *adds;
 
-	GCond* condition;
-	gboolean had_callback;
-	GMutex *mutex;
-
 } CopyFolderInfo;
 
 
@@ -3308,13 +3143,6 @@
 	if (info->new_name)
 		g_free (info->new_name);
 
-	if (info->condition) {
-		g_mutex_lock (info->mutex);
-		g_cond_broadcast (info->condition);
-		info->had_callback = TRUE;
-		g_mutex_unlock (info->mutex);
-	}
-
 	return;
 }
 
@@ -3360,7 +3188,7 @@
 		TNY_FOLDER_STATUS, TNY_FOLDER_STATUS_CODE_COPY_FOLDER, what, sofar, 
 		oftotal, oinfo->stopper, oinfo->session->priv->ui_lock, oinfo->user_data);
 
-	execute_callback (oinfo->depth, G_PRIORITY_HIGH,
+	g_idle_add_full (G_PRIORITY_HIGH,
 			  tny_progress_info_idle_func, info, 
 			  tny_progress_info_destroy);
 
@@ -3422,25 +3250,6 @@
 
 	g_static_rec_mutex_unlock (priv->folder_lock);
 
-	info->mutex = g_mutex_new ();
-	info->condition = g_cond_new ();
-	info->had_callback = FALSE;
-
-	execute_callback (info->depth, G_PRIORITY_DEFAULT, 
-		tny_camel_folder_copy_async_callback, info, 
-		tny_camel_folder_copy_async_destroyer);
-
-	/* Wait on the queue for the mainloop callback to be finished */
-	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 (CopyFolderInfo, info);
-
 	return NULL;
 }
 
@@ -3455,7 +3264,7 @@
 		g_error_free (info->err);
 	g_object_unref (info->self);
 	g_object_unref (info->into);
-	g_slice_free (CopyFolderInfo, info);
+
 	return;
 }
 
@@ -3494,11 +3303,9 @@
 	info->callback = callback;
 	info->status_callback = status_callback;
 	info->user_data = user_data;
-	info->depth = g_main_depth ();
 	info->err = NULL;
 	info->delete_originals = del;
 	info->new_name = g_strdup (new_name);
-	info->condition = NULL;
 	info->err = NULL;
 
 	info->stopper = tny_idle_stopper_new();
@@ -3509,9 +3316,13 @@
 
 	_tny_camel_queue_launch (TNY_FOLDER_PRIV_GET_QUEUE (priv), 
 		tny_camel_folder_copy_async_thread, 
+		tny_camel_folder_copy_async_callback,
+		tny_camel_folder_copy_async_destroyer, 
 		tny_camel_folder_copy_async_cancelled_callback,
-		tny_camel_folder_copy_async_cancelled_destroyer, &info->cancelled,
-		info, __FUNCTION__);
+		tny_camel_folder_copy_async_cancelled_destroyer, 
+		&info->cancelled,
+		info, sizeof (CopyFolderInfo),
+		__FUNCTION__);
 
 	return;
 }
@@ -3519,13 +3330,14 @@
 
 typedef struct 
 {
+	TnyCamelQueueable parent;
+
 	GError *err;
 	TnyFolder *self;
 	TnyTransferMsgsCallback callback;
 	TnyStatusCallback status_callback;
 	TnyIdleStopper *stopper;
 	gpointer user_data;
-	guint depth;
 	TnyList *header_list;
 	TnyList *new_header_list;
 	TnyFolder *folder_dst;
@@ -3537,10 +3349,6 @@
 	gint to_unread;
 	gboolean cancelled;
 
-	GCond* condition;
-	gboolean had_callback;
-	GMutex *mutex;
-
 } TransferMsgsInfo;
 
 
@@ -3606,13 +3414,6 @@
 	tny_idle_stopper_destroy (info->stopper);
 	info->stopper = NULL;
 
-	if (info->condition) {
-		g_mutex_lock (info->mutex);
-		g_cond_broadcast (info->condition);
-		info->had_callback = TRUE;
-		g_mutex_unlock (info->mutex);
-	}
-
 	return;
 }
 
@@ -3970,7 +3771,7 @@
 		TNY_FOLDER_STATUS, TNY_FOLDER_STATUS_CODE_XFER_MSGS, what, sofar, 
 		oftotal, oinfo->stopper, oinfo->session->priv->ui_lock, oinfo->user_data);
 
-	execute_callback (oinfo->depth, G_PRIORITY_HIGH,
+	g_idle_add_full (G_PRIORITY_HIGH,
 			  tny_progress_info_idle_func, info, 
 			  tny_progress_info_destroy);
 
@@ -4027,25 +3828,6 @@
 			priv_dst->folder_name?priv_dst->folder_name:"(null)");
 	}
 
-	info->mutex = g_mutex_new ();
-	info->condition = g_cond_new ();
-	info->had_callback = FALSE;
-
-	execute_callback (info->depth, G_PRIORITY_DEFAULT, 
-		tny_camel_folder_transfer_msgs_async_callback, info, 
-		tny_camel_folder_transfer_msgs_async_destroyer);
-
-	/* Wait on the queue for the mainloop callback to be finished */
-	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 (TransferMsgsInfo, info);
-
 	return NULL;
 }
 
@@ -4067,7 +3849,7 @@
 
 	if (info->err)
 		g_error_free (info->err);
-	g_slice_free (TransferMsgsInfo, info);
+
 	return;
 }
 
@@ -4111,8 +3893,6 @@
 	info->status_callback = status_callback;
 	info->user_data = user_data;
 	info->delete_originals = delete_originals;
-	info->depth = g_main_depth ();
-	info->condition = NULL;
 	info->err = NULL;
 
 	info->stopper = tny_idle_stopper_new();
@@ -4126,9 +3906,13 @@
 
 	_tny_camel_queue_launch (TNY_FOLDER_PRIV_GET_QUEUE (priv),
 		tny_camel_folder_transfer_msgs_async_thread, 
+		tny_camel_folder_transfer_msgs_async_callback,
+		tny_camel_folder_transfer_msgs_async_destroyer, 
 		tny_camel_folder_transfer_msgs_async_cancelled_callback,
-		tny_camel_folder_transfer_msgs_async_cancelled_destroyer, &info->cancelled,
-		info, __FUNCTION__);
+		tny_camel_folder_transfer_msgs_async_cancelled_destroyer, 
+		&info->cancelled,
+		info, sizeof (TransferMsgsInfo),
+		__FUNCTION__);
 
 	return;
 }
@@ -4835,20 +4619,17 @@
 
 typedef struct 
 {
+	TnyCamelQueueable parent;
+
 	GError *err;
 	TnyFolderStore *self;
 	TnyList *list;
 	TnyGetFoldersCallback callback;
 	TnyFolderStoreQuery *query;
 	gpointer user_data;
-	guint depth; 
 	TnySessionCamel *session;
 	gboolean cancelled;
 
-	GCond* condition;
-	gboolean had_callback;
-	GMutex *mutex;
-
 } GetFoldersInfo;
 
 
@@ -4868,13 +4649,6 @@
 
 	_tny_session_stop_operation (info->session);
 
-	if (info->condition) {
-		g_mutex_lock (info->mutex);
-		g_cond_broadcast (info->condition);
-		info->had_callback = TRUE;
-		g_mutex_unlock (info->mutex);
-	}
-
 	return;
 }
 
@@ -4908,25 +4682,6 @@
 	if (info->query)
 		g_object_unref (G_OBJECT (info->query));
 
-	info->mutex = g_mutex_new ();
-	info->condition = g_cond_new ();
-	info->had_callback = FALSE;
-
-	execute_callback (info->depth, G_PRIORITY_DEFAULT, 
-		tny_camel_folder_get_folders_async_callback, info, 
-		tny_camel_folder_get_folders_async_destroyer);
-
-	/* Wait on the queue for the mainloop callback to be finished */
-	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 (GetFoldersInfo, info);
-
 	return NULL;
 }
 
@@ -4945,7 +4700,7 @@
 		g_error_free (info->err);
 	if (info->query)
 		g_object_unref (info->query);
-	g_slice_free (GetFoldersInfo, info);
+
 	return;
 }
 
@@ -4981,8 +4736,6 @@
 	info->callback = callback;
 	info->user_data = user_data;
 	info->query = query;
-	info->depth = g_main_depth ();
-	info->condition = NULL;
 	info->err = NULL;
 
 	/* thread reference */
@@ -4994,9 +4747,13 @@
 
 	_tny_camel_queue_launch (TNY_FOLDER_PRIV_GET_QUEUE (priv), 
 		tny_camel_folder_get_folders_async_thread, 
+		tny_camel_folder_get_folders_async_callback,
+		tny_camel_folder_get_folders_async_destroyer, 
 		tny_camel_folder_get_folders_async_cancelled_callback,
 		tny_camel_folder_get_folders_async_cancelled_destroyer, 
-		&info->cancelled, info, __FUNCTION__);
+		&info->cancelled, 
+		info, sizeof (GetFoldersInfo),
+		__FUNCTION__);
 
 	return;
 }
@@ -5053,9 +4810,12 @@
 }
 
 typedef struct {
+	TnyCamelQueueable parent;
+
 	TnyFolder *self;
 	gint unread;
 	gint total;
+	gboolean do_status;
 } PokeStatusInfo;
 
 static gboolean
@@ -5063,26 +4823,27 @@
 {
 	PokeStatusInfo *info = (PokeStatusInfo *) data;
 	TnyFolder *self = (TnyFolder *) info->self;
-	TnyFolderChange *change = tny_folder_change_new (self);
+	TnyFolderChange *change = NULL;
 	TnyCamelFolderPriv *priv = TNY_CAMEL_FOLDER_GET_PRIVATE (self);
-	gboolean do_something = FALSE;
 
 	if (info->total != -1) {
-		do_something = TRUE;
 		priv->cached_length = (guint) info->total;
+		if (!change)
+			change = tny_folder_change_new (self);
 		tny_folder_change_set_new_all_count (change, priv->cached_length);
 	}
 	if (info->unread != -1) {
-		do_something = TRUE;
 		priv->unread_length = (guint) info->unread;
+		if (!change)
+			change = tny_folder_change_new (self);
 		tny_folder_change_set_new_unread_count (change, priv->unread_length);
 	}
 
-	if (do_something)
+	if (change) {
 		notify_folder_observers_about (self, change);
+		g_object_unref (change);
+	}
 
-	g_object_unref (change);
-
 	return FALSE;
 }
 
@@ -5090,8 +4851,8 @@
 tny_camel_folder_poke_status_destroyer (gpointer data)
 {
 	PokeStatusInfo *info = (PokeStatusInfo *) data;
+	/* Thread reference */
 	g_object_unref (info->self);
-	g_slice_free (PokeStatusInfo, info);
 	return;
 }
 
@@ -5099,8 +4860,8 @@
 static gpointer
 tny_camel_folder_poke_status_thread (gpointer user_data)
 {
-	PokeStatusInfo *info = NULL;
-	TnyFolder *folder = (TnyFolder *) user_data;
+	PokeStatusInfo *info = (PokeStatusInfo *) user_data;
+	TnyFolder *folder = info->self;
 	TnyCamelFolderPriv *priv = NULL;
 	CamelStore *store = NULL;
 	int newlen = -1, newurlen = -1, uidnext = -1;
@@ -5108,13 +4869,14 @@
 	priv = TNY_CAMEL_FOLDER_GET_PRIVATE (folder);
 	store = priv->store;
 
-	camel_store_get_folder_status (store, priv->folder_name, 
-		&newurlen, &newlen, &uidnext);
+	if (info->do_status) {
+		camel_store_get_folder_status (store, priv->folder_name, 
+			&newurlen, &newlen, &uidnext);
+	}
 
 	if (newurlen == -1 || newlen == -1)
 	{
 		if (priv->iter) {
-			info = g_slice_new (PokeStatusInfo);
 			info->unread = priv->iter->unread;
 			info->total = priv->iter->total;
 		} else {
@@ -5122,28 +4884,10 @@
 			info->total = priv->cached_length;
 		}
 	} else {
-		info = g_slice_new (PokeStatusInfo);
 		info->unread = newurlen;
 		info->total = newlen;
 	}
 
-	if (info && folder)
-	{
-		info->self = TNY_FOLDER (g_object_ref (folder));
-
-
-		g_idle_add_full (G_PRIORITY_HIGH, 
-			tny_camel_folder_poke_status_callback, 
-			info, tny_camel_folder_poke_status_destroyer);
-
-	} else if (info)
-		g_slice_free (PokeStatusInfo, info);
-
-	/* Thread reference */
-	if (folder)
-		g_object_unref (folder);
-
-
 	return NULL;
 }
 
@@ -5153,11 +4897,14 @@
 {
 	TnyCamelFolderPriv *priv = TNY_CAMEL_FOLDER_GET_PRIVATE (self);
 	CamelStore *store = priv->store;
-	PokeStatusInfo *info = NULL;
+	PokeStatusInfo *info = g_slice_new (PokeStatusInfo);
 
+	info->do_status = FALSE;
+	/* Thread reference */
+	info->self = TNY_FOLDER (g_object_ref (self));
+
 	if (priv->folder)
 	{
-		info = g_slice_new (PokeStatusInfo);
 		info->unread = camel_folder_get_unread_message_count (priv->folder);
 		info->total = camel_folder_get_message_count (priv->folder);
 
@@ -5166,33 +4913,25 @@
 		if (store && CAMEL_IS_DISCO_STORE (store)  && priv->folder_name 
 			&& camel_disco_store_status (CAMEL_DISCO_STORE (store)) == CAMEL_DISCO_STORE_ONLINE)
 		{
-			/* Thread reference */
-			g_object_ref (self);
-			_tny_camel_queue_launch (TNY_FOLDER_PRIV_GET_QUEUE (priv), 
-				tny_camel_folder_poke_status_thread, 
-				/* If this one becomes cancellable, there must be
-				 * cancel handlers here to clean up the ref on
-				 * self !! */
-				NULL, NULL, NULL, self, __FUNCTION__);
-
+			info->do_status = TRUE;
 		} else {
 			if (priv->iter) {
-				info = g_slice_new (PokeStatusInfo);
 				info->unread = priv->iter->unread;
 				info->total = priv->iter->total;
 			}
 		}
 	}
 
+	_tny_camel_queue_launch (TNY_FOLDER_PRIV_GET_QUEUE (priv), 
+		tny_camel_folder_poke_status_thread, 
+		tny_camel_folder_poke_status_callback, 
+		tny_camel_folder_poke_status_destroyer, 
+		tny_camel_folder_poke_status_callback, 
+		tny_camel_folder_poke_status_destroyer, 
+		NULL, 
+		info, sizeof (PokeStatusInfo),
+		__FUNCTION__);
 
-	if (info) 
-	{
-		info->self = TNY_FOLDER (g_object_ref (self));
-		execute_callback (10, G_PRIORITY_HIGH, 
-			tny_camel_folder_poke_status_callback, info, 
-			tny_camel_folder_poke_status_destroyer);
-	}
-
 	return;
 }
 
Index: libtinymail-camel/tny-camel-account-priv.h
===================================================================
--- libtinymail-camel/tny-camel-account-priv.h	(revision 2991)
+++ libtinymail-camel/tny-camel-account-priv.h	(working copy)
@@ -30,6 +30,8 @@
 
 #include <camel/camel-operation.h>
 
+#include "tny-camel-queue-priv.h"
+
 typedef struct _TnyCamelAccountPriv TnyCamelAccountPriv;
 typedef struct _RefreshStatusInfo RefreshStatusInfo;
 
@@ -72,6 +74,7 @@
 	TnyConnectionStatus status;
 	gboolean is_connecting, is_ready;
 	gchar *delete_this;
+	TnyCamelQueue *queue;
 };
 
 const CamelService* _tny_camel_account_get_service (TnyCamelAccount *self);
Index: libtinymail-camel/tny-camel-queue.c
===================================================================
--- libtinymail-camel/tny-camel-queue.c	(revision 2991)
+++ libtinymail-camel/tny-camel-queue.c	(working copy)
@@ -63,14 +63,14 @@
 
 /**
  * _tny_camel_queue_new
- * @account: the queue
+ * @account: the account
  *
  * Internal, non-public API documentation of Tinymail
  *
  * Make a new queue for @account.
  **/
 TnyCamelQueue*
-_tny_camel_queue_new (TnyCamelStoreAccount *account)
+_tny_camel_queue_new (TnyCamelAccount *account)
 {
 	TnyCamelQueue *self = g_object_new (TNY_TYPE_CAMEL_QUEUE, NULL);
 
@@ -84,13 +84,79 @@
 	GThreadFunc func;
 	GSourceFunc callback;
 	GDestroyNotify destroyer;
+	GSourceFunc cancel_callback;
+	GDestroyNotify cancel_destroyer;
 	gpointer data;
+	gsize data_size;
 	TnyCamelQueueItemFlags flags;
 	const gchar *name;
 	gboolean *cancel_field;
+	gboolean deleted;
 } QueueItem;
 
+static gboolean
+perform_callback (gpointer user_data)
+{
+	QueueItem *item = (QueueItem *) user_data;
+	gboolean retval = FALSE;
 
+	if (item->callback)
+		retval = item->callback (item->data);
+
+	return retval;
+}
+
+static void
+perform_destroyer (gpointer user_data)
+{
+	QueueItem *item = (QueueItem *) user_data;
+	TnyCamelQueueable *info = (TnyCamelQueueable * ) item->data;
+
+	if (item->destroyer)
+		item->destroyer (item->data);
+
+	if (info->condition) {
+		g_mutex_lock (info->mutex);
+		g_cond_broadcast (info->condition);
+		info->had_callback = TRUE;
+		g_mutex_unlock (info->mutex);
+	}
+
+	return;
+}
+
+
+static gboolean
+perform_cancel_callback (gpointer user_data)
+{
+	QueueItem *item = (QueueItem *) user_data;
+	gboolean retval = FALSE;
+
+	if (item->cancel_callback)
+		retval = item->cancel_callback (item->data);
+
+	return retval;
+}
+
+static void
+perform_cancel_destroyer (gpointer user_data)
+{
+	QueueItem *item = (QueueItem *) user_data;
+	TnyCamelQueueable *info = (TnyCamelQueueable * ) item->data;
+
+	if (item->cancel_destroyer)
+		item->cancel_destroyer (item->data);
+
+	if (info->condition) {
+		g_mutex_lock (info->mutex);
+		g_cond_broadcast (info->condition);
+		info->had_callback = TRUE;
+		g_mutex_unlock (info->mutex);
+	}
+
+	return;
+}
+
 static gpointer 
 thread_main_func (gpointer user_data)
 {
@@ -100,6 +166,7 @@
 	{
 		GList *first = NULL;
 		QueueItem *item = NULL;
+		gboolean deleted = FALSE;
 
 		g_static_rec_mutex_lock (queue->lock);
 
@@ -112,15 +179,49 @@
 		first = g_list_first (queue->list);
 		if (first) {
 			item = first->data;
+			if (item)
+				deleted = item->deleted;
 			queue->current = item;
 		} else
 			queue->stopped = TRUE;
 		g_static_rec_mutex_unlock (queue->lock);
 
 		if (item) {
-			tny_debug ("TnyCamelQueue: %s is on the stage, now performing\n", item->name);
-			item->func (item->data);
-			tny_debug ("TnyCamelQueue: %s is off the stage, done performing\n", item->name);
+			TnyCamelQueueable *info = (TnyCamelQueueable * ) item->data;
+
+			if (!deleted) {
+				tny_debug ("TnyCamelQueue: %s is on the stage, now performing\n", item->name);
+				item->func (item->data);
+			}
+
+			info->mutex = g_mutex_new ();
+			info->condition = g_cond_new ();
+			info->had_callback = FALSE;
+
+			if (deleted) {
+
+				g_idle_add_full (G_PRIORITY_DEFAULT, 
+					perform_cancel_callback, item, 
+					perform_cancel_destroyer);
+			} else {
+
+				g_idle_add_full (G_PRIORITY_DEFAULT, 
+					perform_callback, item, 
+					perform_destroyer);
+			}
+			/* Wait on the queue for the mainloop callback to be finished */
+			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_free1 (item->data_size, item->data);
+
+			if (!deleted)
+				tny_debug ("TnyCamelQueue: %s is off the stage, done performing\n", item->name);
 		}
 
 		g_static_rec_mutex_lock (queue->lock);
@@ -147,6 +248,7 @@
 	return NULL;
 }
 
+
 /**
  * _tny_camel_queue_remove_items
  * @queue: the queue
@@ -165,10 +267,10 @@
 
 	g_static_rec_mutex_lock (queue->lock);
 	copy = queue->list;
-
 	while (copy) 
 	{
 		QueueItem *item = copy->data;
+
 		if (queue->current != item)
 		{
 			if (item && (item->flags & flags)) 
@@ -178,20 +280,11 @@
 				if (item->cancel_field)
 					*item->cancel_field = TRUE;
 
-				if (item->callback)
-					g_idle_add_full (G_PRIORITY_HIGH, item->callback, 
-						item->data, item->destroyer);
-
-				rem = g_list_prepend (rem, copy);
-				g_slice_free (QueueItem, item);
+				item->deleted = TRUE;
 			}
 		}
 		copy = g_list_next (copy);
 	}
-	while (rem) {
-		queue->list = g_list_delete_link (queue->list, rem->data);
-		rem = g_list_next (rem);
-	}
 	g_static_rec_mutex_unlock (queue->lock);
 }
 
@@ -243,10 +336,13 @@
  * _tny_camel_queue_launch_wflags
  * @queue: the queue
  * @func: the work function
- * @callback: for in case of a cancellation, can be NULL
- * @destroyer: for in case of a cancellation, can be NULL
+ * @callback: the callback for when finished
+ * @destroyer: the destroyer for the @callback
+ * @cancel_callback: for in case of a cancellation, can be NULL
+ * @cancel_destroyer: for in case of a cancellation, can be NULL
  * @cancel_field: a byref location of a gboolean that will be set to TRUE in case of a cancellation
  * @data: data that will be passed to @func, @callback and @destroyer
+ * @data_size: size of the @data pointer
  * @flags: flags of this item
  * @name: a name for this item for debugging (__FUNCTION__ will do)
  *
@@ -258,7 +354,7 @@
  * A cancelled item's @cancel_field will also be set to TRUE.
  **/
 void 
-_tny_camel_queue_launch_wflags (TnyCamelQueue *queue, GThreadFunc func, GSourceFunc callback, GDestroyNotify destroyer, gboolean *cancel_field, gpointer data, TnyCamelQueueItemFlags flags, const gchar *name)
+_tny_camel_queue_launch_wflags (TnyCamelQueue *queue, GThreadFunc func, GSourceFunc callback, GDestroyNotify destroyer, GSourceFunc cancel_callback, GDestroyNotify cancel_destroyer, gboolean *cancel_field, gpointer data, gsize data_size, TnyCamelQueueItemFlags flags, const gchar *name)
 {
 	QueueItem *item = g_slice_new (QueueItem);
 
@@ -268,10 +364,14 @@
 	item->func = func;
 	item->callback = callback;
 	item->destroyer = destroyer;
+	item->cancel_callback = cancel_callback;
+	item->cancel_destroyer = cancel_destroyer;
 	item->data = data;
+	item->data_size = data_size;
 	item->flags = flags;
 	item->name = name;
 	item->cancel_field = cancel_field;
+	item->deleted = FALSE;
 
 	g_static_rec_mutex_lock (queue->lock);
 
@@ -315,10 +415,13 @@
  * _tny_camel_queue_launch
  * @queue: the queue
  * @func: the work function
- * @callback: for in case of a cancellation, can be NULL
- * @destroyer: for in case of a cancellation, can be NULL
+ * @callback: the callback for when finished
+ * @destroyer: the destroyer for the @callback
+ * @cancel_callback: for in case of a cancellation, can be NULL
+ * @cancel_destroyer: for in case of a cancellation, can be NULL
  * @cancel_field: a byref location of a gboolean that will be set to TRUE in case of a cancellation
  * @data: data that will be passed to @func, @callback and @destroyer
+ * @data_size: size of the @data pointer
  * @name: a name for this item for debugging (__FUNCTION__ will do)
  *
  * Internal, non-public API documentation of Tinymail
@@ -331,10 +434,10 @@
  * The flags of the queue item will be TNY_CAMEL_QUEUE_NORMAL_ITEM.
  **/
 void 
-_tny_camel_queue_launch (TnyCamelQueue *queue, GThreadFunc func, GSourceFunc callback, GDestroyNotify destroyer, gboolean *cancel_field, gpointer data, const gchar *name)
+_tny_camel_queue_launch (TnyCamelQueue *queue, GThreadFunc func, GSourceFunc callback, GDestroyNotify destroyer, GSourceFunc cancel_callback, GDestroyNotify cancel_destroyer, gboolean *cancel_field, gpointer data, gsize data_size, const gchar *name)
 {
-	_tny_camel_queue_launch_wflags (queue, func, callback, destroyer, 
-		cancel_field, data, TNY_CAMEL_QUEUE_NORMAL_ITEM, name);
+	_tny_camel_queue_launch_wflags (queue, func, callback, destroyer, cancel_callback, cancel_destroyer,
+		cancel_field, data, data_size, TNY_CAMEL_QUEUE_NORMAL_ITEM, name);
 	return;
 }
 
Index: libtinymail-camel/tny-camel-store-account.c
===================================================================
--- libtinymail-camel/tny-camel-store-account.c	(revision 2991)
+++ libtinymail-camel/tny-camel-store-account.c	(working copy)
@@ -640,9 +640,9 @@
 	TnyCamelStoreAccountPriv *priv = TNY_CAMEL_STORE_ACCOUNT_GET_PRIVATE (self);
 	TnyCamelAccountPriv *apriv = TNY_CAMEL_ACCOUNT_GET_PRIVATE (self);
 
+	priv->queue = apriv->queue;
 	priv->deleted = FALSE;
-	priv->queue = _tny_camel_queue_new (self);
-	priv->msg_queue = _tny_camel_queue_new (self);
+	priv->msg_queue = _tny_camel_queue_new (TNY_CAMEL_ACCOUNT (self));
 	apriv->type = CAMEL_PROVIDER_STORE;
 	apriv->account_type = TNY_ACCOUNT_TYPE_STORE;
 	priv->managed_folders = NULL;
@@ -715,7 +715,6 @@
 	g_free (priv->obs_lock);
 	priv->obs_lock = NULL;
 
-	g_object_unref (priv->queue);
 	g_object_unref (priv->msg_queue);
 
 	(*parent_class->finalize) (object);
@@ -1222,21 +1221,19 @@
 }
 
 
-typedef struct {
+typedef struct 
+{
+	TnyCamelQueueable parent;
+
 	GError *err;
 	TnyFolderStore *self;
 	TnyList *list;
 	TnyGetFoldersCallback callback;
 	TnyFolderStoreQuery *query;
 	gpointer user_data;
-	guint depth; 
 	TnySessionCamel *session;
 	gboolean cancelled;
 
-	GCond* condition;
-	gboolean had_callback;
-	GMutex *mutex;
-
 } GetFoldersInfo;
 
 
@@ -1252,11 +1249,6 @@
 	if (info->err)
 		g_error_free (info->err);
 
-	g_mutex_lock (info->mutex);
-	g_cond_broadcast (info->condition);
-	info->had_callback = TRUE;
-	g_mutex_unlock (info->mutex);
-
 	return;
 }
 
@@ -1273,28 +1265,6 @@
 }
 
 
-/**
- * When using a #GMainLoop this method will execute a callback using
- * g_idle_add_full.  Note that without a #GMainLoop, the callbacks
- * could happen in a worker thread (depends on who call it) at an
- * unknown moment in time (check your locking in this case).
- */
-static void
-execute_callback (gint depth, 
-		  gint priority,
-		  GSourceFunc idle_func,
-		  gpointer data, 
-		  GDestroyNotify destroy_func)
-{
-	/* if (depth > 0){ */
-		g_idle_add_full (priority, idle_func, data, destroy_func);
-	/* } else {
-		idle_func (data);
-		destroy_func (data);
-	} */
-}
-
-
 static gpointer 
 tny_camel_store_account_get_folders_async_thread (gpointer thr_user_data)
 {
@@ -1312,25 +1282,6 @@
 	if (info->query)
 		g_object_unref (G_OBJECT (info->query));
 
-	info->mutex = g_mutex_new ();
-	info->condition = g_cond_new ();
-	info->had_callback = FALSE;
-
-	execute_callback (info->depth, G_PRIORITY_DEFAULT, 
-		tny_camel_store_account_get_folders_async_callback, info, 
-		tny_camel_store_account_get_folders_async_destroyer);
-
-	/* Wait on the queue for the mainloop callback to be finished */
-	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 (GetFoldersInfo, info);
-
 	return NULL;
 }
 
@@ -1345,7 +1296,6 @@
 	g_object_unref (info->list);
 	if (info->err)
 		g_error_free (info->err);
-	g_slice_free (GetFoldersInfo, info);
 	return;
 }
 
@@ -1385,7 +1335,6 @@
 	info->callback = callback;
 	info->user_data = user_data;
 	info->query = query;
-	info->depth = g_main_depth ();
 
 	/* thread reference */
 	g_object_ref (info->self);
@@ -1395,10 +1344,13 @@
 
 	_tny_camel_queue_launch_wflags (priv->queue, 
 		tny_camel_store_account_get_folders_async_thread,
+		tny_camel_store_account_get_folders_async_callback,
+		tny_camel_store_account_get_folders_async_destroyer, 
 		tny_camel_store_account_get_folders_async_cancelled_callback,
 		tny_camel_store_account_get_folders_async_cancelled_destroyer, 
-		&info->cancelled, info, TNY_CAMEL_QUEUE_NORMAL_ITEM|
-			TNY_CAMEL_QUEUE_PRIORITY_ITEM, __FUNCTION__);
+		&info->cancelled, info, sizeof (GetFoldersInfo),
+		TNY_CAMEL_QUEUE_NORMAL_ITEM|TNY_CAMEL_QUEUE_PRIORITY_ITEM, 
+		__FUNCTION__);
 
 	return;
 }
@@ -1689,6 +1641,8 @@
 
 
 typedef struct {
+	TnyCamelQueueable parent;
+
 	TnySessionCamel *session;
 	TnyCamelStoreAccount *self;
 	gboolean online;
@@ -1788,7 +1742,7 @@
 	GoingOnlineInfo *info = (GoingOnlineInfo *) user_data;
 	g_object_unref (info->self);
 	camel_object_unref (info->session);
-	g_slice_free (GoingOnlineInfo, info);
+
 	return;
 }
 
@@ -1819,9 +1773,10 @@
 
 	_tny_camel_queue_launch_wflags (priv->queue, 
 		tny_camel_store_account_queue_going_online_thread,
+		NULL, NULL, /* If not canceled, we'll cleanup in the thread */
 		cancelled_conn, cancelled_conn_destroy, NULL,
-		 info, TNY_CAMEL_QUEUE_RECONNECT_ITEM|
-			TNY_CAMEL_QUEUE_CANCELLABLE_ITEM,
+		 info, sizeof (GoingOnlineInfo),
+		TNY_CAMEL_QUEUE_RECONNECT_ITEM|TNY_CAMEL_QUEUE_CANCELLABLE_ITEM,
 		__FUNCTION__);
 
 	return;
Index: libtinymail-camel/tny-camel-account.c
===================================================================
--- libtinymail-camel/tny-camel-account.c	(revision 2991)
+++ libtinymail-camel/tny-camel-account.c	(working copy)
@@ -124,7 +124,6 @@
 	apriv->service->reconnecting = FALSE;
 
 	g_object_unref (info->self);
-	g_slice_free (ReconInfo, info);
 	return NULL;
 }
 
@@ -139,7 +138,6 @@
 {
 	ReconInfo *info = (ReconInfo *) user_data;
 	g_object_unref (info->self);
-	g_slice_free (ReconInfo, info);
 	return;
 }
 
@@ -229,8 +227,12 @@
 				TNY_CAMEL_QUEUE_RECONNECT_ITEM);
 
 			_tny_camel_queue_launch_wflags (aspriv->queue, 
-				reconnect_thread, cancelled_refresh, 
-				cancelled_refresh_destroy, NULL, info,
+				reconnect_thread, 
+				NULL, NULL,
+				cancelled_refresh, 
+				cancelled_refresh_destroy, 
+				NULL, 
+				info, sizeof (ReconInfo),
 				TNY_CAMEL_QUEUE_RECONNECT_ITEM,
 				__FUNCTION__);
 		}
@@ -1351,6 +1353,7 @@
 	TnyCamelAccount *self = (TnyCamelAccount *)instance;
 	TnyCamelAccountPriv *priv = TNY_CAMEL_ACCOUNT_GET_PRIVATE (self);
 
+	priv->queue = _tny_camel_queue_new (self);
 	priv->delete_this = NULL;
 	priv->is_ready = FALSE;
 	priv->is_connecting = FALSE;
@@ -1799,6 +1802,8 @@
 
 typedef struct 
 {
+	TnyCamelQueueable parent;
+
 	TnyCamelAccount *self;
 	TnyCamelGetSupportedSecureAuthCallback callback;
 	TnyStatusCallback status_callback;
@@ -1809,10 +1814,6 @@
 	GError *err;
 	TnySessionCamel *session;
 
-	GCond* condition;
-	gboolean had_callback;
-	GMutex *mutex;
-
 } GetSupportedAuthInfo;
 
 
@@ -1833,6 +1834,22 @@
 }
 
 
+static gboolean 
+on_supauth_cancelled_idle_func (gpointer user_data)
+{
+	GetSupportedAuthInfo *info = (GetSupportedAuthInfo *) user_data;
+
+	if (info->callback) {
+		tny_lockable_lock (info->session->priv->ui_lock);
+		info->callback (info->self, TRUE, info->result, info->err, info->user_data);
+		tny_lockable_unlock (info->session->priv->ui_lock);
+	}
+
+	tny_idle_stopper_stop (info->stopper);
+
+	return FALSE; /* Don't call this again. */
+}
+
 static void 
 on_supauth_destroy_func (gpointer user_data)
 {
@@ -1849,19 +1866,18 @@
 	tny_idle_stopper_destroy (info->stopper);
 	info->stopper = NULL;
 
-	if (info->condition) {
-		g_mutex_lock (info->mutex);
-		g_cond_broadcast (info->condition);
-		info->had_callback = TRUE;
-		g_mutex_unlock (info->mutex);
+	if (info->err) {
+		g_error_free (info->err);
+		info->err = NULL;
 	}
+
+	return;
 }
 
 static void 
 on_supauth_destroy_and_kill_func (gpointer user_data)
 {
 	on_supauth_destroy_func (user_data);
-	g_slice_free (GetSupportedAuthInfo, user_data);
 }
 
 /* Starts the operation in the thread: */
@@ -1918,30 +1934,6 @@
 
 	g_static_rec_mutex_unlock (priv->service_lock);
 
-	info->mutex = g_mutex_new ();
-	info->condition = g_cond_new ();
-	info->had_callback = FALSE;
-
-	execute_callback (10, G_PRIORITY_HIGH, 
-		on_supauth_idle_func, 
-		info, on_supauth_destroy_func);
-
-	/* Wait on the queue for the mainloop callback to be finished */
-	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);
-
-	if (info->err) {
-		g_error_free (info->err);
-		info->err = NULL;
-	}
-
-	g_slice_free (GetSupportedAuthInfo, info);
-
 	tny_status_free(status);
 
 	return NULL;
@@ -2018,9 +2010,12 @@
 		TnyCamelStoreAccountPriv *aspriv = TNY_CAMEL_STORE_ACCOUNT_GET_PRIVATE (self);
 		_tny_camel_queue_launch (aspriv->queue, 
 			tny_camel_account_get_supported_secure_authentication_async_thread, 
-			on_supauth_idle_func, on_supauth_destroy_and_kill_func, 
-			&info->cancelled, info, __FUNCTION__);
+			on_supauth_idle_func, on_supauth_destroy_func, 
+			on_supauth_cancelled_idle_func, on_supauth_destroy_and_kill_func, 
+			&info->cancelled, info, sizeof (GetSupportedAuthInfo),
+			__FUNCTION__);
 	} else {
+		TnyCamelQueue *temp_queue = _tny_camel_queue_new (self);
 		g_thread_create (tny_camel_account_get_supported_secure_authentication_async_thread,
 			info, FALSE, NULL);
 	}
@@ -2104,6 +2099,8 @@
 
 	g_static_rec_mutex_unlock (priv->service_lock);
 
+	g_object_unref (priv->queue);
+
 	camel_exception_free (priv->ex);
 
 	/* g_static_rec_mutex_free (priv->service_lock); */


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]