Patch to TnyCamelFolder
- From: Sergio Villar Senin <svillar igalia com>
- To: tinymail-devel-list gnome org
- Subject: Patch to TnyCamelFolder
- Date: Thu, 05 Jul 2007 12:12:06 +0200
Hi all,
find attached a patch against TnyCamelFolder that changes the following
things:
* If the _tny_session_check_operation check fails in the
asynchronous operations, then call the callback into an idle call if the
GMainLoop is available. This allows the clients to always wrap their
callbacks -that executes gtk+ code- with gkd_threads_enter/leave() stuff.
* Refactored the calls to the callbacks in a function called
execute_callback, because they all do the same with different parameters.
* Changed the priority of the idles. Now the status callbacks have
more priority than the function callbacks. This way we'll call first,
all the status callbacks, and then the function callback.
Br
Index: tny-camel-folder.c
===================================================================
--- tny-camel-folder.c (revision 2388)
+++ tny-camel-folder.c (working copy)
@@ -834,6 +834,26 @@
return;
}
+/**
+ * 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
@@ -914,15 +934,9 @@
TNY_FOLDER_STATUS, TNY_FOLDER_STATUS_CODE_REFRESH, what, sofar,
oftotal, oinfo->stopper, oinfo->user_data);
- if (oinfo->depth > 0)
- {
- g_idle_add_full (G_PRIORITY_DEFAULT_IDLE,
- tny_progress_info_idle_func, info,
- tny_progress_info_destroy);
- } else {
- tny_progress_info_idle_func (info);
- tny_progress_info_destroy (info);
- }
+ execute_callback (oinfo->depth, G_PRIORITY_HIGH,
+ tny_progress_info_idle_func, info,
+ tny_progress_info_destroy);
return;
}
@@ -982,15 +996,9 @@
if (info->callback)
{
- if (info->depth > 0)
- {
- g_idle_add_full (G_PRIORITY_HIGH,
- tny_camel_folder_refresh_async_callback,
- info, tny_camel_folder_refresh_async_destroyer);
- } else {
- tny_camel_folder_refresh_async_callback (info);
- tny_camel_folder_refresh_async_destroyer (info);
- }
+ execute_callback (info->depth, G_PRIORITY_DEFAULT,
+ tny_camel_folder_refresh_async_callback, info,
+ tny_camel_folder_refresh_async_destroyer);
} else { /* Thread reference */
g_object_unref (G_OBJECT (self));
_tny_camel_folder_unreason (priv);
@@ -1007,6 +1015,28 @@
return;
}
+static void
+tny_camel_folder_refresh_async_cancelled_destroyer (gpointer thr_user_data)
+{
+ RefreshFolderInfo *info = thr_user_data;
+
+ g_error_free (info->err);
+ g_object_unref (info->self);
+ g_slice_free (RefreshFolderInfo, thr_user_data);
+}
+
+static gboolean
+tny_camel_folder_refresh_async_cancelled_callback (gpointer thr_user_data)
+{
+ RefreshFolderInfo *info = thr_user_data;
+
+ if (info->callback)
+ info->callback (info->self, TRUE, &info->err, info->user_data);
+
+ return FALSE;
+}
+
+
/**
* tny_camel_folder_refresh_async_default:
*
@@ -1028,17 +1058,7 @@
GError *err = NULL;
TnyCamelFolderPriv *priv = TNY_CAMEL_FOLDER_GET_PRIVATE (self);
- if (!_tny_session_check_operation (TNY_FOLDER_PRIV_GET_SESSION(priv), priv->account, &err,
- TNY_FOLDER_ERROR, TNY_FOLDER_ERROR_REFRESH))
- {
- if (callback)
- callback (self, TRUE, &err, user_data);
- g_error_free (err);
- return;
- }
-
- /* Idle info for the status callback: */
-
+ /* Idle info for the callbacks */
info = g_slice_new (RefreshFolderInfo);
info->session = TNY_FOLDER_PRIV_GET_SESSION (priv);
info->err = NULL;
@@ -1047,11 +1067,26 @@
info->status_callback = status_callback;
info->user_data = user_data;
info->depth = g_main_depth ();
-
+
+ if (!_tny_session_check_operation (TNY_FOLDER_PRIV_GET_SESSION(priv), priv->account, &err,
+ TNY_FOLDER_ERROR, TNY_FOLDER_ERROR_REFRESH))
+ {
+ if (callback) {
+ info->err = g_error_copy (err);
+ g_object_ref (info->self);
+
+ execute_callback (info->depth, G_PRIORITY_DEFAULT,
+ tny_camel_folder_refresh_async_cancelled_callback, info,
+ tny_camel_folder_refresh_async_cancelled_destroyer);
+ }
+ g_error_free (err);
+ return;
+ }
+
+
/* Use a ref count because we do not know which of the 2 idle callbacks
* will be the last, and we can only unref self in the last callback:
* This is destroyed in the idle GDestroyNotify callback.*/
-
info->stopper = tny_idle_stopper_new();
/* thread reference */
@@ -1310,15 +1345,9 @@
TNY_FOLDER_STATUS, TNY_FOLDER_STATUS_CODE_GET_MSG, what, sofar,
oftotal, oinfo->stopper, oinfo->user_data);
- if (oinfo->depth > 0)
- {
- g_idle_add_full (G_PRIORITY_DEFAULT_IDLE,
- tny_progress_info_idle_func, info,
- tny_progress_info_destroy);
- } else {
- tny_progress_info_idle_func (info);
- tny_progress_info_destroy (info);
- }
+ execute_callback (oinfo->depth, G_PRIORITY_HIGH,
+ tny_progress_info_idle_func, info,
+ tny_progress_info_destroy);
return;
}
@@ -1375,15 +1404,9 @@
if (info->callback)
{
- if (info->depth > 0)
- {
- g_idle_add_full (G_PRIORITY_HIGH,
- tny_camel_folder_get_msg_async_callback,
- info, tny_camel_folder_get_msg_async_destroyer);
- } else {
- tny_camel_folder_get_msg_async_callback (info);
- tny_camel_folder_get_msg_async_destroyer (info);
- }
+ execute_callback (info->depth, G_PRIORITY_DEFAULT,
+ tny_camel_folder_get_msg_async_callback, info,
+ tny_camel_folder_get_msg_async_destroyer);
} else {/* thread reference */
_tny_camel_folder_unreason (priv);
g_object_unref (G_OBJECT (info->self));
@@ -1394,7 +1417,30 @@
return NULL;
}
+
static void
+tny_camel_folder_get_msg_async_cancelled_destroyer (gpointer thr_user_data)
+{
+ GetMsgInfo *info = (GetMsgInfo *) thr_user_data;
+
+ g_error_free (info->err);
+ g_object_unref (info->self);
+ g_slice_free (GetMsgInfo, info);
+}
+
+static gboolean
+tny_camel_folder_get_msg_async_cancelled_callback (gpointer thr_user_data)
+{
+
+ GetMsgInfo *info = (GetMsgInfo *) thr_user_data;
+
+ if (info->callback)
+ info->callback (info->self, TRUE, NULL, &info->err, info->user_data);
+
+ return FALSE;
+}
+
+static void
tny_camel_folder_get_msg_async (TnyFolder *self, TnyHeader *header, TnyGetMsgCallback callback, TnyStatusCallback status_callback, gpointer user_data)
{
return TNY_CAMEL_FOLDER_GET_CLASS (self)->get_msg_async_func (self, header, callback, status_callback, user_data);
@@ -1409,15 +1455,7 @@
GError *err = NULL;
TnyCamelFolderPriv *priv = TNY_CAMEL_FOLDER_GET_PRIVATE (self);
- if (!_tny_session_check_operation (TNY_FOLDER_PRIV_GET_SESSION(priv), priv->account, &err,
- TNY_FOLDER_ERROR, TNY_FOLDER_ERROR_GET_MSG))
- {
- if (callback)
- callback (self, TRUE, NULL, &err, user_data);
- g_error_free (err);
- return;
- }
-
+ /* Idle info for the callbacks */
info = g_slice_new (GetMsgInfo);
info->cancelled = FALSE;
info->session = TNY_FOLDER_PRIV_GET_SESSION (priv);
@@ -1428,10 +1466,24 @@
info->user_data = user_data;
info->depth = g_main_depth ();
+ if (!_tny_session_check_operation (TNY_FOLDER_PRIV_GET_SESSION(priv), priv->account, &err,
+ TNY_FOLDER_ERROR, TNY_FOLDER_ERROR_GET_MSG))
+ {
+ if (callback) {
+ info->err = g_error_copy (err);
+ g_object_ref (info->self);
+
+ execute_callback (info->depth, G_PRIORITY_DEFAULT,
+ tny_camel_folder_get_msg_async_cancelled_callback, info,
+ tny_camel_folder_get_msg_async_cancelled_destroyer);
+ }
+ g_error_free (err);
+ return;
+ }
+
/* Use a ref count because we do not know which of the 2 idle callbacks
* will be the last, and we can only unref self in the last callback:
* This is destroyed in the idle GDestroyNotify callback. */
-
info->stopper = tny_idle_stopper_new();
/* thread reference */
@@ -2247,15 +2299,9 @@
TNY_FOLDER_STATUS, TNY_FOLDER_STATUS_CODE_COPY_FOLDER, what, sofar,
oftotal, oinfo->stopper, oinfo->user_data);
- if (oinfo->depth > 0)
- {
- g_idle_add_full (G_PRIORITY_DEFAULT_IDLE,
- tny_progress_info_idle_func, info,
- tny_progress_info_destroy);
- } else {
- tny_progress_info_idle_func (info);
- tny_progress_info_destroy (info);
- }
+ execute_callback (oinfo->depth, G_PRIORITY_HIGH,
+ tny_progress_info_idle_func, info,
+ tny_progress_info_destroy);
return;
}
@@ -2306,15 +2352,9 @@
if (info->callback)
{
- if (info->depth > 0)
- {
- g_idle_add_full (G_PRIORITY_HIGH,
- tny_camel_folder_copy_async_callback,
- info, tny_camel_folder_copy_async_destroyer);
- } else {
- tny_camel_folder_copy_async_callback (info);
- tny_camel_folder_copy_async_destroyer (info);
- }
+ execute_callback (info->depth, G_PRIORITY_DEFAULT,
+ tny_camel_folder_copy_async_callback, info,
+ tny_camel_folder_copy_async_destroyer);
} else { /* Thread reference */
g_object_unref (info->into);
g_object_unref (info->self);
@@ -2326,6 +2366,30 @@
}
static void
+tny_camel_folder_copy_async_cancelled_destroyer (gpointer thr_user_data)
+{
+ CopyFolderInfo *info = (CopyFolderInfo *) thr_user_data;
+
+ g_free (info->new_name);
+ g_error_free (info->err);
+ g_object_unref (info->self);
+ g_object_unref (info->into);
+ g_slice_free (CopyFolderInfo, info);
+}
+
+static gboolean
+tny_camel_folder_copy_async_cancelled_callback (gpointer thr_user_data)
+{
+
+ CopyFolderInfo *info = (CopyFolderInfo *) thr_user_data;
+
+ if (info->callback)
+ info->callback (info->self, info->into, TRUE, NULL, &info->err, info->user_data);
+
+ return FALSE;
+}
+
+static void
tny_camel_folder_copy_async (TnyFolder *self, TnyFolderStore *into, const gchar *new_name, gboolean del, TnyCopyFolderCallback callback, TnyStatusCallback status_callback, gpointer user_data)
{
TNY_CAMEL_FOLDER_GET_CLASS (self)->copy_async_func (self, into, new_name, del, callback, status_callback, user_data);
@@ -2340,17 +2404,8 @@
GThread *thread;
GError *err = NULL;
- if (!_tny_session_check_operation (TNY_FOLDER_PRIV_GET_SESSION(priv), priv->account, &err,
- TNY_FOLDER_ERROR, TNY_FOLDER_ERROR_COPY))
- {
- if (callback)
- callback (self, into, TRUE, NULL, &err, user_data);
- g_error_free (err);
- return;
- }
-
+ /* Idle info for the callbacks */
info = g_slice_new (CopyFolderInfo);
-
info->cancelled = FALSE;
info->session = TNY_FOLDER_PRIV_GET_SESSION (priv);
info->self = self;
@@ -2364,10 +2419,25 @@
info->delete_originals = del;
info->new_name = g_strdup (new_name);
+ if (!_tny_session_check_operation (TNY_FOLDER_PRIV_GET_SESSION(priv), priv->account, &err,
+ TNY_FOLDER_ERROR, TNY_FOLDER_ERROR_COPY))
+ {
+ if (callback) {
+ info->err = g_error_copy (err);
+ g_object_ref (info->self);
+ g_object_ref (info->into);
+
+ execute_callback (info->depth, G_PRIORITY_DEFAULT,
+ tny_camel_folder_copy_async_cancelled_callback, info,
+ tny_camel_folder_copy_async_cancelled_destroyer);
+ }
+ g_error_free (err);
+ return;
+ }
+
/* Use a ref count because we do not know which of the 2 idle callbacks
* will be the last, and we can only unref self in the last callback:
* This is destroyed in the idle GDestroyNotify callback. */
-
info->stopper = tny_idle_stopper_new();
/* thread reference */
@@ -2665,15 +2735,9 @@
TNY_FOLDER_STATUS, TNY_FOLDER_STATUS_CODE_XFER_MSGS, what, sofar,
oftotal, oinfo->stopper, oinfo->user_data);
- if (oinfo->depth > 0)
- {
- g_idle_add_full (G_PRIORITY_DEFAULT_IDLE,
- tny_progress_info_idle_func, info,
- tny_progress_info_destroy);
- } else {
- tny_progress_info_idle_func (info);
- tny_progress_info_destroy (info);
- }
+ execute_callback (oinfo->depth, G_PRIORITY_HIGH,
+ tny_progress_info_idle_func, info,
+ tny_progress_info_destroy);
return;
}
@@ -2728,15 +2792,9 @@
/* Call callback function, if it exists */
if (info->callback)
{
- if (info->depth > 0)
- {
- g_idle_add_full (G_PRIORITY_HIGH,
- tny_camel_folder_transfer_msgs_async_callback,
- info, tny_camel_folder_transfer_msgs_async_destroyer);
- } else {
- tny_camel_folder_transfer_msgs_async_callback (info);
- tny_camel_folder_transfer_msgs_async_destroyer (info);
- }
+ execute_callback (info->depth, G_PRIORITY_DEFAULT,
+ tny_camel_folder_transfer_msgs_async_callback, info,
+ tny_camel_folder_transfer_msgs_async_destroyer);
} else {
/* Thread reference */
_tny_camel_folder_unreason (priv_src);
@@ -2752,6 +2810,29 @@
}
static void
+tny_camel_folder_transfer_msgs_async_cancelled_destroyer (gpointer thr_user_data)
+{
+ TransferMsgsInfo *info = thr_user_data;
+
+ g_error_free (info->err);
+ g_object_unref (info->new_header_list);
+ g_object_unref (info->self);
+ g_slice_free (TransferMsgsInfo, info);
+}
+
+static gboolean
+tny_camel_folder_transfer_msgs_async_cancelled_callback (gpointer thr_user_data)
+{
+ TransferMsgsInfo *info = thr_user_data;
+
+ if (info->callback)
+ info->callback (info->self, TRUE, &info->err, info->user_data);
+
+ return FALSE;
+}
+
+
+static void
tny_camel_folder_transfer_msgs_async (TnyFolder *self, TnyList *header_list, TnyFolder *folder_dst, gboolean delete_originals, TnyTransferMsgsCallback callback, TnyStatusCallback status_callback, gpointer user_data)
{
TNY_CAMEL_FOLDER_GET_CLASS (self)->transfer_msgs_async_func (self, header_list, folder_dst, delete_originals, callback, status_callback, user_data);
@@ -2768,15 +2849,7 @@
TnyCamelFolderPriv *priv_src = priv;
TnyCamelFolderPriv *priv_dst = TNY_CAMEL_FOLDER_GET_PRIVATE (folder_dst);
- if (!_tny_session_check_operation (TNY_FOLDER_PRIV_GET_SESSION(priv), priv->account, &err,
- TNY_FOLDER_ERROR, TNY_FOLDER_ERROR_TRANSFER_MSGS))
- {
- if (callback)
- callback (self, TRUE, &err, user_data);
- g_error_free (err);
- return;
- }
-
+ /* Idle info for the callbacks */
info = g_slice_new (TransferMsgsInfo);
info->cancelled = FALSE;
info->session = TNY_FOLDER_PRIV_GET_SESSION (priv);
@@ -2790,10 +2863,24 @@
info->delete_originals = delete_originals;
info->depth = g_main_depth ();
+ if (!_tny_session_check_operation (TNY_FOLDER_PRIV_GET_SESSION(priv), priv->account, &err,
+ TNY_FOLDER_ERROR, TNY_FOLDER_ERROR_TRANSFER_MSGS))
+ {
+ if (callback) {
+ info->err = g_error_copy (err);
+ g_object_ref (info->self);
+
+ execute_callback (info->depth, G_PRIORITY_DEFAULT,
+ tny_camel_folder_transfer_msgs_async_cancelled_callback, info,
+ tny_camel_folder_transfer_msgs_async_cancelled_destroyer);
+ }
+ g_error_free (err);
+ return;
+ }
+
/* Use a ref count because we do not know which of the 2 idle callbacks
* will be the last, and we can only unref self in the last callback:
* This is destroyed in the idle GDestroyNotify callback. */
-
info->stopper = tny_idle_stopper_new();
/* thread reference */
@@ -3462,15 +3549,9 @@
if (info->callback)
{
- if (info->depth > 0)
- {
- g_idle_add_full (G_PRIORITY_HIGH,
- tny_camel_folder_get_folders_async_callback,
- info, tny_camel_folder_get_folders_async_destroyer);
- } else {
- tny_camel_folder_get_folders_async_callback (info);
- tny_camel_folder_get_folders_async_destroyer (info);
- }
+ execute_callback (info->depth, G_PRIORITY_DEFAULT,
+ tny_camel_folder_get_folders_async_callback, info,
+ tny_camel_folder_get_folders_async_destroyer);
} else {
/* thread reference */
_tny_camel_folder_unreason (priv);
@@ -3483,6 +3564,28 @@
return NULL;
}
+static void
+tny_camel_folder_get_folders_async_cancelled_destroyer (gpointer thr_user_data)
+{
+ GetFoldersInfo *info = thr_user_data;
+
+ g_error_free (info->err);
+ g_object_unref (info->self);
+ g_object_unref (info->list);
+ g_slice_free (GetFoldersInfo, info);
+}
+
+static gboolean
+tny_camel_folder_get_folders_async_cancelled_callback (gpointer thr_user_data)
+{
+ GetFoldersInfo *info = thr_user_data;
+
+ if (info->callback)
+ info->callback (info->self, info->list, &info->err, info->user_data);
+
+ return FALSE;
+}
+
static void
tny_camel_folder_get_folders_async (TnyFolderStore *self, TnyList *list, TnyGetFoldersCallback callback, TnyFolderStoreQuery *query, TnyStatusCallback status_callback, gpointer user_data)
{
@@ -3497,15 +3600,7 @@
GError *err = NULL;
TnyCamelFolderPriv *priv = TNY_CAMEL_FOLDER_GET_PRIVATE (self);
- if (!_tny_session_check_operation (TNY_FOLDER_PRIV_GET_SESSION(priv), priv->account, &err,
- TNY_FOLDER_ERROR, TNY_FOLDER_ERROR_REFRESH))
- {
- if (callback)
- callback (self, list, &err, user_data);
- g_error_free (err);
- return;
- }
-
+ /* Idle info for the callbacks */
info = g_slice_new (GetFoldersInfo);
info->session = TNY_FOLDER_PRIV_GET_SESSION (priv);
info->self = self;
@@ -3515,6 +3610,22 @@
info->query = query;
info->depth = g_main_depth ();
+ if (!_tny_session_check_operation (TNY_FOLDER_PRIV_GET_SESSION(priv), priv->account, &err,
+ TNY_FOLDER_ERROR, TNY_FOLDER_ERROR_REFRESH))
+ {
+ if (callback) {
+ info->err = g_error_copy (err);
+ g_object_ref (info->self);
+ g_object_ref (info->list);
+
+ execute_callback (info->depth, G_PRIORITY_DEFAULT,
+ tny_camel_folder_get_folders_async_cancelled_callback, info,
+ tny_camel_folder_get_folders_async_cancelled_destroyer);
+ }
+ g_error_free (err);
+ return;
+ }
+
/* thread reference */
_tny_camel_folder_reason (priv);
g_object_ref (G_OBJECT (info->self));
@@ -3737,16 +3848,9 @@
{
info->self = TNY_FOLDER (g_object_ref (self));
- if (g_main_depth () > 0)
- {
- g_idle_add_full (G_PRIORITY_HIGH,
- tny_camel_folder_poke_status_callback,
- info, tny_camel_folder_poke_status_destroyer);
- } else
- {
- tny_camel_folder_poke_status_callback (info);
- tny_camel_folder_poke_status_destroyer (info);
- }
+ execute_callback (g_main_depth (), G_PRIORITY_HIGH,
+ tny_camel_folder_poke_status_callback, info,
+ tny_camel_folder_poke_status_destroyer);
}
return;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]