[evolution-data-server] Bug 736006 - Crash under backend_finalize() during online state change



commit 0b34708ec3b533f0a421cb589689e23fea478134
Author: Milan Crha <mcrha redhat com>
Date:   Mon Jan 12 14:20:11 2015 +0100

    Bug 736006 - Crash under backend_finalize() during online state change

 camel/camel-network-service.c |   34 +++++++++++++++++-----------------
 libebackend/e-backend.c       |   41 +++++++++++++++++++++--------------------
 2 files changed, 38 insertions(+), 37 deletions(-)
---
diff --git a/camel/camel-network-service.c b/camel/camel-network-service.c
index b70afc0..8d61cc0 100644
--- a/camel/camel-network-service.c
+++ b/camel/camel-network-service.c
@@ -408,6 +408,8 @@ network_service_update_host_reachable (CamelNetworkService *service)
 {
        CamelNetworkServicePrivate *priv;
        CamelSession *session;
+       GMainContext *main_context;
+       GSource *timeout_source;
 
        priv = CAMEL_NETWORK_SERVICE_GET_PRIVATE (service);
 
@@ -419,31 +421,29 @@ network_service_update_host_reachable (CamelNetworkService *service)
 
        g_mutex_lock (&priv->update_host_reachable_lock);
 
+       /* Reference the service before destroying any already scheduled GSource,
+          in case the service's last reference is held by that GSource. */
+       g_object_ref (service);
+
        if (priv->update_host_reachable) {
                g_source_destroy (priv->update_host_reachable);
                g_source_unref (priv->update_host_reachable);
                priv->update_host_reachable = NULL;
        }
 
-       if (priv->update_host_reachable == NULL) {
-               GMainContext *main_context;
-               GSource *timeout_source;
-
-               main_context = camel_session_ref_main_context (session);
+       main_context = camel_session_ref_main_context (session);
 
-               timeout_source = g_timeout_source_new_seconds (5);
-               g_source_set_priority (timeout_source, G_PRIORITY_LOW);
-               g_source_set_callback (
-                       timeout_source,
-                       network_service_update_host_reachable_timeout_cb,
-                       g_object_ref (service),
-                       (GDestroyNotify) g_object_unref);
-               g_source_attach (timeout_source, main_context);
-               priv->update_host_reachable = g_source_ref (timeout_source);
-               g_source_unref (timeout_source);
+       timeout_source = g_timeout_source_new_seconds (5);
+       g_source_set_priority (timeout_source, G_PRIORITY_LOW);
+       g_source_set_callback (
+               timeout_source,
+               network_service_update_host_reachable_timeout_cb,
+               service, (GDestroyNotify) g_object_unref);
+       g_source_attach (timeout_source, main_context);
+       priv->update_host_reachable = g_source_ref (timeout_source);
+       g_source_unref (timeout_source);
 
-               g_main_context_unref (main_context);
-       }
+       g_main_context_unref (main_context);
 
        g_mutex_unlock (&priv->update_host_reachable_lock);
 
diff --git a/libebackend/e-backend.c b/libebackend/e-backend.c
index 868b35e..a020c4d 100644
--- a/libebackend/e-backend.c
+++ b/libebackend/e-backend.c
@@ -191,34 +191,35 @@ backend_update_online_state_timeout_cb (gpointer user_data)
 static void
 backend_update_online_state (EBackend *backend)
 {
+       GMainContext *main_context;
+       GSource *timeout_source;
+
        g_mutex_lock (&backend->priv->update_online_state_lock);
 
+       /* Reference the backend before destroying any already scheduled GSource,
+          in case the backend's last reference is held by that GSource. */
+       g_object_ref (backend);
+
        if (backend->priv->update_online_state) {
                g_source_destroy (backend->priv->update_online_state);
                g_source_unref (backend->priv->update_online_state);
                backend->priv->update_online_state = NULL;
        }
 
-       if (backend->priv->update_online_state == NULL) {
-               GMainContext *main_context;
-               GSource *timeout_source;
-
-               main_context = e_backend_ref_main_context (backend);
-
-               timeout_source = g_timeout_source_new_seconds (5);
-               g_source_set_priority (timeout_source, G_PRIORITY_LOW);
-               g_source_set_callback (
-                       timeout_source,
-                       backend_update_online_state_timeout_cb,
-                       g_object_ref (backend),
-                       (GDestroyNotify) g_object_unref);
-               g_source_attach (timeout_source, main_context);
-               backend->priv->update_online_state =
-                       g_source_ref (timeout_source);
-               g_source_unref (timeout_source);
-
-               g_main_context_unref (main_context);
-       }
+       main_context = e_backend_ref_main_context (backend);
+
+       timeout_source = g_timeout_source_new_seconds (5);
+       g_source_set_priority (timeout_source, G_PRIORITY_LOW);
+       g_source_set_callback (
+               timeout_source,
+               backend_update_online_state_timeout_cb,
+               backend, (GDestroyNotify) g_object_unref);
+       g_source_attach (timeout_source, main_context);
+       backend->priv->update_online_state =
+               g_source_ref (timeout_source);
+       g_source_unref (timeout_source);
+
+       g_main_context_unref (main_context);
 
        g_mutex_unlock (&backend->priv->update_online_state_lock);
 }


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