[evolution-data-server] ESource: Required signals not connected after EDBusObject is replaced



commit 90941a4ed5ef24ec45775546ea4f9fffb048aa2a
Author: Milan Crha <mcrha redhat com>
Date:   Wed Oct 16 12:51:11 2019 +0200

    ESource: Required signals not connected after EDBusObject is replaced
    
    When D-Bus notified about replaced EDBusObject for an existing ESource,
    this ESource did not connect to signals as when it had been created
    with such EDBsuObject from the beginning, which could cause long-pending
    authentications in some cases, and other misbehavior due to not receiving
    those signals.

 src/libedataserver/e-source.c | 83 +++++++++++++++++++++++++++++++++----------
 1 file changed, 65 insertions(+), 18 deletions(-)
---
diff --git a/src/libedataserver/e-source.c b/src/libedataserver/e-source.c
index ba3a56111..e7b8cff54 100644
--- a/src/libedataserver/e-source.c
+++ b/src/libedataserver/e-source.c
@@ -851,16 +851,14 @@ source_update_connection_status_internal (ESource *source,
        return changed;
 }
 
-static gboolean
-source_idle_connection_status_change_cb (gpointer user_data)
+static void
+source_update_connection_status (ESource *source)
 {
-       ESource *source = E_SOURCE (user_data);
        EDBusObject *dbus_object;
        EDBusSource *dbus_source;
        gboolean changed = FALSE;
 
-       if (g_source_is_destroyed (g_main_current_source ()))
-               return FALSE;
+       g_return_if_fail (E_IS_SOURCE (source));
 
        g_mutex_lock (&source->priv->connection_status_change_lock);
        if (source->priv->connection_status_change != NULL) {
@@ -885,6 +883,19 @@ source_idle_connection_status_change_cb (gpointer user_data)
 
        g_mutex_unlock (&source->priv->property_lock);
        g_object_thaw_notify (G_OBJECT (source));
+}
+
+static gboolean
+source_idle_connection_status_change_cb (gpointer user_data)
+{
+       ESource *source;
+
+       if (g_source_is_destroyed (g_main_current_source ()))
+               return FALSE;
+
+       source = E_SOURCE (user_data);
+
+       source_update_connection_status (source);
 
        return FALSE;
 }
@@ -1958,6 +1969,40 @@ source_unset_last_credentials_required_arguments_impl (ESource *source,
        return success;
 }
 
+static void
+source_connect_dbus_source (ESource *source)
+{
+       EDBusObject *dbus_object;
+       EDBusSource *dbus_source;
+
+       g_return_if_fail (E_IS_SOURCE (source));
+
+       if (!source->priv->dbus_object)
+               return;
+
+       dbus_object = E_DBUS_OBJECT (source->priv->dbus_object);
+
+       /* An EDBusObject lacking an EDBusSource
+        * interface indicates a programmer error. */
+       dbus_source = e_dbus_object_get_source (dbus_object);
+       g_return_if_fail (E_DBUS_IS_SOURCE (dbus_source));
+
+       g_signal_connect_object (
+               dbus_source, "notify::data",
+               G_CALLBACK (source_notify_dbus_data_cb), source, 0);
+       g_signal_connect_object (
+               dbus_source, "notify::connection-status",
+               G_CALLBACK (source_notify_dbus_connection_status_cb), source, 0);
+       g_signal_connect_object (
+               dbus_source, "credentials-required",
+               G_CALLBACK (source_dbus_credentials_required_cb), source, 0);
+       g_signal_connect_object (
+               dbus_source, "authenticate",
+               G_CALLBACK (source_dbus_authenticate_cb), source, 0);
+
+       g_clear_object (&dbus_source);
+}
+
 static gboolean
 source_initable_init (GInitable *initable,
                       GCancellable *cancellable,
@@ -1990,19 +2035,7 @@ source_initable_init (GInitable *initable,
                source->priv->uid = e_dbus_source_dup_uid (dbus_source);
 
                source_update_connection_status_internal (source, dbus_source);
-
-               g_signal_connect (
-                       dbus_source, "notify::data",
-                       G_CALLBACK (source_notify_dbus_data_cb), source);
-               g_signal_connect (
-                       dbus_source, "notify::connection-status",
-                       G_CALLBACK (source_notify_dbus_connection_status_cb), source);
-               g_signal_connect (
-                       dbus_source, "credentials-required",
-                       G_CALLBACK (source_dbus_credentials_required_cb), source);
-               g_signal_connect (
-                       dbus_source, "authenticate",
-                       G_CALLBACK (source_dbus_authenticate_cb), source);
+               source_connect_dbus_source (source);
 
                success = source_parse_dbus_data (source, error);
 
@@ -2437,11 +2470,25 @@ __e_source_private_replace_dbus_object (ESource *source,
 
        g_mutex_lock (&source->priv->property_lock);
 
+       if (source->priv->dbus_object) {
+               EDBusSource *dbus_source;
+
+               dbus_source = e_dbus_object_get_source (E_DBUS_OBJECT (source->priv->dbus_object));
+
+               if (dbus_source) {
+                       g_signal_handlers_disconnect_by_data (dbus_source, source),
+                       g_object_unref (dbus_source);
+               }
+       }
+
        g_clear_object (&source->priv->dbus_object);
        source->priv->dbus_object = dbus_object;
 
        g_mutex_unlock (&source->priv->property_lock);
 
+       source_connect_dbus_source (source);
+       source_update_connection_status (source);
+
        g_object_notify (G_OBJECT (source), "dbus-object");
 }
 


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