Re: The GDK lock in tinymail
- From: Philip Van Hoof <spam pvanhoof be>
- To: Rob Taylor <rob taylor codethink co uk>
- Cc: Dirk-Jan Binnema <Dirk-Jan Binnema nokia com>, tinymail-devel-list gnome org
- Subject: Re: The GDK lock in tinymail
- Date: Sun, 05 Aug 2007 00:03:19 +0200
And the patch grows ...
This version of the patch adds GDK lock correctness for g_signal_emit
situations. A few are left uncovered as those require some
infrastructure changes (for example in TnyMergeFolder we don't yet have
the ui_lock).
On Sat, 2007-08-04 at 12:01 +0200, Philip Van Hoof wrote:
> On Fri, 2007-08-03 at 18:51 +0100, Rob Taylor wrote:
> > Philip Van Hoof wrote:
> > > This patch makes Tinymail's callbacks and observer's updates behave like
> > > signals in Gtk+.
> > >
> > > Please review extensively
>
> > That's quite a complex patch! Could you explain it a bit?
>
> o. The notify_folder_observers, and notify_folder_store_observers got a
> _in_idle equivalent that will throw the function call into the
> GMainLoop using a g_idle_add_full. This was done to in a generic way
> escape the GDK lock or throw the call out of a thread
>
> o. All locations where folder observers are now called, are in the
> GMainLoop or at locations where it makes sense to lock the GDK lock
>
> o. All tny_folder_store_observer_update and tny_folder_observer_update
> have been wrapped with tny_lockable_lock and tny_lockable_unlock
>
> o. All callbacks have been wrapped with tny_lockable_lock and
> tny_lockable_unlock
>
> o. notify_folder_observers_about_copy got rewritten
>
> o. inform_observers_about_transfer got renamed to
> notify_folder_observers_about_transfer
>
> o. tny_camel_account_get_supported_secure_authentication got rewritten
>
> o. tny_gtk_folder_store_tree_model_folder_obsr_update got rewritten (it
> assumed that it got called from a thread, which is not the case
> anymore)
>
> o. tny_gtk_folder_store_tree_model_store_obsr_update got rewritten (it
> assumed that it got called from a thread, which is not the case
> anymore)
>
> o. All status_callback invokes got wrapped by tny_lockable_lock and
> tny_lockable_unlock (in tny-progress-info.c)
>
>
--
Philip Van Hoof, software developer
home: me at pvanhoof dot be
gnome: pvanhoof at gnome dot org
http://www.pvanhoof.be/blog
Index: libtinymail-gpe/tny-gpe-device.c
===================================================================
--- libtinymail-gpe/tny-gpe-device.c (revision 2551)
+++ libtinymail-gpe/tny-gpe-device.c (working copy)
@@ -1,4 +1,4 @@
-/* libtinymail-camel - The Tiny Mail base library for Camel
+/* libtinymail-gpe - The Tiny Mail base library for gpe
* Copyright (C) 2006-2007 Philip Van Hoof <pvanhoof gnome org>
*
* This library is free software; you can redistribute it and/or
@@ -31,13 +31,16 @@
static void tny_gpe_device_on_offline (TnyDevice *self);
static gboolean tny_gpe_device_is_online (TnyDevice *self);
-static void
+
+static gboolean
emit_status (TnyDevice *self)
{
if (tny_gpe_device_is_online (self))
tny_gpe_device_on_online (self);
else
tny_gpe_device_on_offline (self);
+
+ return FALSE;
}
static void
@@ -52,12 +55,16 @@
/* Signal if it changed: */
if (status_before != tny_gpe_device_is_online (self))
- emit_status (self);
+ g_idle_add_full (G_PRIORITY_DEFAULT,
+ (GSourceFunc) emit_status,
+ g_object_ref (self),
+ (GDestroyNotify) g_object_unref);
}
static void
tny_gpe_device_force_online (TnyDevice *self)
{
+
TnyGpeDevicePriv *priv = TNY_GPE_DEVICE_GET_PRIVATE (self);
const gboolean already_online = tny_gpe_device_is_online (self);
@@ -67,8 +74,11 @@
/* Signal if it changed: */
if (!already_online)
- emit_status (self);
-
+ g_idle_add_full (G_PRIORITY_DEFAULT,
+ (GSourceFunc) emit_status,
+ g_object_ref (self),
+ (GDestroyNotify) g_object_unref);
+
return;
}
@@ -85,7 +95,10 @@
/* Signal if it changed: */
if (!already_offline)
- emit_status (self);
+ g_idle_add_full (G_PRIORITY_DEFAULT,
+ (GSourceFunc) emit_status,
+ g_object_ref (self),
+ (GDestroyNotify) g_object_unref);
return;
}
@@ -93,7 +106,9 @@
static void
tny_gpe_device_on_online (TnyDevice *self)
{
+ gdk_threads_enter ();
g_signal_emit (self, tny_device_signals [TNY_DEVICE_CONNECTION_CHANGED], 0, TRUE);
+ gdk_threads_leave ();
return;
}
@@ -101,7 +116,9 @@
static void
tny_gpe_device_on_offline (TnyDevice *self)
{
+ gdk_threads_enter ();
g_signal_emit (self, tny_device_signals [TNY_DEVICE_CONNECTION_CHANGED], 0, FALSE);
+ gdk_threads_leave ();
return;
}
@@ -121,7 +138,7 @@
static void
tny_gpe_device_instance_init (GTypeInstance *instance, gpointer g_class)
{
- TnyGpeDevice *self = (TnyGpeDevice *)instance;
+ TnyGpeDevice *self = (TnyGpeDevice *) instance;
TnyGpeDevicePriv *priv = TNY_GPE_DEVICE_GET_PRIVATE (self);
return;
@@ -131,7 +148,7 @@
/**
* tny_gpe_device_new:
*
- * Return value: A new #TnyDevice instance
+ * Return value: A new #TnyDevice implemented for GPE
**/
TnyDevice*
tny_gpe_device_new (void)
@@ -145,8 +162,11 @@
static void
tny_gpe_device_finalize (GObject *object)
{
+ TnyGpeDevice *self = (TnyGpeDevice *) object;
+ TnyGpeDevicePriv *priv = TNY_GPE_DEVICE_GET_PRIVATE (self);
+
(*parent_class->finalize) (object);
-
+
return;
}
Index: libtinymail-camel/tny-camel-folder.c
===================================================================
--- libtinymail-camel/tny-camel-folder.c (revision 2551)
+++ libtinymail-camel/tny-camel-folder.c (working copy)
@@ -77,71 +77,190 @@
static GObjectClass *parent_class = NULL;
+
+typedef struct {
+ GObject *self;
+ GObject *change;
+} NotFolObInIdleInfo;
+
+static void
+do_notify_in_idle_destroy (gpointer user_data)
+{
+ NotFolObInIdleInfo *info = (NotFolObInIdleInfo *) user_data;
+ TnyCamelFolderPriv *priv = TNY_CAMEL_FOLDER_GET_PRIVATE (info->self);
+
+ g_object_unref (info->change);
+ _tny_camel_folder_unreason (priv);
+ g_object_unref (info->self);
+ g_slice_free (NotFolObInIdleInfo, info);
+}
+
static void
notify_folder_store_observers_about (TnyFolderStore *self, TnyFolderStoreChange *change)
{
TnyCamelFolderPriv *priv = TNY_CAMEL_FOLDER_GET_PRIVATE (self);
+ TnyCamelAccountPriv *apriv = TNY_CAMEL_ACCOUNT_GET_PRIVATE (priv->account);
TnyIterator *iter;
TnyList *list;
g_static_rec_mutex_lock (priv->obs_lock);
-
if (!priv->sobservers) {
g_static_rec_mutex_unlock (priv->obs_lock);
return;
}
-
list = tny_list_copy (priv->sobservers);
g_static_rec_mutex_unlock (priv->obs_lock);
iter = tny_list_create_iterator (list);
-
while (!tny_iterator_is_done (iter))
{
TnyFolderStoreObserver *observer = TNY_FOLDER_STORE_OBSERVER (tny_iterator_get_current (iter));
-
+ tny_lockable_lock (apriv->session->priv->ui_lock);
tny_folder_store_observer_update (observer, change);
- g_object_unref (G_OBJECT (observer));
+ tny_lockable_unlock (apriv->session->priv->ui_lock);
+ g_object_unref (observer);
tny_iterator_next (iter);
}
- g_object_unref (G_OBJECT (iter));
-
+ g_object_unref (iter);
g_object_unref (list);
+ return;
}
+static gboolean
+notify_folder_store_observers_about_idle (gpointer user_data)
+{
+ NotFolObInIdleInfo *info = (NotFolObInIdleInfo *) user_data;
+ notify_folder_store_observers_about (TNY_FOLDER_STORE (info->self),
+ TNY_FOLDER_STORE_CHANGE (info->change));
+ return FALSE;
+}
+
static void
+notify_folder_store_observers_about_in_idle (TnyFolderStore *self, TnyFolderStoreChange *change)
+{
+ NotFolObInIdleInfo *info = g_slice_new (NotFolObInIdleInfo);
+ TnyCamelFolderPriv *priv = TNY_CAMEL_FOLDER_GET_PRIVATE (self);
+
+ _tny_camel_folder_reason (priv);
+ info->self = g_object_ref (self);
+ info->change = g_object_ref (change);
+ g_idle_add_full (G_PRIORITY_HIGH, notify_folder_store_observers_about_idle,
+ info, do_notify_in_idle_destroy);
+}
+
+
+static void
notify_folder_observers_about (TnyFolder *self, TnyFolderChange *change)
{
TnyCamelFolderPriv *priv = TNY_CAMEL_FOLDER_GET_PRIVATE (self);
+ TnyCamelAccountPriv *apriv = TNY_CAMEL_ACCOUNT_GET_PRIVATE (priv->account);
TnyIterator *iter;
TnyList *list;
g_static_rec_mutex_lock (priv->obs_lock);
-
if (!priv->observers) {
g_static_rec_mutex_unlock (priv->obs_lock);
return;
}
-
list = tny_list_copy (priv->observers);
g_static_rec_mutex_unlock (priv->obs_lock);
iter = tny_list_create_iterator (list);
-
while (!tny_iterator_is_done (iter))
{
TnyFolderObserver *observer = TNY_FOLDER_OBSERVER (tny_iterator_get_current (iter));
+ tny_lockable_lock (apriv->session->priv->ui_lock);
tny_folder_observer_update (observer, change);
- g_object_unref (G_OBJECT (observer));
+ tny_lockable_unlock (apriv->session->priv->ui_lock);
+ g_object_unref (observer);
tny_iterator_next (iter);
}
- g_object_unref (G_OBJECT (iter));
+ g_object_unref (iter);
+ g_object_unref (list);
+ return;
+}
+
+
+static gboolean
+notify_folder_observers_about_idle (gpointer user_data)
+{
+ NotFolObInIdleInfo *info = (NotFolObInIdleInfo *) user_data;
+ notify_folder_observers_about (TNY_FOLDER (info->self),
+ TNY_FOLDER_CHANGE (info->change));
+ return FALSE;
+}
+
+static void
+notify_folder_observers_about_in_idle (TnyFolder *self, TnyFolderChange *change)
+{
+ NotFolObInIdleInfo *info = g_slice_new (NotFolObInIdleInfo);
+ TnyCamelFolderPriv *priv = TNY_CAMEL_FOLDER_GET_PRIVATE (self);
+
+ _tny_camel_folder_reason (priv);
+ info->self = g_object_ref (self);
+ info->change = g_object_ref (change);
+ g_idle_add_full (G_PRIORITY_HIGH, notify_folder_observers_about_idle,
+ info, do_notify_in_idle_destroy);
+}
+
+
+static void
+notify_folder_store_observers_about_for_store_acc (TnyFolderStore *self, TnyFolderStoreChange *change)
+{
+ TnyCamelStoreAccountPriv *priv = TNY_CAMEL_STORE_ACCOUNT_GET_PRIVATE (self);
+ TnyCamelAccountPriv *apriv = TNY_CAMEL_ACCOUNT_GET_PRIVATE (self);
+ TnyIterator *iter;
+ TnyList *list = NULL;
+
+ g_static_rec_mutex_lock (priv->obs_lock);
+ if (!priv->sobservers) {
+ g_static_rec_mutex_unlock (priv->obs_lock);
+ return;
+ }
+ list = tny_list_copy (priv->sobservers);
+ g_static_rec_mutex_unlock (priv->obs_lock);
+
+ iter = tny_list_create_iterator (list);
+ while (!tny_iterator_is_done (iter))
+ {
+ TnyFolderStoreObserver *observer = TNY_FOLDER_STORE_OBSERVER (tny_iterator_get_current (iter));
+ tny_lockable_lock (apriv->session->priv->ui_lock);
+ tny_folder_store_observer_update (observer, change);
+ tny_lockable_unlock (apriv->session->priv->ui_lock);
+ g_object_unref (observer);
+ tny_iterator_next (iter);
+ }
+ g_object_unref (iter);
g_object_unref (list);
+ return;
}
+static gboolean
+notify_folder_store_observers_about_for_store_acc_idle (gpointer user_data)
+{
+ NotFolObInIdleInfo *info = (NotFolObInIdleInfo *) user_data;
+ notify_folder_store_observers_about_for_store_acc (TNY_FOLDER_STORE (info->self),
+ TNY_FOLDER_STORE_CHANGE (info->change));
+ return FALSE;
+}
+
+static void
+notify_folder_store_observers_about_for_store_acc_in_idle (TnyFolderStore *self, TnyFolderStoreChange *change)
+{
+ NotFolObInIdleInfo *info = g_slice_new (NotFolObInIdleInfo);
+ TnyCamelFolderPriv *priv = TNY_CAMEL_FOLDER_GET_PRIVATE (self);
+
+ _tny_camel_folder_reason (priv);
+ info->self = g_object_ref (self);
+ info->change = g_object_ref (change);
+ g_idle_add_full (G_PRIORITY_HIGH, notify_folder_store_observers_about_for_store_acc_idle,
+ info, do_notify_in_idle_destroy);
+}
+
+
static void
update_iter_counts (TnyCamelFolderPriv *priv)
{
@@ -163,7 +282,7 @@
update_iter_counts (priv);
tny_folder_change_set_new_unread_count (change, priv->unread_length);
tny_folder_change_set_new_all_count (change, priv->cached_length);
- notify_folder_observers_about (TNY_FOLDER (self), change);
+ notify_folder_observers_about_in_idle (TNY_FOLDER (self), change);
g_object_unref (change);
}
@@ -616,9 +735,9 @@
tny_folder_change_set_new_all_count (change, priv->cached_length);
tny_folder_change_set_new_unread_count (change, priv->unread_length);
- notify_folder_observers_about (self, change);
+ notify_folder_observers_about_in_idle (self, change);
- g_object_unref (G_OBJECT (change));
+ g_object_unref (change);
if (dst_orig_uids) {
g_ptr_array_foreach (dst_orig_uids, (GFunc) g_free, NULL);
@@ -690,7 +809,7 @@
/* Notify header has been removed */
change = tny_folder_change_new (self);
tny_folder_change_add_expunged_header (change, header);
- notify_folder_observers_about (self, change);
+ notify_folder_observers_about_in_idle (self, change);
g_object_unref (change);
g_static_rec_mutex_unlock (priv->folder_lock);
@@ -993,8 +1112,11 @@
notify_folder_observers_about (self, change);
g_object_unref (change);
- if (info->callback)
+ if (info->callback) {
+ tny_lockable_lock (info->session->priv->ui_lock);
info->callback (info->self, info->cancelled, &info->err, info->user_data);
+ tny_lockable_unlock (info->session->priv->ui_lock);
+ }
tny_idle_stopper_stop (info->stopper);
@@ -1010,7 +1132,7 @@
info = tny_progress_info_new (G_OBJECT (oinfo->self), oinfo->status_callback,
TNY_FOLDER_STATUS, TNY_FOLDER_STATUS_CODE_SYNC, what, sofar,
- oftotal, oinfo->stopper, oinfo->user_data);
+ oftotal, oinfo->stopper, oinfo->session->priv->ui_lock, oinfo->user_data);
execute_callback (oinfo->depth, G_PRIORITY_HIGH,
tny_progress_info_idle_func, info,
@@ -1109,8 +1231,11 @@
tny_camel_folder_sync_async_cancelled_callback (gpointer thr_user_data)
{
SyncFolderInfo *info = thr_user_data;
- if (info->callback)
+ if (info->callback) {
+ tny_lockable_lock (info->session->priv->ui_lock);
info->callback (info->self, TRUE, &info->err, info->user_data);
+ tny_lockable_unlock (info->session->priv->ui_lock);
+ }
return FALSE;
}
@@ -1229,8 +1354,11 @@
notify_folder_observers_about (self, change);
g_object_unref (change);
- if (info->callback)
+ if (info->callback) {
+ tny_lockable_lock (info->session->priv->ui_lock);
info->callback (info->self, info->cancelled, &info->err, info->user_data);
+ tny_lockable_unlock (info->session->priv->ui_lock);
+ }
/* Prevent status callbacks from being called after this
* (can happen because the 2 idle callbacks have different priorities)
@@ -1250,7 +1378,8 @@
info = tny_progress_info_new (G_OBJECT (oinfo->self), oinfo->status_callback,
TNY_FOLDER_STATUS, TNY_FOLDER_STATUS_CODE_REFRESH, what, sofar,
- oftotal, oinfo->stopper, oinfo->user_data);
+ oftotal, oinfo->stopper, oinfo->session->priv->ui_lock,
+ oinfo->user_data);
execute_callback (oinfo->depth, G_PRIORITY_HIGH,
tny_progress_info_idle_func, info,
@@ -1353,8 +1482,11 @@
tny_camel_folder_refresh_async_cancelled_callback (gpointer thr_user_data)
{
RefreshFolderInfo *info = thr_user_data;
- if (info->callback)
+ if (info->callback) {
+ tny_lockable_lock (info->session->priv->ui_lock);
info->callback (info->self, TRUE, &info->err, info->user_data);
+ tny_lockable_unlock (info->session->priv->ui_lock);
+ }
return FALSE;
}
@@ -1482,7 +1614,7 @@
change = tny_folder_change_new (self);
tny_folder_change_set_new_all_count (change, priv->cached_length);
tny_folder_change_set_new_unread_count (change, priv->unread_length);
- notify_folder_observers_about (self, change);
+ notify_folder_observers_about_in_idle (self, change);
g_object_unref (change);
return;
@@ -1568,8 +1700,11 @@
tny_camel_folder_get_headers_async_callback (gpointer thr_user_data)
{
GetHeadersInfo *info = thr_user_data;
- if (info->callback)
+ if (info->callback) {
+ tny_lockable_lock (info->session->priv->ui_lock);
info->callback (info->self, FALSE, info->headers, &info->err, info->user_data);
+ tny_lockable_unlock (info->session->priv->ui_lock);
+ }
return FALSE;
}
@@ -1625,8 +1760,11 @@
tny_camel_folder_get_headers_async_cancelled_callback (gpointer thr_user_data)
{
GetHeadersInfo *info = thr_user_data;
- if (info->callback)
+ if (info->callback) {
+ tny_lockable_lock (info->session->priv->ui_lock);
info->callback (info->self, TRUE, info->headers, &info->err, info->user_data);
+ tny_lockable_unlock (info->session->priv->ui_lock);
+ }
return FALSE;
}
@@ -1823,8 +1961,11 @@
g_object_unref (change);
}
- if (info->callback)
+ if (info->callback) {
+ tny_lockable_lock (info->session->priv->ui_lock);
info->callback (info->self, info->cancelled, info->msg, &info->err, info->user_data);
+ tny_lockable_unlock (info->session->priv->ui_lock);
+ }
if (info->msg)
g_object_unref (info->msg);
@@ -1847,7 +1988,7 @@
info = tny_progress_info_new (G_OBJECT (oinfo->self), oinfo->status_callback,
TNY_FOLDER_STATUS, TNY_FOLDER_STATUS_CODE_GET_MSG, what, sofar,
- oftotal, oinfo->stopper, oinfo->user_data);
+ oftotal, oinfo->stopper, oinfo->session->priv->ui_lock, oinfo->user_data);
execute_callback (oinfo->depth, G_PRIORITY_HIGH,
tny_progress_info_idle_func, info,
@@ -1946,8 +2087,11 @@
{
GetMsgInfo *info = (GetMsgInfo *) thr_user_data;
- if (info->callback)
+ if (info->callback) {
+ tny_lockable_lock (info->session->priv->ui_lock);
info->callback (info->self, TRUE, NULL, &info->err, info->user_data);
+ tny_lockable_unlock (info->session->priv->ui_lock);
+ }
return FALSE;
}
@@ -2088,8 +2232,8 @@
{
change = tny_folder_change_new (self);
tny_folder_change_set_received_msg (change, retval);
- notify_folder_observers_about (self, change);
- g_object_unref (G_OBJECT (change));
+ notify_folder_observers_about_in_idle (self, change);
+ g_object_unref (change);
}
g_static_rec_mutex_unlock (priv->folder_lock);
@@ -2441,80 +2585,106 @@
}
+
+typedef struct {
+ TnyFolder *folder;
+ gboolean rem;
+} NotFolObsItem;
+
static void
-notify_folder_store_observers_about_for_store_acc (TnyFolderStore *self, TnyFolderStoreChange *change)
+not_fol_obs_foreach (gpointer key, gpointer value, gpointer user_data)
{
- TnyCamelStoreAccountPriv *priv = TNY_CAMEL_STORE_ACCOUNT_GET_PRIVATE (self);
- TnyIterator *iter;
+ GList *items = (GList *) value;
+ TnyFolderStore *str = (TnyFolderStore *) key;
+ TnyFolderStoreChange *change = tny_folder_store_change_new (str);
+ gboolean in_idle = (gboolean) user_data;
- if (!priv->sobservers)
- return;
+ while (items)
+ {
+ NotFolObsItem *item = (NotFolObsItem *) items->data;
- iter = tny_list_create_iterator (priv->sobservers);
- while (!tny_iterator_is_done (iter))
- {
- TnyFolderStoreObserver *observer = TNY_FOLDER_STORE_OBSERVER (tny_iterator_get_current (iter));
- tny_folder_store_observer_update (observer, change);
- g_object_unref (observer);
- tny_iterator_next (iter);
+ tny_debug ("tny_folder_copy: observers notify folder-%s %s\n",
+ item->rem ? "del" : "add",
+ tny_folder_get_name (item->folder));
+
+ if (item->rem)
+ tny_folder_store_change_add_removed_folder (change, item->folder);
+ else
+ tny_folder_store_change_add_created_folder (change, item->folder);
+
+ g_slice_free (NotFolObsItem, item);
+ items = g_list_next (items);
}
- g_object_unref (iter);
+
+ g_list_free (items);
+
+ if (TNY_IS_CAMEL_STORE_ACCOUNT (str)) {
+ if (in_idle)
+ notify_folder_store_observers_about_for_store_acc_in_idle (str, change);
+ else
+ notify_folder_store_observers_about_for_store_acc (str, change);
+ } else {
+ if (in_idle)
+ notify_folder_store_observers_about_in_idle (str, change);
+ else
+ notify_folder_store_observers_about (str, change);
+ }
+ g_object_unref (change);
+
+ return;
}
static void
-notify_folder_observers_about_copy (GList *adds, GList *rems, gboolean del)
+notify_folder_observers_about_copy (GList *adds, GList *rems, gboolean del, gboolean in_idle)
{
+
+ GHashTable *table = g_hash_table_new_full (g_direct_hash, g_direct_equal,
+ NULL, NULL);
+
rems = g_list_first (rems);
-
while (rems)
{
CpyEvent *evt = rems->data;
-
-
if (del) {
- TnyFolderStoreChange *change = tny_folder_store_change_new (evt->str);
- tny_folder_store_change_add_removed_folder (change, evt->fol);
+ gboolean add = FALSE;
+ NotFolObsItem *item = g_slice_new (NotFolObsItem);
+ GList *items = g_hash_table_lookup (table, evt->str);
+ if (!items)
+ add = TRUE;
+ item->folder = TNY_FOLDER (g_object_ref (evt->fol));
+ item->rem = TRUE;
+ items = g_list_append (items, item);
+ if (add)
+ g_hash_table_insert (table, evt->str, items);
- if (TNY_IS_CAMEL_STORE_ACCOUNT (evt->str))
- notify_folder_store_observers_about_for_store_acc (evt->str, change);
- else
- notify_folder_store_observers_about (evt->str, change);
-
- tny_debug ("tny_folder_copy: observers notify folder-del %s\n",
- tny_folder_get_name (evt->fol));
-
- g_object_unref (change);
}
-
cpy_event_free (evt);
rems = g_list_next (rems);
}
-
g_list_free (rems);
while (adds)
{
- TnyFolderStoreChange *change;
CpyEvent *evt = adds->data;
-
- change = tny_folder_store_change_new (evt->str);
- tny_folder_store_change_add_created_folder (change, evt->fol);
-
- if (TNY_IS_CAMEL_STORE_ACCOUNT (evt->str))
- notify_folder_store_observers_about_for_store_acc (evt->str, change);
- else
- notify_folder_store_observers_about (evt->str, change);
-
- g_object_unref (change);
-
- tny_debug ("tny_folder_copy: observers notify folder-add %s\n",
- tny_folder_get_name (evt->fol));
-
+ gboolean add = FALSE;
+ NotFolObsItem *item = g_slice_new (NotFolObsItem);
+ GList *items = g_hash_table_lookup (table, evt->str);
+ if (!items)
+ add = TRUE;
+ item->folder = TNY_FOLDER (g_object_ref (evt->fol));
+ item->rem = FALSE;
+ items = g_list_append (items, item);
+ if (add)
+ g_hash_table_insert (table, evt->str, items);
cpy_event_free (evt);
adds = g_list_next (adds);
}
+ g_list_free (adds);
- g_list_free (adds);
+ g_hash_table_foreach (table, not_fol_obs_foreach, (gpointer) in_idle);
+ g_hash_table_destroy (table);
+
+ return;
}
static CpyRecRet*
@@ -2674,7 +2844,14 @@
g_static_rec_mutex_lock (priv->folder_lock);
camel_folder_info_free (priv->iter);
priv->iter = NULL;
- /* unload_folder_no_lock (priv, FALSE); */
+
+ /* PVH investigated this and noticed that it made things
+ * crash in the following situation:
+ * You rename folder A to B, you copy B to C
+ *
+ * unload_folder_no_lock (priv, FALSE);
+ **/
+
g_static_rec_mutex_unlock (priv->folder_lock);
}
@@ -2725,7 +2902,7 @@
if (nerr != NULL)
g_propagate_error (err, nerr);
else
- notify_folder_observers_about_copy (adds, rems, del);
+ notify_folder_observers_about_copy (adds, rems, del, TRUE);
_tny_session_stop_operation (TNY_FOLDER_PRIV_GET_SESSION (priv));
@@ -2765,7 +2942,7 @@
if (info->err == NULL)
notify_folder_observers_about_copy (info->adds, info->rems,
- info->delete_originals);
+ info->delete_originals, FALSE);
if (info->new_folder)
g_object_unref (info->new_folder);
@@ -2800,13 +2977,13 @@
{
CopyFolderInfo *info = (CopyFolderInfo *) thr_user_data;
- if (info->callback)
+ if (info->callback) {
+ tny_lockable_lock (info->session->priv->ui_lock);
info->callback (info->self, info->into, info->cancelled,
info->new_folder, &info->err, info->user_data);
+ tny_lockable_unlock (info->session->priv->ui_lock);
+ }
- /* Prevent status callbacks from being called after this
- * (can happen because the 2 idle callbacks have different priorities)
- * by causing tny_idle_stopper_is_stopped() to return TRUE. */
tny_idle_stopper_stop (info->stopper);
return FALSE;
@@ -2830,7 +3007,7 @@
info = tny_progress_info_new (G_OBJECT (oinfo->self), oinfo->status_callback,
TNY_FOLDER_STATUS, TNY_FOLDER_STATUS_CODE_COPY_FOLDER, what, sofar,
- oftotal, oinfo->stopper, oinfo->user_data);
+ oftotal, oinfo->stopper, oinfo->session->priv->ui_lock, oinfo->user_data);
execute_callback (oinfo->depth, G_PRIORITY_HIGH,
tny_progress_info_idle_func, info,
@@ -2920,8 +3097,11 @@
{
CopyFolderInfo *info = (CopyFolderInfo *) thr_user_data;
- if (info->callback)
+ if (info->callback) {
+ tny_lockable_lock (info->session->priv->ui_lock);
info->callback (info->self, info->into, TRUE, NULL, &info->err, info->user_data);
+ tny_lockable_unlock (info->session->priv->ui_lock);
+ }
return FALSE;
}
@@ -3016,7 +3196,7 @@
static void
-inform_observers_about_transfer (TnyFolder *from, TnyFolder *to, gboolean del_orig, TnyList *headers, TnyList *new_header_list, gint from_all, gint to_all, gint from_unread, gint to_unread)
+notify_folder_observers_about_transfer (TnyFolder *from, TnyFolder *to, gboolean del_orig, TnyList *headers, TnyList *new_header_list, gint from_all, gint to_all, gint from_unread, gint to_unread, gboolean in_idle)
{
TnyFolderChange *tochange = tny_folder_change_new (to);
TnyFolderChange *fromchange = tny_folder_change_new (from);
@@ -3025,15 +3205,14 @@
iter = tny_list_create_iterator (new_header_list);
while (!tny_iterator_is_done (iter))
{
- TnyHeader *header;
- header = TNY_HEADER (tny_iterator_get_current (iter));
+ TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
if (del_orig)
tny_folder_change_add_expunged_header (fromchange, header);
tny_folder_change_add_added_header (tochange, header);
g_object_unref (header);
tny_iterator_next (iter);
}
- g_object_unref (G_OBJECT (iter));
+ g_object_unref (iter);
tny_folder_change_set_new_all_count (tochange, to_all);
tny_folder_change_set_new_unread_count (tochange, to_unread);
@@ -3041,8 +3220,14 @@
tny_folder_change_set_new_all_count (fromchange, from_all);
tny_folder_change_set_new_unread_count (fromchange, from_unread);
- notify_folder_observers_about (to, tochange);
- notify_folder_observers_about (from, fromchange);
+ if (in_idle)
+ {
+ notify_folder_observers_about_in_idle (to, tochange);
+ notify_folder_observers_about_in_idle (from, fromchange);
+ } else {
+ notify_folder_observers_about (to, tochange);
+ notify_folder_observers_about (from, fromchange);
+ }
g_object_unref (tochange);
g_object_unref (fromchange);
@@ -3057,10 +3242,6 @@
TnyCamelFolderPriv *priv_src = TNY_CAMEL_FOLDER_GET_PRIVATE (info->self);
TnyCamelFolderPriv *priv_dst = TNY_CAMEL_FOLDER_GET_PRIVATE (info->folder_dst);
- inform_observers_about_transfer (info->self, info->folder_dst, info->delete_originals,
- info->header_list, info->new_header_list, info->from_all,
- info->to_all, info->from_unread, info->to_unread);
-
/* thread reference */
_tny_camel_folder_unreason (priv_src);
g_object_unref (info->self);
@@ -3092,12 +3273,21 @@
tny_camel_folder_transfer_msgs_async_callback (gpointer thr_user_data)
{
TransferMsgsInfo *info = thr_user_data;
- if (info->callback)
+ TnyCamelFolderPriv *priv_src = TNY_CAMEL_FOLDER_GET_PRIVATE (info->self);
+ TnyCamelFolderPriv *priv_dst = TNY_CAMEL_FOLDER_GET_PRIVATE (info->folder_dst);
+
+ notify_folder_observers_about_transfer (info->self, info->folder_dst, info->delete_originals,
+ info->header_list, info->new_header_list, info->from_all,
+ info->to_all, info->from_unread, info->to_unread, FALSE);
+
+ if (info->callback) {
+ tny_lockable_lock (info->session->priv->ui_lock);
info->callback (info->self, info->cancelled, &info->err, info->user_data);
- /* Prevent status callbacks from being called after this
- * (can happen because the 2 idle callbacks have different priorities)
- * by causing tny_idle_stopper_is_stopped() to return TRUE. */
+ tny_lockable_unlock (info->session->priv->ui_lock);
+ }
+
tny_idle_stopper_stop (info->stopper);
+
return FALSE;
}
@@ -3276,8 +3466,10 @@
{
TnyHeader *hdr = _tny_camel_header_new ();
/* This adds a reason to live for folder_dst */
+ printf ("A %d\n", priv_dst->reason_to_live);
_tny_camel_header_set_folder (TNY_CAMEL_HEADER (hdr),
TNY_CAMEL_FOLDER (folder_dst), priv_dst);
+ printf ("A %d\n", priv_dst->reason_to_live);
/* hdr will take care of the freeup */
_tny_camel_header_set_as_memory (TNY_CAMEL_HEADER (hdr), minfo);
succeeded_news = g_list_prepend (succeeded_news, hdr);
@@ -3344,8 +3536,10 @@
TnyHeader *hdr = _tny_camel_header_new ();
/* This adds a reason to live for folder_dst */
+ printf ("B %d\n", priv_dst->reason_to_live);
_tny_camel_header_set_folder (TNY_CAMEL_HEADER (hdr),
TNY_CAMEL_FOLDER (folder_dst), priv_dst);
+ printf ("B %d\n", priv_dst->reason_to_live);
/* hdr will take care of the freeup */
_tny_camel_header_set_as_memory (TNY_CAMEL_HEADER (hdr), om);
tny_list_prepend (new_headers, G_OBJECT (hdr));
@@ -3412,7 +3606,7 @@
info = tny_progress_info_new (G_OBJECT (oinfo->self), oinfo->status_callback,
TNY_FOLDER_STATUS, TNY_FOLDER_STATUS_CODE_XFER_MSGS, what, sofar,
- oftotal, oinfo->stopper, oinfo->user_data);
+ oftotal, oinfo->stopper, oinfo->session->priv->ui_lock, oinfo->user_data);
execute_callback (oinfo->depth, G_PRIORITY_HIGH,
tny_progress_info_idle_func, info,
@@ -3474,8 +3668,8 @@
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);
+ 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);
@@ -3506,8 +3700,11 @@
tny_camel_folder_transfer_msgs_async_cancelled_callback (gpointer thr_user_data)
{
TransferMsgsInfo *info = thr_user_data;
- if (info->callback)
+ if (info->callback) {
+ tny_lockable_lock (info->session->priv->ui_lock);
info->callback (info->self, TRUE, &info->err, info->user_data);
+ tny_lockable_unlock (info->session->priv->ui_lock);
+ }
return FALSE;
}
@@ -3551,8 +3748,8 @@
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);
+ tny_camel_folder_transfer_msgs_async_cancelled_callback, info,
+ tny_camel_folder_transfer_msgs_async_cancelled_destroyer);
}
g_error_free (err);
return;
@@ -3618,8 +3815,8 @@
ufrom = camel_folder_get_unread_message_count (priv_src->folder);
uto = camel_folder_get_unread_message_count (priv_dst->folder);
- inform_observers_about_transfer (self, folder_dst, delete_originals,
- headers, new_headers, from, to, ufrom, uto);
+ notify_folder_observers_about_transfer (self, folder_dst, delete_originals,
+ headers, new_headers, from, to, ufrom, uto, TRUE);
}
g_object_unref (new_headers);
@@ -3840,8 +4037,8 @@
change = tny_folder_store_change_new (self);
tny_folder_store_change_add_removed_folder (change, folder);
- notify_folder_store_observers_about (self, change);
- g_object_unref (G_OBJECT (change));
+ notify_folder_store_observers_about_in_idle (self, change);
+ g_object_unref (change);
}
g_static_rec_mutex_unlock (apriv->factory_lock);
@@ -4041,8 +4238,8 @@
change = tny_folder_store_change_new (self);
tny_folder_store_change_add_created_folder (change, folder);
- notify_folder_store_observers_about (self, change);
- g_object_unref (G_OBJECT (change));
+ notify_folder_store_observers_about_in_idle (self, change);
+ g_object_unref (change);
_tny_session_stop_operation (TNY_FOLDER_PRIV_GET_SESSION (priv));
@@ -4227,8 +4424,11 @@
tny_camel_folder_get_folders_async_callback (gpointer thr_user_data)
{
GetFoldersInfo *info = thr_user_data;
- if (info->callback)
+ if (info->callback) {
+ tny_lockable_lock (info->session->priv->ui_lock);
info->callback (info->self, info->list, &info->err, info->user_data);
+ tny_lockable_unlock (info->session->priv->ui_lock);
+ }
return FALSE;
}
@@ -4288,8 +4488,11 @@
tny_camel_folder_get_folders_async_cancelled_callback (gpointer thr_user_data)
{
GetFoldersInfo *info = thr_user_data;
- if (info->callback)
+ if (info->callback) {
+ tny_lockable_lock (info->session->priv->ui_lock);
info->callback (info->self, info->list, &info->err, info->user_data);
+ tny_lockable_unlock (info->session->priv->ui_lock);
+ }
return FALSE;
}
Index: libtinymail-camel/camel-lite/camel/camel-folder-summary.c
===================================================================
--- libtinymail-camel/camel-lite/camel/camel-folder-summary.c (revision 2551)
+++ libtinymail-camel/camel-lite/camel/camel-folder-summary.c (working copy)
@@ -3206,7 +3206,8 @@
g_return_if_fail(mi != NULL);
- if (mi->summary) {
+ if (mi->summary)
+ {
CAMEL_SUMMARY_LOCK(mi->summary, ref_lock);
if (mi->refcount >= 1)
Index: libtinymail-camel/tny-camel-send-queue.c
===================================================================
--- libtinymail-camel/tny-camel-send-queue.c (revision 2551)
+++ libtinymail-camel/tny-camel-send-queue.c (working copy)
@@ -55,19 +55,32 @@
} ErrorInfo;
typedef struct {
- TnySendQueue *self;
- TnyMsg *msg;
- TnyHeader *header;
- gint i, total;
- guint signal_id;
+ TnySendQueue *self;
+ TnyMsg *msg;
+ TnyHeader *header;
+ gint i, total;
+ guint signal_id;
} ControlInfo;
static gboolean
emit_error_on_mainloop (gpointer data)
{
ErrorInfo *info = data;
+ TnyCamelSendQueuePriv *priv = TNY_CAMEL_SEND_QUEUE_GET_PRIVATE (info->self);
+ TnyCamelAccountPriv *apriv = NULL;
+
+ if (priv->trans_account)
+ apriv = TNY_CAMEL_ACCOUNT_GET_PRIVATE (priv->trans_account);
+
+ if (apriv)
+ tny_lockable_lock (apriv->session->priv->ui_lock);
+
g_signal_emit (info->self, tny_send_queue_signals [TNY_SEND_QUEUE_ERROR_HAPPENED],
0, info->header, info->msg, info->error);
+
+ if (apriv)
+ tny_lockable_unlock (apriv->session->priv->ui_lock);
+
return FALSE;
}
@@ -90,7 +103,12 @@
emit_error (TnySendQueue *self, TnyHeader *header, TnyMsg *msg, GError *error, int i, int total)
{
ErrorInfo *info = g_slice_new0 (ErrorInfo);
+ TnyCamelSendQueuePriv *priv = TNY_CAMEL_SEND_QUEUE_GET_PRIVATE (info->self);
+ TnyCamelAccountPriv *apriv = NULL;
+ if (priv->trans_account)
+ apriv = TNY_CAMEL_ACCOUNT_GET_PRIVATE (priv->trans_account);
+
if (error != NULL)
info->error = g_error_copy ((const GError *) error);
if (self)
@@ -103,9 +121,15 @@
info->i = i;
info->total = total;
+ if (apriv)
+ tny_lockable_lock (apriv->session->priv->ui_lock);
+
g_idle_add_full (G_PRIORITY_DEFAULT_IDLE,
emit_error_on_mainloop, info, destroy_error_info);
+ if (apriv)
+ tny_lockable_unlock (apriv->session->priv->ui_lock);
+
return;
}
@@ -113,47 +137,71 @@
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;
+ ControlInfo *info = data;
+ TnyCamelSendQueuePriv *priv = TNY_CAMEL_SEND_QUEUE_GET_PRIVATE (info->self);
+ TnyCamelAccountPriv *apriv = NULL;
+
+ if (priv->trans_account)
+ apriv = TNY_CAMEL_ACCOUNT_GET_PRIVATE (priv->trans_account);
+
+ if (apriv)
+ tny_lockable_lock (apriv->session->priv->ui_lock);
+
+ g_signal_emit (info->self, tny_send_queue_signals [info->signal_id],
+ 0, info->header, info->msg, info->i, info->total);
+
+ if (apriv)
+ tny_lockable_unlock (apriv->session->priv->ui_lock);
+
+ return FALSE;
}
static void
destroy_control_info (gpointer data)
{
- ControlInfo *info = 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));
+ 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);
+ g_slice_free (ControlInfo, info);
}
static void
emit_control (TnySendQueue *self, TnyHeader *header, TnyMsg *msg, guint signal_id, int i, int total)
{
- ControlInfo *info = g_slice_new0 (ControlInfo);
+ ControlInfo *info = g_slice_new0 (ControlInfo);
+ TnyCamelSendQueuePriv *priv = TNY_CAMEL_SEND_QUEUE_GET_PRIVATE (info->self);
+ TnyCamelAccountPriv *apriv = NULL;
- 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)));
+ if (priv->trans_account)
+ apriv = TNY_CAMEL_ACCOUNT_GET_PRIVATE (priv->trans_account);
- info->signal_id = signal_id;
- info->i = i;
- info->total = total;
-
- g_idle_add_full (G_PRIORITY_DEFAULT_IDLE,
+ 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;
+
+ if (apriv)
+ tny_lockable_lock (apriv->session->priv->ui_lock);
+
+ g_idle_add_full (G_PRIORITY_DEFAULT_IDLE,
emit_control_signals_on_mainloop, info, destroy_control_info);
- return;
+ if (apriv)
+ tny_lockable_unlock (apriv->session->priv->ui_lock);
+
+ return;
}
@@ -162,7 +210,6 @@
{
TnySendQueue *self = (TnySendQueue *) data;
TnyCamelSendQueuePriv *priv = TNY_CAMEL_SEND_QUEUE_GET_PRIVATE (self);
- /* TnyCamelAccountPriv *apriv = NULL; */
TnyFolder *sentbox, *outbox;
guint i = 0, length = 0;
TnyList *list;
@@ -172,10 +219,6 @@
priv->is_running = TRUE;
priv->creating_spin = FALSE;
-/* apriv = TNY_CAMEL_ACCOUNT_GET_PRIVATE (priv->trans_account);
- if (apriv)
- tny_session_camel_join_connecting (apriv->session); */
-
list = tny_simple_list_new ();
g_mutex_lock (priv->todo_lock);
@@ -254,7 +297,6 @@
}
if (to_remove)
g_list_free (to_remove);
- /**/
length = tny_list_get_length (headers);
@@ -287,7 +329,7 @@
/* 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);
-
+
if (err == NULL)
{
tny_transport_account_send (priv->trans_account, msg, &err);
@@ -348,12 +390,12 @@
errorhandler:
- g_object_unref (G_OBJECT (sentbox));
- g_object_unref (G_OBJECT (outbox));
+ g_object_unref (sentbox);
+ g_object_unref (outbox);
g_object_unref (self); /* The one added here */
- g_object_unref (G_OBJECT (self));
+ g_object_unref (self);
priv->thread = NULL;
priv->is_running = FALSE;
@@ -371,8 +413,8 @@
{
while (priv->creating_spin);
priv->creating_spin = TRUE;
- priv->thread = g_thread_create (thread_main,
- g_object_ref (self), TRUE, NULL);
+ g_object_ref (self);
+ priv->thread = g_thread_create (thread_main, self, TRUE, NULL);
}
return;
@@ -391,6 +433,8 @@
if (priv->thread)
g_thread_join (priv->thread);
+
+ return;
}
static void
Index: libtinymail-camel/tny-camel-store-account-priv.h
===================================================================
--- libtinymail-camel/tny-camel-store-account-priv.h (revision 2551)
+++ libtinymail-camel/tny-camel-store-account-priv.h (working copy)
@@ -35,7 +35,7 @@
GList *managed_folders;
TnyList *sobservers;
gboolean cant_reuse_iter;
- GStaticRecMutex *factory_lock;
+ GStaticRecMutex *factory_lock, *obs_lock;
TnyCamelQueue *queue, *msg_queue;
};
Index: libtinymail-camel/tny-session-camel.c
===================================================================
--- libtinymail-camel/tny-session-camel.c (revision 2551)
+++ libtinymail-camel/tny-session-camel.c (working copy)
@@ -719,7 +719,33 @@
return;
}
+typedef struct {
+ TnySessionCamel *self;
+ TnyAccount *account;
+ gboolean online;
+} SetOnlHapInfo;
+static gboolean
+set_online_happened_idle (gpointer user_data)
+{
+ SetOnlHapInfo *info = (SetOnlHapInfo *) user_data;
+ tny_lockable_lock (info->self->priv->ui_lock);
+ g_signal_emit (info->account,
+ tny_camel_account_signals [TNY_CAMEL_ACCOUNT_SET_ONLINE_HAPPENED],
+ 0, info->online);
+ tny_lockable_unlock (info->self->priv->ui_lock);
+ return FALSE;
+}
+
+static void
+set_online_happened_destroy (gpointer user_data)
+{
+ SetOnlHapInfo *info = (SetOnlHapInfo *) user_data;
+ camel_object_unref (info->self);
+ g_object_unref (info->account);
+ g_slice_free (SetOnlHapInfo, info);
+}
+
static void
tny_session_queue_going_online_for_account (TnySessionCamel *self, TnyCamelAccount *account, gboolean online)
{
@@ -741,8 +767,16 @@
if (TNY_IS_CAMEL_TRANSPORT_ACCOUNT (account))
{
- g_signal_emit (account,
- tny_camel_account_signals [TNY_CAMEL_ACCOUNT_SET_ONLINE_HAPPENED], 0, online);
+ SetOnlHapInfo *info = g_slice_new (SetOnlHapInfo);
+
+ info->self = self;
+ camel_object_ref (info->self);
+ info->account = TNY_ACCOUNT (g_object_ref (account));
+ info->online = online;
+
+ g_idle_add_full (G_PRIORITY_DEFAULT, set_online_happened_idle,
+ info, set_online_happened_destroy);
+
return;
}
}
Index: libtinymail-camel/tny-camel-store-account.c
===================================================================
--- libtinymail-camel/tny-camel-store-account.c (revision 2551)
+++ libtinymail-camel/tny-camel-store-account.c (working copy)
@@ -69,35 +69,84 @@
char *strcasestr(const char *haystack, const char *needle);
+typedef struct {
+ GObject *self;
+ GObject *change;
+} NotFolObInIdleInfo;
+
+static void
+do_notify_in_idle_destroy (gpointer user_data)
+{
+ NotFolObInIdleInfo *info = (NotFolObInIdleInfo *) info;
+ g_object_unref (info->self);
+ g_object_unref (info->change);
+ g_slice_free (NotFolObInIdleInfo, info);
+}
+
static void
notify_folder_store_observers_about (TnyFolderStore *self, TnyFolderStoreChange *change)
{
TnyCamelStoreAccountPriv *priv = TNY_CAMEL_STORE_ACCOUNT_GET_PRIVATE (self);
- TnyIterator *iter;
+ TnyCamelAccountPriv *apriv = TNY_CAMEL_ACCOUNT_GET_PRIVATE (self);
- if (!priv->sobservers)
+ TnyIterator *iter = NULL;
+
+ TnyList *list = NULL;
+
+ g_static_rec_mutex_lock (priv->obs_lock);
+ if (!priv->sobservers) {
+ g_static_rec_mutex_unlock (priv->obs_lock);
return;
+ }
+ list = tny_list_copy (priv->sobservers);
+ g_static_rec_mutex_unlock (priv->obs_lock);
- iter = tny_list_create_iterator (priv->sobservers);
+ iter = tny_list_create_iterator (list);
while (!tny_iterator_is_done (iter))
{
TnyFolderStoreObserver *observer = TNY_FOLDER_STORE_OBSERVER (tny_iterator_get_current (iter));
+ tny_lockable_lock (apriv->session->priv->ui_lock);
tny_folder_store_observer_update (observer, change);
+ tny_lockable_unlock (apriv->session->priv->ui_lock);
g_object_unref (observer);
tny_iterator_next (iter);
}
g_object_unref (iter);
+ g_object_unref (list);
+
+ return;
}
+static gboolean
+notify_folder_store_observers_about_idle (gpointer user_data)
+{
+ NotFolObInIdleInfo *info = (NotFolObInIdleInfo *) info;
+ notify_folder_store_observers_about (TNY_FOLDER_STORE (info->self),
+ TNY_FOLDER_STORE_CHANGE (info->change));
+ return FALSE;
+}
+
+static void
+notify_folder_store_observers_about_in_idle (TnyFolderStore *self, TnyFolderStoreChange *change)
+{
+ NotFolObInIdleInfo *info = g_slice_new (NotFolObInIdleInfo);
+ info->self = g_object_ref (self);
+ info->change = g_object_ref (change);
+ g_idle_add_full (G_PRIORITY_HIGH, notify_folder_store_observers_about_idle,
+ info, do_notify_in_idle_destroy);
+}
+
static gboolean
connection_status_idle (gpointer data)
{
TnyAccount *self = (TnyAccount *) data;
TnyCamelAccountPriv *apriv = TNY_CAMEL_ACCOUNT_GET_PRIVATE (self);
+ tny_lockable_lock (apriv->session->priv->ui_lock);
g_signal_emit (G_OBJECT (self),
tny_account_signals [TNY_ACCOUNT_CONNECTION_STATUS_CHANGED],
0, apriv->status);
+ tny_lockable_unlock (apriv->session->priv->ui_lock);
return FALSE;
}
@@ -434,7 +483,37 @@
* subscribe parameter is TRUE, then we're asking for a folder
* subscription, else for a folder unsubscription */
+typedef struct {
+ TnySessionCamel *session;
+ GObject *self, *folder;
+} SetSubsInfo;
+
+static gboolean
+set_subscription_idle (gpointer user_data)
+{
+ SetSubsInfo *info = (SetSubsInfo *) user_data;
+
+ tny_lockable_lock (info->session->priv->ui_lock);
+ g_signal_emit (info->self,
+ tny_store_account_signals [TNY_STORE_ACCOUNT_SUBSCRIPTION_CHANGED],
+ 0, info->folder);
+ tny_lockable_unlock (info->session->priv->ui_lock);
+
+ return FALSE;
+}
+
static void
+set_subscription_destroy (gpointer user_data)
+{
+ SetSubsInfo *info = (SetSubsInfo *) user_data;
+ g_object_unref (info->self);
+ g_object_unref (info->folder);
+ camel_object_unref (info->session);
+ g_slice_free (SetSubsInfo, info);
+ return;
+}
+
+static void
set_subscription (TnyStoreAccount *self, TnyFolder *folder, gboolean subscribe)
{
TnyCamelAccountPriv *apriv;
@@ -484,17 +563,24 @@
camel_exception_clear (&ex);
} else
{
+ SetSubsInfo *info = g_slice_new (SetSubsInfo);
+
/* Sync */
_tny_camel_folder_set_subscribed (TNY_CAMEL_FOLDER (folder), subscribe);
-
- g_signal_emit (self,
- tny_store_account_signals [TNY_STORE_ACCOUNT_SUBSCRIPTION_CHANGED],
- 0, folder);
+
+ info->session = apriv->session;
+ camel_object_ref (info->session);
+ info->self = g_object_ref (self);
+ info->folder = g_object_ref (folder);
+
+ g_idle_add_full (G_PRIORITY_DEFAULT, set_subscription_idle, info,
+ set_subscription_destroy);
+
}
- camel_object_unref (CAMEL_OBJECT (cfolder));
+ camel_object_unref (cfolder);
cleanup:
- camel_object_unref (CAMEL_OBJECT (store));
+ camel_object_unref (store);
}
static void
@@ -546,6 +632,8 @@
priv->cant_reuse_iter = TRUE;
priv->factory_lock = g_new0 (GStaticRecMutex, 1);
g_static_rec_mutex_init (priv->factory_lock);
+ priv->obs_lock = g_new0 (GStaticRecMutex, 1);
+ g_static_rec_mutex_init (priv->obs_lock);
return;
}
@@ -584,6 +672,8 @@
g_static_rec_mutex_free (priv->factory_lock);
priv->factory_lock = NULL;
+ g_static_rec_mutex_free (priv->obs_lock);
+ priv->obs_lock = NULL;
g_object_unref (priv->queue);
g_object_unref (priv->msg_queue);
@@ -663,6 +753,8 @@
camel_exception_clear (&ex);
} else
{
+ TnyFolderStoreChange *change = NULL;
+
if (aspriv->iter)
{
/* Known memleak
@@ -673,11 +765,10 @@
if (camel_store_supports_subscriptions (store))
camel_store_unsubscribe_folder (store, cpriv->folder_name, &subex);
- TnyFolderStoreChange *change;
change = tny_folder_store_change_new (self);
tny_folder_store_change_add_removed_folder (change, folder);
- notify_folder_store_observers_about (self, change);
- g_object_unref (G_OBJECT (change));
+ notify_folder_store_observers_about_in_idle (self, change);
+ g_object_unref (change);
}
g_free (cpriv->folder_name);
@@ -887,8 +978,8 @@
change = tny_folder_store_change_new (self);
tny_folder_store_change_add_created_folder (change, folder);
notify_folder_store_observers_about (self, change);
- g_object_unref (G_OBJECT (change));
-
+ g_object_unref (change);
+
camel_object_unref (CAMEL_OBJECT (store));
_tny_session_stop_operation (apriv->session);
@@ -1118,8 +1209,11 @@
tny_camel_store_account_get_folders_async_callback (gpointer thr_user_data)
{
GetFoldersInfo *info = thr_user_data;
- if (info->callback)
+ if (info->callback) {
+ tny_lockable_lock (info->session->priv->ui_lock);
info->callback (info->self, info->list,&info->err, info->user_data);
+ tny_lockable_unlock (info->session->priv->ui_lock);
+ }
return FALSE;
}
@@ -1201,8 +1295,11 @@
tny_camel_store_account_get_folders_async_cancelled_callback (gpointer thr_user_data)
{
GetFoldersInfo *info = thr_user_data;
- if (info->callback)
+ if (info->callback) {
+ tny_lockable_lock (info->session->priv->ui_lock);
info->callback (info->self, info->list, &info->err, info->user_data);
+ tny_lockable_unlock (info->session->priv->ui_lock);
+ }
return FALSE;
}
Index: libtinymail-camel/tny-camel-account.c
===================================================================
--- libtinymail-camel/tny-camel-account.c (revision 2551)
+++ libtinymail-camel/tny-camel-account.c (working copy)
@@ -69,8 +69,10 @@
TnyAccount *self = (TnyAccount *) data;
TnyCamelAccountPriv *apriv = TNY_CAMEL_ACCOUNT_GET_PRIVATE (self);
+ tny_lockable_lock (apriv->session->priv->ui_lock);
g_signal_emit (G_OBJECT (self),
tny_account_signals [TNY_ACCOUNT_CHANGED], 0);
+ tny_lockable_unlock (apriv->session->priv->ui_lock);
return FALSE;
}
@@ -624,10 +626,11 @@
{
RefreshStatusInfo *oinfo = user_data;
TnyProgressInfo *info = NULL;
+ TnyCamelAccountPriv *apriv = TNY_CAMEL_ACCOUNT_GET_PRIVATE (oinfo->self);
info = tny_progress_info_new (G_OBJECT (oinfo->self), oinfo->status_callback,
oinfo->domain, oinfo->code, what, sofar,
- oftotal, oinfo->stopper, oinfo->user_data);
+ oftotal, oinfo->stopper, apriv->session->priv->ui_lock, oinfo->user_data);
if (oinfo->depth > 0)
{
@@ -1220,6 +1223,52 @@
* always happen in a thread. In fact, it will always happen in the operations
* queue of @self (else it's a bug). */
+typedef struct {
+ TnySessionCamel *session;
+ TnyAccount *account;
+ gboolean online;
+} SetOnlInfo;
+
+
+static gboolean
+set_online_happened_idle (gpointer user_data)
+{
+ SetOnlInfo *info = (SetOnlInfo *) user_data;
+ tny_lockable_lock (info->session->priv->ui_lock);
+ g_signal_emit (info->account,
+ tny_camel_account_signals [TNY_CAMEL_ACCOUNT_SET_ONLINE_HAPPENED],
+ 0, info->online);
+ tny_lockable_unlock (info->session->priv->ui_lock);
+ return FALSE;
+}
+
+static void
+set_online_happened_destroy (gpointer user_data)
+{
+ SetOnlInfo *info = (SetOnlInfo *) user_data;
+ camel_object_unref (info->session);
+ g_object_unref (info->account);
+ g_slice_free (SetOnlInfo, info);
+ return;
+}
+
+static void
+set_online_happened (TnySessionCamel *session, TnyCamelAccount *account, gboolean online)
+{
+ SetOnlInfo *info = g_slice_new (SetOnlInfo);
+
+ info->session = session;
+ camel_object_ref (info->session);
+ info->account = TNY_ACCOUNT (g_object_ref (account));
+ info->online = online;
+
+ g_idle_add_full (G_PRIORITY_DEFAULT, set_online_happened_idle,
+ info, set_online_happened_destroy);
+
+ return;
+}
+
+
void
_tny_camel_account_set_online (TnyCamelAccount *self, gboolean online, GError **err)
{
@@ -1268,8 +1317,7 @@
}
if (!camel_exception_is_set (&ex))
- g_signal_emit (self,
- tny_camel_account_signals [TNY_CAMEL_ACCOUNT_SET_ONLINE_HAPPENED], 0, TRUE);
+ set_online_happened (priv->session, self, TRUE);
goto done;
@@ -1308,8 +1356,7 @@
}
if (!camel_exception_is_set (&ex))
- g_signal_emit (self,
- tny_camel_account_signals [TNY_CAMEL_ACCOUNT_SET_ONLINE_HAPPENED], 0, TRUE);
+ set_online_happened (priv->session, self, TRUE);
goto done;
} else {
@@ -1345,8 +1392,7 @@
}
if (!camel_exception_is_set (&ex))
- g_signal_emit (self,
- tny_camel_account_signals [TNY_CAMEL_ACCOUNT_SET_ONLINE_HAPPENED], 0, FALSE);
+ set_online_happened (priv->session, self, FALSE);
}
@@ -1403,8 +1449,14 @@
on_set_online_done_idle_func (gpointer data)
{
OnSetOnlineInfo *info = (OnSetOnlineInfo *) data;
- if (info->callback)
+ TnyCamelAccountPriv *apriv = TNY_CAMEL_ACCOUNT_GET_PRIVATE (info->account);
+ TnySessionCamel *session = apriv->session;
+
+ if (info->callback) {
+ tny_lockable_lock (session->priv->ui_lock);
info->callback (info->account, info->err);
+ tny_lockable_unlock (session->priv->ui_lock);
+ }
return FALSE;
}
@@ -1492,19 +1544,16 @@
void
tny_camel_account_set_online_default (TnyCamelAccount *self, gboolean online, TnyCamelSetOnlineCallback callback)
{
+ TnyCamelAccountPriv *priv = TNY_CAMEL_ACCOUNT_GET_PRIVATE (self);
+ TnySessionCamel *session = priv->session;
/* In case we are a store account, this means that we need to throw the
* request to go online to the account's queue. */
if (TNY_IS_CAMEL_STORE_ACCOUNT (self))
- {
- TnyCamelAccountPriv *priv = TNY_CAMEL_ACCOUNT_GET_PRIVATE (self);
- TnySessionCamel *session = priv->session;
-
_tny_camel_store_account_queue_going_online (
TNY_CAMEL_STORE_ACCOUNT (self), session, online,
on_set_online_done, (gpointer) callback);
- }
/* Else, if it's a transport account, we don't have any transport
@@ -1513,11 +1562,7 @@
* current implementations will automatically connect themselves. */
if (TNY_IS_CAMEL_TRANSPORT_ACCOUNT (self))
- {
- g_signal_emit (self,
- tny_camel_account_signals [TNY_CAMEL_ACCOUNT_SET_ONLINE_HAPPENED], 0, online);
- return;
- }
+ set_online_happened (session, self, online);
}
static gboolean
@@ -1774,13 +1819,55 @@
gpointer user_data;
gboolean cancelled;
TnyList *result;
- /* This stops us from calling a status callback after the operation has
- * finished. */
TnyIdleStopper* stopper;
GError *err;
TnySessionCamel *session;
+
+ GCond* condition;
+ gboolean had_callback;
+ GMutex *mutex;
+
} GetSupportedAuthInfo;
+
+static gboolean
+on_supauth_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, info->cancelled, info->result, &info->err, info->user_data);
+ tny_lockable_unlock (info->session->priv->ui_lock);
+ }
+
+ tny_idle_stopper_stop (info->stopper);
+}
+
+static void
+on_supauth_destroy_func (gpointer user_data)
+{
+ GetSupportedAuthInfo *info = (GetSupportedAuthInfo *) user_data;
+
+ /* Thread reference */
+ g_object_unref (info->self);
+ camel_object_ref (info->session);
+
+ /* Result reference */
+ if (info->result)
+ g_object_unref (info->result);
+
+ 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);
+ }
+}
+
/* Starts the operation in the thread: */
static gpointer
tny_camel_account_get_supported_secure_authentication_async_thread (
@@ -1792,6 +1879,9 @@
CamelException ex = CAMEL_EXCEPTION_INITIALISER;
GError *err = NULL;
TnyStatus* status;
+ GList *authtypes = NULL;
+ TnyList *result = NULL;
+ GList *iter = NULL;
g_static_rec_mutex_lock (priv->service_lock);
@@ -1799,47 +1889,26 @@
TNY_GET_SUPPORTED_SECURE_AUTH_STATUS_GET_SECURE_AUTH, 0, 1,
"Get secure authentication methods");
- info->status_callback(G_OBJECT(self),
- status, info->user_data);
-
- /* Do the actual work:
- * This is happening in a thread,
- * and the status callback is being called regularly while this is
- * happening. */
- GList *authtypes = camel_service_query_auth_types (priv->service, &ex);
+ authtypes = camel_service_query_auth_types (priv->service, &ex);
+ /* Result reference */
+ result = tny_simple_list_new ();
+ iter = authtypes;
- tny_status_set_fraction(status, 1);
- info->status_callback(G_OBJECT(self),
- status, info->user_data);
-
- /* The result will be a TnyList of TnyPairs: */
- TnyList *result = tny_simple_list_new ();
- GList *iter = authtypes;
- while (iter) {
+ while (iter)
+ {
CamelServiceAuthType *item = (CamelServiceAuthType *)iter->data;
if (item) {
- /* Get the name of the auth method:
- * Note that, at least for IMAP, authproto=NULL when
- * name=Password. */
-
- /* We don't use the value part of the TnyPair. */
TnyPair *pair = tny_pair_new (item->name, NULL);
tny_list_append (result, G_OBJECT (pair));
g_object_unref (pair);
}
-
iter = g_list_next (iter);
}
+
g_list_free (authtypes);
authtypes = NULL;
-
-
- /* The work has finished, so clean up and provide the result via the
- * main callback: */
info->result = result;
- /* Create the GError if necessary,
- * from the CamelException: */
info->err = NULL;
if (camel_exception_is_set (&ex))
{
@@ -1852,26 +1921,31 @@
g_static_rec_mutex_unlock (priv->service_lock);
- /* Call the callback, with the result, in an idle thread,
- * and stop this thread: */
- if (info->callback) {
- info->callback (info->self, info->cancelled, info->result, &info->err, info->user_data);
- } else {
- /* Thread reference */
- g_object_unref (G_OBJECT (self));
- }
+ 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);
+
+ g_slice_free (GetSupportedAuthInfo, info);
+
tny_status_free(status);
- g_thread_exit (NULL);
return NULL;
}
-/*TODO: This should be a vfunc so that it is generally available
- * (and implementable) for other imlpementations. But this should not need a
- * TnyAccount instance, so we need to find some other object to put the vfunc.
- */
-
/**
* TnyCamelGetSupportedSecureAuthCallback:
* @self: The TnyCamelAccount on which tny_camel_account_get_supported_secure_authentication() was called.
@@ -1901,20 +1975,8 @@
{
TnyCamelAccountPriv *priv = TNY_CAMEL_ACCOUNT_GET_PRIVATE (self);
GetSupportedAuthInfo *info = NULL;
+ GError *err = NULL;
- g_return_if_fail (callback);
- g_return_if_fail (priv->session);
-
- /* Store all the interesting info in a struct
- * launch a thread and keep that struct-instance around.
- * - While the thread is running, we regularly call the status callback in
- * an idle handler.
- * - When the thread is finished, the main callback will
- * then be called in an idle handler.
- */
-
- /* Check that the session is ready, and stop with a GError if it is not: */
- GError *err = NULL;
if (!_tny_session_check_operation (priv->session, TNY_ACCOUNT (self), &err,
TNY_ACCOUNT_ERROR, TNY_ACCOUNT_ERROR_GET_SUPPORTED_AUTH))
{
@@ -1924,8 +1986,6 @@
return;
}
-
- /* Idle info for the status callback: */
info = g_slice_new (GetSupportedAuthInfo);
info->session = priv->session;
info->err = NULL;
@@ -1935,22 +1995,22 @@
info->status_callback = status_callback;
info->user_data = user_data;
- /* 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.
- * A shared copy is taken and released by the _tny_progress* callback,
- * so that it can prevent the stats callback from being called after
- * the main callback. */
info->stopper = tny_idle_stopper_new();
/* thread reference */
- g_object_ref (G_OBJECT (self));
+ g_object_ref (self);
+ camel_object_ref (info->session);
- /* This will cause the idle status callback to be called,
- * via _tny_camel_account_start_camel_operation,
- * and also calls the idle main callback: */
- g_thread_create (tny_camel_account_get_supported_secure_authentication_async_thread,
- info, FALSE, NULL);
+ if (TNY_IS_CAMEL_STORE_ACCOUNT (self))
+ {
+ TnyCamelStoreAccountPriv *aspriv = TNY_CAMEL_STORE_ACCOUNT_GET_PRIVATE (self);
+ _tny_camel_queue_launch (aspriv->queue,
+ tny_camel_account_get_supported_secure_authentication_async_thread, info,
+ __FUNCTION__);
+ } else {
+ g_thread_create (tny_camel_account_get_supported_secure_authentication_async_thread,
+ info, FALSE, NULL);
+ }
}
Index: libtinymailui-gtk/tny-gtk-folder-store-tree-model.c
===================================================================
--- libtinymailui-gtk/tny-gtk-folder-store-tree-model.c (revision 2551)
+++ libtinymailui-gtk/tny-gtk-folder-store-tree-model.c (working copy)
@@ -827,75 +827,54 @@
return FALSE;
}
-typedef struct {
- TnyFolderObserver *self;
- TnyFolderChange *change;
-} FolObsUpInfo;
-static gboolean
-folder_obsr_update_idle (gpointer user_data)
+
+static void
+tny_gtk_folder_store_tree_model_folder_obsr_update (TnyFolderObserver *self, TnyFolderChange *change)
{
- FolObsUpInfo *info = user_data;
- TnyFolderObserver *self = info->self;
- TnyFolderChange *change = info->change;
TnyFolderChangeChanged changed = tny_folder_change_get_changed (change);
- GtkTreeModel *model = GTK_TREE_MODEL (self);
+ GtkTreeModel *model = (GtkTreeModel *) self;
if (changed & TNY_FOLDER_CHANGE_CHANGED_FOLDER_RENAME ||
changed & TNY_FOLDER_CHANGE_CHANGED_ALL_COUNT ||
changed & TNY_FOLDER_CHANGE_CHANGED_UNREAD_COUNT)
{
- gdk_threads_enter ();
gtk_tree_model_foreach (model, updater, change);
- gdk_threads_leave ();
}
- return FALSE;
-}
-static void
-folder_obsr_update_idle_destroy (gpointer user_data)
-{
- FolObsUpInfo *info = user_data;
- TnyFolderObserver *self = info->self;
- TnyFolderChange *change = info->change;
-
- g_object_unref (self);
- g_object_unref (change);
- g_slice_free (FolObsUpInfo, info);
-}
-
-static void
-tny_gtk_folder_store_tree_model_folder_obsr_update (TnyFolderObserver *self, TnyFolderChange *change)
-{
- FolObsUpInfo *info = g_slice_new (FolObsUpInfo);
- info->self = TNY_FOLDER_OBSERVER (g_object_ref (self));
- info->change = TNY_FOLDER_CHANGE (g_object_ref (change));
-
- g_idle_add_full (G_PRIORITY_DEFAULT_IDLE,
- folder_obsr_update_idle, info,
- folder_obsr_update_idle_destroy);
-
return;
}
-typedef struct {
- TnyFolderObserver *self;
- TnyFolderStoreChange *change;
-} FolStObsUpInfo;
-
-static gboolean
-folder_store_obsr_update_idle (gpointer user_data)
+static void
+tny_gtk_folder_store_tree_model_store_obsr_update (TnyFolderStoreObserver *self, TnyFolderStoreChange *change)
{
- FolStObsUpInfo *info = user_data;
- TnyFolderObserver *self = info->self;
- TnyFolderStoreChange *change = info->change;
TnyFolderStoreChangeChanged changed = tny_folder_store_change_get_changed (change);
GtkTreeModel *model = GTK_TREE_MODEL (self);
TnyGtkFolderStoreTreeModel *me = (TnyGtkFolderStoreTreeModel*) self;
if (changed & TNY_FOLDER_STORE_CHANGE_CHANGED_CREATED_FOLDERS)
{
+ TnyList *created = tny_simple_list_new ();
+ TnyIterator *miter;
+
+ tny_folder_store_change_get_created_folders (change, created);
+ miter = tny_list_create_iterator (created);
+
+ while (!tny_iterator_is_done (miter))
+ {
+ TnyFolder *folder = TNY_FOLDER (tny_iterator_get_current (miter));
+ tny_folder_add_observer (TNY_FOLDER (folder), TNY_FOLDER_OBSERVER (self));
+ tny_folder_store_add_observer (TNY_FOLDER_STORE (folder), TNY_FOLDER_STORE_OBSERVER (self));
+ g_object_unref (folder);
+ tny_iterator_next (miter);
+ }
+ g_object_unref (miter);
+ g_object_unref (created);
+ }
+
+ if (changed & TNY_FOLDER_STORE_CHANGE_CHANGED_CREATED_FOLDERS)
+ {
TnyFolderStore *parentstore = tny_folder_store_change_get_folder_store (change);
GtkTreeIter first, iter;
@@ -913,11 +892,6 @@
GtkTreeIter newiter;
TnyFolder *folder = TNY_FOLDER (tny_iterator_get_current (miter));
- /* See early added below! (#CCUX)
-
- tny_folder_add_observer (TNY_FOLDER (folder), TNY_FOLDER_OBSERVER (self));
- tny_folder_store_add_observer (TNY_FOLDER_STORE (folder), TNY_FOLDER_STORE_OBSERVER (self));*/
-
me->folder_observables = g_list_prepend (me->folder_observables, folder);
me->store_observables = g_list_prepend (me->store_observables, folder);
@@ -968,64 +942,6 @@
}
- return FALSE;
-}
-
-static void
-folder_store_obsr_update_idle_destroy (gpointer user_data)
-{
- FolStObsUpInfo *info = user_data;
- TnyFolderObserver *self = info->self;
- TnyFolderStoreChange *change = info->change;
-
- g_object_unref (self);
- g_object_unref (change);
-
- g_slice_free (FolStObsUpInfo, info);
-}
-
-static void
-tny_gtk_folder_store_tree_model_store_obsr_update (TnyFolderStoreObserver *self, TnyFolderStoreChange *change)
-{
- TnyFolderStoreChangeChanged changed = tny_folder_store_change_get_changed (change);
- FolStObsUpInfo *info = g_slice_new (FolStObsUpInfo);
- info->self = TNY_FOLDER_OBSERVER (g_object_ref (self));
- info->change = TNY_FOLDER_STORE_CHANGE (g_object_ref (change));
-
- if (changed & TNY_FOLDER_STORE_CHANGE_CHANGED_CREATED_FOLDERS)
- {
- TnyList *created = tny_simple_list_new ();
- TnyIterator *miter;
-
- tny_folder_store_change_get_created_folders (change, created);
- miter = tny_list_create_iterator (created);
-
- while (!tny_iterator_is_done (miter))
- {
- TnyFolder *folder = TNY_FOLDER (tny_iterator_get_current (miter));
-
- /* Already added! (#CCUX)
- * We can't add these in the idle because the thread might
- * be added subfolders right now! (the idle would register
- * self as an observer too late!)
- * Question. though: is there any reason why not to do the
- * doubly-linked lists here too? (except for locking, which
- * would then be necessary of course) */
-
- tny_folder_add_observer (TNY_FOLDER (folder), TNY_FOLDER_OBSERVER (self));
- tny_folder_store_add_observer (TNY_FOLDER_STORE (folder), TNY_FOLDER_STORE_OBSERVER (self));
-
- g_object_unref (folder);
- tny_iterator_next (miter);
- }
- g_object_unref (miter);
- g_object_unref (created);
- }
-
- g_idle_add_full (G_PRIORITY_DEFAULT_IDLE,
- folder_store_obsr_update_idle, info,
- folder_store_obsr_update_idle_destroy);
-
return;
}
Index: tests/shared/device.c
===================================================================
--- tests/shared/device.c (revision 2551)
+++ tests/shared/device.c (working copy)
@@ -73,7 +73,9 @@
static void
tny_test_device_on_online (TnyDevice *self)
{
+ /* TNY TODO: tny_lockable_lock (ui_lock); */
g_signal_emit (self, tny_device_signals [TNY_DEVICE_CONNECTION_CHANGED], 0, TRUE);
+ /* TNY TODO: tny_lockable_unlock (ui_lock); */
return;
}
@@ -81,7 +83,9 @@
static void
tny_test_device_on_offline (TnyDevice *self)
{
+ /* TNY TODO: tny_lockable_lock (ui_lock); */
g_signal_emit (self, tny_device_signals [TNY_DEVICE_CONNECTION_CHANGED], 0, FALSE);
+ /* TNY TODO: tny_lockable_unlock (ui_lock); */
return;
}
Index: libtinymail-maemo/tny-maemo-device.c
===================================================================
--- libtinymail-maemo/tny-maemo-device.c (revision 2551)
+++ libtinymail-maemo/tny-maemo-device.c (working copy)
@@ -1,4 +1,4 @@
-/* libtinymail-camel - The Tiny Mail base library for Camel
+/* libtinymail-maemo - The Tiny Mail base library for maemo
* Copyright (C) 2006-2007 Philip Van Hoof <pvanhoof gnome org>
*
* This library is free software; you can redistribute it and/or
@@ -25,39 +25,59 @@
static GObjectClass *parent_class = NULL;
+#include "tny-maemo-device-priv.h"
-typedef struct {
- gboolean fset, forced;
-} TnyMaemoDevicePriv;
-
-#define TNY_MAEMO_DEVICE_GET_PRIVATE(o) \
- (G_TYPE_INSTANCE_GET_PRIVATE ((o), TNY_TYPE_MAEMO_DEVICE, TnyMaemoDevicePriv))
-
-
static void tny_maemo_device_on_online (TnyDevice *self);
static void tny_maemo_device_on_offline (TnyDevice *self);
static gboolean tny_maemo_device_is_online (TnyDevice *self);
+static gboolean
+emit_status (TnyDevice *self)
+{
+ if (tny_maemo_device_is_online (self))
+ tny_maemo_device_on_online (self);
+ else
+ tny_maemo_device_on_offline (self);
+
+ return FALSE;
+}
+
static void
tny_maemo_device_reset (TnyDevice *self)
{
TnyMaemoDevicePriv *priv = TNY_MAEMO_DEVICE_GET_PRIVATE (self);
+ const gboolean status_before = tny_maemo_device_is_online (self);
+
priv->fset = FALSE;
priv->forced = FALSE;
+ /* Signal if it changed: */
+ if (status_before != tny_maemo_device_is_online (self))
+ g_idle_add_full (G_PRIORITY_DEFAULT,
+ (GSourceFunc) emit_status,
+ g_object_ref (self),
+ (GDestroyNotify) g_object_unref);
}
static void
tny_maemo_device_force_online (TnyDevice *self)
{
+
TnyMaemoDevicePriv *priv = TNY_MAEMO_DEVICE_GET_PRIVATE (self);
+ const gboolean already_online = tny_maemo_device_is_online (self);
+
priv->fset = TRUE;
priv->forced = TRUE;
- tny_maemo_device_on_online (self);
+ /* Signal if it changed: */
+ if (!already_online)
+ g_idle_add_full (G_PRIORITY_DEFAULT,
+ (GSourceFunc) emit_status,
+ g_object_ref (self),
+ (GDestroyNotify) g_object_unref);
return;
}
@@ -68,10 +88,17 @@
{
TnyMaemoDevicePriv *priv = TNY_MAEMO_DEVICE_GET_PRIVATE (self);
+ const gboolean already_offline = !tny_maemo_device_is_online (self);
+
priv->fset = TRUE;
priv->forced = FALSE;
- tny_maemo_device_on_offline (self);
+ /* Signal if it changed: */
+ if (!already_offline)
+ g_idle_add_full (G_PRIORITY_DEFAULT,
+ (GSourceFunc) emit_status,
+ g_object_ref (self),
+ (GDestroyNotify) g_object_unref);
return;
}
@@ -79,7 +106,9 @@
static void
tny_maemo_device_on_online (TnyDevice *self)
{
+ gdk_threads_enter ();
g_signal_emit (self, tny_device_signals [TNY_DEVICE_CONNECTION_CHANGED], 0, TRUE);
+ gdk_threads_leave ();
return;
}
@@ -87,7 +116,9 @@
static void
tny_maemo_device_on_offline (TnyDevice *self)
{
+ gdk_threads_enter ();
g_signal_emit (self, tny_device_signals [TNY_DEVICE_CONNECTION_CHANGED], 0, FALSE);
+ gdk_threads_leave ();
return;
}
@@ -117,14 +148,13 @@
/**
* tny_maemo_device_new:
*
- * Return value: A new #TnyDevice instance
+ * Return value: A new #TnyDevice implemented for MAEMO
**/
TnyDevice*
tny_maemo_device_new (void)
{
TnyMaemoDevice *self = g_object_new (TNY_TYPE_MAEMO_DEVICE, NULL);
-
return TNY_DEVICE (self);
}
@@ -132,6 +162,9 @@
static void
tny_maemo_device_finalize (GObject *object)
{
+ TnyMaemoDevice *self = (TnyMaemoDevice *) object;
+ TnyMaemoDevicePriv *priv = TNY_MAEMO_DEVICE_GET_PRIVATE (self);
+
(*parent_class->finalize) (object);
return;
@@ -206,3 +239,4 @@
return type;
}
+
Index: libtinymail-maemo/tny-maemo-conic-device.c
===================================================================
--- libtinymail-maemo/tny-maemo-conic-device.c (revision 2551)
+++ libtinymail-maemo/tny-maemo-conic-device.c (working copy)
@@ -77,7 +77,48 @@
(G_TYPE_INSTANCE_GET_PRIVATE ((o), TNY_TYPE_MAEMO_CONIC_DEVICE, TnyMaemoConicDevicePriv))
+typedef struct {
+ GObject *self;
+ gboolean status;
+} EmitStatusInfo;
+
+static gboolean
+conic_emit_status_idle (gpointer user_data)
+{
+ EmitStatusInfo *info = (EmitStatusInfo *) user_data;
+
+ gdk_threads_enter ();
+ g_signal_emit (info->self, tny_device_signals [TNY_DEVICE_CONNECTION_CHANGED],
+ 0, self->status);
+ gdk_threads_leave ();
+
+ return FALSE;
+}
+
+static void
+conic_emit_status_destroy (gpointer user_data)
+{
+ EmitStatusInfo *info = (EmitStatusInfo *) user_data;
+ g_object_unref (info->self);
+ g_slice_free (EmitStatusInfo, info);
+ return;
+}
+
static void
+conic_emit_status (TnyDevice *self, gboolean status)
+{
+ EmitStatusInfo *info = g_slice_new (EmitStatusInfo);
+
+ info->self = g_object_ref (self);
+ info->status = status;
+
+ g_idle_add_full (G_PRIORITY_DEFAULT, conic_emit_status_idle,
+ info, conic_emit_status_destroy);
+
+ return;
+}
+
+static void
tny_maemo_conic_device_reset (TnyDevice *device)
{
TnyMaemoConicDevice *self;
@@ -91,8 +132,7 @@
priv->forced = FALSE;
if (status_before != tny_maemo_conic_device_is_online (device))
- g_signal_emit (device, tny_device_signals [TNY_DEVICE_CONNECTION_CHANGED],
- 0, !status_before);
+ conic_emit_status (device, !status_before);
}
static void
@@ -170,8 +210,9 @@
priv->forced = FALSE; /* is_online is now accurate. */
g_message ("DEBUG: %s: emitting signal CONNECTION_CHANGED: %s",
__FUNCTION__, is_online ? "online" : "offline");
- g_signal_emit (device, tny_device_signals [TNY_DEVICE_CONNECTION_CHANGED],
- 0, is_online);
+
+ conic_emit_status (device, is_online);
+
}
#ifdef MAEMO_CONIC_DUMMY
@@ -186,7 +227,8 @@
return filename;
}
-static gboolean dummy_con_ic_connection_connect_by_id (TnyMaemoConicDevice *self, const gchar* iap_id)
+static gboolean
+dummy_con_ic_connection_connect_by_id (TnyMaemoConicDevice *self, const gchar* iap_id)
{
/* Show a dialog, because libconic would show a dialog here,
* and give the user a chance to refuse a new connection, because libconic would allow that too.
@@ -223,7 +265,8 @@
}
#endif /* MAEMO_CONIC_DUMMY */
-
+
+
/**
* tny_maemo_conic_device_connect:
* @self: a #TnyDevice object
@@ -248,12 +291,12 @@
g_return_val_if_fail (TNY_IS_DEVICE(self), FALSE);
priv = TNY_MAEMO_CONIC_DEVICE_GET_PRIVATE (self);
-
+
g_return_val_if_fail (priv->cnx, FALSE);
g_message (__FUNCTION__);
g_message ("connecting to %s", iap_id ? iap_id : "<any>");
-
+
priv->loop = g_main_loop_new(NULL, FALSE /* not running immediately. */);
gboolean request_failed = FALSE;
@@ -311,10 +354,9 @@
g_return_val_if_fail (TNY_IS_MAEMO_CONIC_DEVICE(self), FALSE);
- priv = TNY_MAEMO_CONIC_DEVICE_GET_PRIVATE (self);
+ priv = TNY_MAEMO_CONIC_DEVICE_GET_PRIVATE (self);
g_return_val_if_fail (priv->cnx, FALSE);
-
g_message (__FUNCTION__);
g_message ("disconnecting from %s", iap_id ? iap_id : "<any>");
@@ -341,14 +383,13 @@
{
TnyMaemoConicDevice *self = TNY_MAEMO_CONIC_DEVICE (user_data);
TnyMaemoConicDevicePriv *priv = TNY_MAEMO_CONIC_DEVICE_GET_PRIVATE (self);
-
/* Check whether the enviroment variable has changed,
* so we can fake a connection change: */
gchar *filename = get_dummy_filename ();
-
gchar *contents = 0;
GError* error = 0;
gboolean test = g_file_get_contents (filename, &contents, NULL, &error);
+
if(error) {
/* printf("%s: error from g_file_get_contents(): %s\n", __FUNCTION__, error->message); */
g_error_free (error);
@@ -382,8 +423,9 @@
}
printf ("DEBUG1: %s: emitting is_online=%d\n", __FUNCTION__, priv->is_online);
- g_signal_emit (self, tny_device_signals [TNY_DEVICE_CONNECTION_CHANGED],
- 0, priv->is_online);
+
+ conic_emit_status (self, priv->is_online);
+
}
g_free (contents);
@@ -404,20 +446,21 @@
**/
const gchar*
tny_maemo_conic_device_get_current_iap_id (TnyMaemoConicDevice *self)
-{
+{
+ TnyMaemoConicDevicePriv *priv = NULL;
+
g_return_val_if_fail (TNY_IS_MAEMO_CONIC_DEVICE(self), NULL);
g_return_val_if_fail (tny_maemo_conic_device_is_online(TNY_DEVICE(self)), NULL);
- TnyMaemoConicDevicePriv *priv = TNY_MAEMO_CONIC_DEVICE_GET_PRIVATE (self);
-
+ priv = TNY_MAEMO_CONIC_DEVICE_GET_PRIVATE (self);
+
#ifdef MAEMO_CONIC_DUMMY
on_dummy_connection_check (self);
-
/* Handle the special "none" text: */
if (priv->iap && (strcmp (priv->iap, MAEMO_CONIC_DUMMY_IAP_ID_NONE) == 0))
return NULL;
#endif
-
+
return priv->iap;
}
@@ -571,22 +614,19 @@
return;
#endif /*MAEMO_CONIC_DUMMY*/
-
-
const gboolean already_offline = !tny_maemo_conic_device_is_online (device);
priv->forced = TRUE;
/* Signal if it changed: */
if (!already_offline)
- g_signal_emit (device, tny_device_signals [TNY_DEVICE_CONNECTION_CHANGED],
- 0, FALSE);
+ conic_emit_status (device, FALSE);
}
static gboolean
tny_maemo_conic_device_is_online (TnyDevice *self)
{
- g_return_val_if_fail (TNY_IS_DEVICE(self), FALSE);
+ g_return_val_if_fail (TNY_IS_DEVICE(self), FALSE);
#ifdef MAEMO_CONIC_DUMMY
on_dummy_connection_check(self);
Index: libtinymailui-mozembed/tny-moz-embed-stream.c
===================================================================
--- libtinymailui-mozembed/tny-moz-embed-stream.c (revision 2551)
+++ libtinymailui-mozembed/tny-moz-embed-stream.c (working copy)
@@ -205,22 +205,6 @@
}
-/* Fire "children_changed::add" event to refresh "UI-Grab" window of GOK,
-* this event is not fired when using gtk_moz_embed_xxx_stream,
-* see Mozilla bug #293670. Done in a timeout to allow mozilla to
-* actually draw to the screen
-
-static gboolean
-timeout_update_gok (GtkMozEmbed *html)
-{
- GtkWidget *widget = gtk_widget_get_accessible (GTK_WIDGET (html));
-
- if (widget
- g_signal_emit_by_name (gtk_widget_get_accessible (GTK_WIDGET (html)),
- "children_changed::add", -1, NULL, NULL);
- return FALSE;
-} */
-
static gint
tny_moz_embed_stream_close (TnyStream *self)
{
Index: libtinymail-gnome-desktop/tny-gnome-device.c
===================================================================
--- libtinymail-gnome-desktop/tny-gnome-device.c (revision 2551)
+++ libtinymail-gnome-desktop/tny-gnome-device.c (working copy)
@@ -41,13 +41,15 @@
static void tny_gnome_device_on_offline (TnyDevice *self);
static gboolean tny_gnome_device_is_online (TnyDevice *self);
-static void
+static gboolean
emit_status (TnyDevice *self)
{
if (tny_gnome_device_is_online (self))
tny_gnome_device_on_online (self);
else
tny_gnome_device_on_offline (self);
+
+ return FALSE;
}
@@ -75,7 +77,12 @@
/* Signal if it changed: */
if (status_before != tny_gnome_device_is_online (self))
- emit_status (self);
+ g_idle_add_full (G_PRIORITY_DEFAULT,
+ (GSourceFunc) emit_status,
+ g_object_ref (self),
+ (GDestroyNotify) g_object_unref);
+
+ return;
}
static void
@@ -90,8 +97,11 @@
/* Signal if it changed: */
if (!already_online)
- emit_status (self);
-
+ g_idle_add_full (G_PRIORITY_DEFAULT,
+ (GSourceFunc) emit_status,
+ g_object_ref (self),
+ (GDestroyNotify) g_object_unref);
+
return;
}
@@ -108,15 +118,20 @@
/* Signal if it changed: */
if (!already_offline)
- emit_status (self);
-
+ g_idle_add_full (G_PRIORITY_DEFAULT,
+ (GSourceFunc) emit_status,
+ g_object_ref (self),
+ (GDestroyNotify) g_object_unref);
+
return;
}
static void
tny_gnome_device_on_online (TnyDevice *self)
{
+ gdk_threads_enter ();
g_signal_emit (self, tny_device_signals [TNY_DEVICE_CONNECTION_CHANGED], 0, TRUE);
+ gdk_threads_leave ();
return;
}
@@ -124,7 +139,9 @@
static void
tny_gnome_device_on_offline (TnyDevice *self)
{
+ gdk_threads_enter ();
g_signal_emit (self, tny_device_signals [TNY_DEVICE_CONNECTION_CHANGED], 0, FALSE);
+ gdk_threads_leave ();
return;
}
Index: libtinymail-olpc/tny-olpc-device.c
===================================================================
--- libtinymail-olpc/tny-olpc-device.c (revision 2551)
+++ libtinymail-olpc/tny-olpc-device.c (working copy)
@@ -1,4 +1,4 @@
-/* libtinymail-camel - The Tiny Mail base library for Camel
+/* libtinymail-olpc - The Tiny Mail base library for olpc
* Copyright (C) 2006-2007 Philip Van Hoof <pvanhoof gnome org>
*
* This library is free software; you can redistribute it and/or
@@ -32,13 +32,15 @@
static gboolean tny_olpc_device_is_online (TnyDevice *self);
-static void
+static gboolean
emit_status (TnyDevice *self)
{
if (tny_olpc_device_is_online (self))
tny_olpc_device_on_online (self);
else
tny_olpc_device_on_offline (self);
+
+ return FALSE;
}
static void
@@ -53,7 +55,10 @@
/* Signal if it changed: */
if (status_before != tny_olpc_device_is_online (self))
- emit_status (self);
+ g_idle_add_full (G_PRIORITY_DEFAULT,
+ (GSourceFunc) emit_status,
+ g_object_ref (self),
+ (GDestroyNotify) g_object_unref);
}
static void
@@ -69,8 +74,11 @@
/* Signal if it changed: */
if (!already_online)
- emit_status (self);
-
+ g_idle_add_full (G_PRIORITY_DEFAULT,
+ (GSourceFunc) emit_status,
+ g_object_ref (self),
+ (GDestroyNotify) g_object_unref);
+
return;
}
@@ -87,15 +95,20 @@
/* Signal if it changed: */
if (!already_offline)
- emit_status (self);
-
+ g_idle_add_full (G_PRIORITY_DEFAULT,
+ (GSourceFunc) emit_status,
+ g_object_ref (self),
+ (GDestroyNotify) g_object_unref);
+
return;
}
static void
tny_olpc_device_on_online (TnyDevice *self)
{
+ gdk_threads_enter ();
g_signal_emit (self, tny_device_signals [TNY_DEVICE_CONNECTION_CHANGED], 0, TRUE);
+ gdk_threads_leave ();
return;
}
@@ -103,7 +116,9 @@
static void
tny_olpc_device_on_offline (TnyDevice *self)
{
+ gdk_threads_enter ();
g_signal_emit (self, tny_device_signals [TNY_DEVICE_CONNECTION_CHANGED], 0, FALSE);
+ gdk_threads_leave ();
return;
}
@@ -123,7 +138,7 @@
static void
tny_olpc_device_instance_init (GTypeInstance *instance, gpointer g_class)
{
- TnyOlpcDevice *self = (TnyOlpcDevice *)instance;
+ TnyOlpcDevice *self = (TnyOlpcDevice *) instance;
TnyOlpcDevicePriv *priv = TNY_OLPC_DEVICE_GET_PRIVATE (self);
return;
@@ -147,7 +162,7 @@
static void
tny_olpc_device_finalize (GObject *object)
{
- TnyOlpcDevice *self = (TnyOlpcDevice *)object;
+ TnyOlpcDevice *self = (TnyOlpcDevice *) object;
TnyOlpcDevicePriv *priv = TNY_OLPC_DEVICE_GET_PRIVATE (self);
(*parent_class->finalize) (object);
Index: libtinymail/tny-combined-account.c
===================================================================
--- libtinymail/tny-combined-account.c (revision 2551)
+++ libtinymail/tny-combined-account.c (working copy)
@@ -361,8 +361,10 @@
{
GObject *self = user_data;
+ /* TNY TODO: tny_lockable_lock (ui_lock); */
g_signal_emit (self, tny_store_account_signals [TNY_STORE_ACCOUNT_SUBSCRIPTION_CHANGED],
0, folder);
+ /* TNY TODO: tny_lockable_unlock (ui_lock); */
}
/**
Index: libtinymail/tny-progress-info.c
===================================================================
--- libtinymail/tny-progress-info.c (revision 2551)
+++ libtinymail/tny-progress-info.c (working copy)
@@ -70,6 +70,7 @@
gint sofar;
gint oftotal;
TnyIdleStopper *stopper;
+ TnyLockable *ui_lock;
gpointer user_data;
};
@@ -96,7 +97,7 @@
* Return value: a #TnyProgressInfo instance that is ready to launch
**/
TnyProgressInfo*
-tny_progress_info_new (GObject *self, TnyStatusCallback status_callback, TnyStatusDomain domain, TnyStatusCode code, const gchar *what, gint sofar, gint oftotal, TnyIdleStopper* stopper, gpointer user_data)
+tny_progress_info_new (GObject *self, TnyStatusCallback status_callback, TnyStatusDomain domain, TnyStatusCode code, const gchar *what, gint sofar, gint oftotal, TnyIdleStopper* stopper, TnyLockable *ui_lock, gpointer user_data)
{
TnyProgressInfo *info = g_slice_new (TnyProgressInfo);
@@ -105,6 +106,7 @@
info->status_callback = status_callback;
info->what = g_strdup (what);
info->self = g_object_ref (self);
+ info->ui_lock = g_object_ref (ui_lock);
info->user_data = user_data;
info->oftotal = oftotal;
@@ -143,7 +145,8 @@
{
TnyProgressInfo *info = data;
- g_object_unref (G_OBJECT (info->self));
+ g_object_unref (info->self);
+ g_object_unref (info->ui_lock);
g_free (info->what);
tny_idle_stopper_destroy (info->stopper);
info->stopper = NULL;
@@ -185,8 +188,10 @@
info->code, info->sofar, info->oftotal,
info->what);
+ tny_lockable_lock (info->ui_lock);
info->status_callback (G_OBJECT (info->self), status,
info->user_data);
+ tny_lockable_unlock (info->ui_lock);
tny_status_free (status);
}
Index: libtinymail/tny-merge-folder.c
===================================================================
--- libtinymail/tny-merge-folder.c (revision 2551)
+++ libtinymail/tny-merge-folder.c (working copy)
@@ -63,7 +63,9 @@
while (!tny_iterator_is_done (iter))
{
TnyFolderObserver *observer = TNY_FOLDER_OBSERVER (tny_iterator_get_current (iter));
+ /* TNY TODO: tny_lockable_lock (ui_lock); */
tny_folder_observer_update (observer, change);
+ /* TNY TODO: tny_lockable_unlock (ui_lock); */
g_object_unref (G_OBJECT (observer));
tny_iterator_next (iter);
}
@@ -165,8 +167,11 @@
{
SyncFolderInfo *info = thr_user_data;
- if (info->callback)
+ if (info->callback) {
+ /* TNY TODO: tny_lockable_lock (ui_lock); */
info->callback (info->self, info->cancelled, &info->err, info->user_data);
+ /* TNY TODO: tny_lockable_unlock (ui_lock); */
+ }
return FALSE;
}
@@ -367,8 +372,13 @@
{
GetMsgInfo *info = (GetMsgInfo *) thr_user_data;
- if (info->callback) /* TODO: the cancelled field */
+ if (info->callback) {
+ /* TNY TODO: the cancelled field */
+
+ /* TNY TODO: tny_lockable_lock (ui_lock); */
info->callback (info->self, FALSE, info->msg, &info->err, info->user_data);
+ /* TNY TODO: tny_lockable_unlock (ui_lock); */
+ }
return FALSE;
}
@@ -472,8 +482,13 @@
get_headers_async_callback (gpointer thr_user_data)
{
GetHeadersFolderInfo *info = thr_user_data;
- if (info->callback)
+
+ if (info->callback) {
+ /* TNY TODO: tny_lockable_lock (ui_lock); */
info->callback (info->self, info->cancelled, info->headers, &info->err, info->user_data);
+ /* TNY TODO: tny_lockable_unlock (ui_lock); */
+ }
+
return FALSE;
}
@@ -832,10 +847,14 @@
{
RefreshFolderInfo *info = thr_user_data;
- if (info->callback)
+ if (info->callback) {
+ /* TNY TODO: tny_lockable_lock (ui_lock); */
info->callback (info->self, info->cancelled, &info->err, info->user_data);
+ /* TNY TODO: tny_lockable_unlock (ui_lock); */
+ }
- /* TODO: trigger this change notification
+ /* TNY TODO: trigger this change notification
+
if (info->oldlen != priv->cached_length || info->oldurlen != priv->unread_length)
{
TnyFolderChange *change = tny_folder_change_new (self);
@@ -1006,8 +1025,13 @@
{
TransferMsgsInfo *info = thr_user_data;
- if (info->callback) /* TODO: the cancelled field */
+ if (info->callback) {
+ /* TNY TODO: the cancelled field */
+
+ /* TNY TODO: tny_lockable_lock (ui_lock); */
info->callback (info->self, FALSE, &info->err, info->user_data);
+ /* TNY TODO: tny_lockable_unlock (ui_lock); */
+ }
return FALSE;
}
@@ -1516,9 +1540,7 @@
g_type_add_interface_static (type, TNY_TYPE_FOLDER_OBSERVER,
&tny_folder_observer_info);
-
}
-
return type;
}
Index: libtinymail/tny-common-priv.h
===================================================================
--- libtinymail/tny-common-priv.h (revision 2551)
+++ libtinymail/tny-common-priv.h (working copy)
@@ -23,6 +23,7 @@
#include <tny-shared.h>
#include <tny-status.h>
#include <tny-error.h>
+#include <tny-lockable.h>
#ifndef TINYMAIL_ENABLE_PRIVATE_API
#error "This is private API that should only be used by tinymail internally."
@@ -38,7 +39,7 @@
TnyIdleStopper* tny_idle_stopper_new (void);
TnyIdleStopper* tny_idle_stopper_copy (TnyIdleStopper *stopper);
-TnyProgressInfo* tny_progress_info_new (GObject *self, TnyStatusCallback status_callback, TnyStatusDomain domain, TnyStatusCode code, const gchar *what, gint sofar, gint oftotal, TnyIdleStopper* stopper, gpointer user_data);
+TnyProgressInfo* tny_progress_info_new (GObject *self, TnyStatusCallback status_callback, TnyStatusDomain domain, TnyStatusCode code, const gchar *what, gint sofar, gint oftotal, TnyIdleStopper* stopper, TnyLockable *uid_lock, gpointer user_data);
gboolean tny_progress_info_idle_func (gpointer data);
void tny_progress_info_destroy (gpointer data);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]