[evolution-data-server] EBackend: Update online state from the correct main loop context.
- From: Matthew Barnes <mbarnes src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-data-server] EBackend: Update online state from the correct main loop context.
- Date: Fri, 22 Feb 2013 15:22:21 +0000 (UTC)
commit a0e55108497390d8efd4d8b2b505ef1c9cb43081
Author: Matthew Barnes <mbarnes redhat com>
Date: Fri Feb 22 10:09:31 2013 -0500
EBackend: Update online state from the correct main loop context.
Use a low-priority idle callback on the backend's main loop context to
reduce the number of times we cancel g_network_monitor_can_reach_async().
libebackend/e-backend.c | 80 +++++++++++++++++++++++++++-------------------
1 files changed, 47 insertions(+), 33 deletions(-)
---
diff --git a/libebackend/e-backend.c b/libebackend/e-backend.c
index 608f4d2..23720eb 100644
--- a/libebackend/e-backend.c
+++ b/libebackend/e-backend.c
@@ -63,7 +63,9 @@ struct _EBackendPrivate {
GNetworkMonitor *network_monitor;
gulong network_changed_handler_id;
- guint network_changed_timeout_id;
+
+ GSource *update_online_state;
+ GMutex update_online_state_lock;
GMutex network_monitor_cancellable_lock;
GCancellable *network_monitor_cancellable;
@@ -151,20 +153,21 @@ backend_network_monitor_can_reach_cb (GObject *source_object,
g_thread_unref (thread);
}
-static void
-backend_update_online_state (EBackend *backend)
+static gboolean
+backend_update_online_state_idle_cb (gpointer user_data)
{
+ EBackend *backend;
GSocketConnectable *connectable;
GCancellable *cancellable;
- /* This should be eventually replaced with default implementation
- of EBackend::get_destination_address() doing basically the same
- what currently does the backend silently on construction, thus
- it'll get also current values from the ESource, not stale from
- construct time.
- */
+ backend = E_BACKEND (user_data);
connectable = e_backend_ref_connectable (backend);
+ g_mutex_lock (&backend->priv->update_online_state_lock);
+ g_source_unref (backend->priv->update_online_state);
+ backend->priv->update_online_state = NULL;
+ g_mutex_unlock (&backend->priv->update_online_state_lock);
+
g_mutex_lock (&backend->priv->network_monitor_cancellable_lock);
cancellable = backend->priv->network_monitor_cancellable;
@@ -223,20 +226,37 @@ backend_update_online_state (EBackend *backend)
if (connectable != NULL)
g_object_unref (connectable);
+
+ return FALSE;
}
-static gboolean
-backend_network_changed_timeout_cb (gpointer user_data)
+static void
+backend_update_online_state (EBackend *backend)
{
- EBackend *backend = user_data;
-
- if (!g_source_is_destroyed (g_main_current_source ())) {
- backend->priv->network_changed_timeout_id = 0;
-
- backend_update_online_state (backend);
+ g_mutex_lock (&backend->priv->update_online_state_lock);
+
+ if (backend->priv->update_online_state == NULL) {
+ GMainContext *main_context;
+ GSource *idle_source;
+
+ main_context = e_backend_ref_main_context (backend);
+
+ idle_source = g_idle_source_new ();
+ g_source_set_priority (idle_source, G_PRIORITY_LOW);
+ g_source_set_callback (
+ idle_source,
+ backend_update_online_state_idle_cb,
+ g_object_ref (backend),
+ (GDestroyNotify) g_object_unref);
+ g_source_attach (idle_source, main_context);
+ backend->priv->update_online_state =
+ g_source_ref (idle_source);
+ g_source_unref (idle_source);
+
+ g_main_context_unref (main_context);
}
- return FALSE;
+ g_mutex_unlock (&backend->priv->update_online_state_lock);
}
static void
@@ -244,11 +264,7 @@ backend_network_changed_cb (GNetworkMonitor *network_monitor,
gboolean network_available,
EBackend *backend)
{
- if (backend->priv->network_changed_timeout_id)
- g_source_remove (backend->priv->network_changed_timeout_id);
-
- /* wait few seconds, a network change can fire this event multiple times */
- backend->priv->network_changed_timeout_id = g_timeout_add_seconds (3,
backend_network_changed_timeout_cb, backend);
+ backend_update_online_state (backend);
}
static void
@@ -345,16 +361,17 @@ backend_dispose (GObject *object)
priv->network_changed_handler_id = 0;
}
- if (priv->network_changed_timeout_id) {
- g_source_remove (priv->network_changed_timeout_id);
- priv->network_changed_timeout_id = 0;
- }
-
if (priv->main_context != NULL) {
g_main_context_unref (priv->main_context);
priv->main_context = NULL;
}
+ if (priv->update_online_state != NULL) {
+ g_source_destroy (priv->update_online_state);
+ g_source_unref (priv->update_online_state);
+ priv->update_online_state = NULL;
+ }
+
g_clear_object (&priv->source);
g_clear_object (&priv->prompter);
g_clear_object (&priv->connectable);
@@ -373,13 +390,9 @@ backend_finalize (GObject *object)
priv = E_BACKEND_GET_PRIVATE (object);
g_mutex_clear (&priv->property_lock);
+ g_mutex_clear (&priv->update_online_state_lock);
g_mutex_clear (&priv->network_monitor_cancellable_lock);
- if (priv->network_changed_timeout_id) {
- g_source_remove (priv->network_changed_timeout_id);
- priv->network_changed_timeout_id = 0;
- }
-
/* Chain up to parent's finalize() method. */
G_OBJECT_CLASS (e_backend_parent_class)->finalize (object);
}
@@ -591,6 +604,7 @@ e_backend_init (EBackend *backend)
backend->priv->main_context = g_main_context_ref_thread_default ();
g_mutex_init (&backend->priv->property_lock);
+ g_mutex_init (&backend->priv->update_online_state_lock);
g_mutex_init (&backend->priv->network_monitor_cancellable_lock);
/* Configure network monitoring. */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]