[evolution-data-server] ESource: Reconnect signal handlers when the D-Bus 'source' interface changes



commit 5d731c9e2188b82b0bc248f42f8e47a5fb75d442
Author: Milan Crha <mcrha redhat com>
Date:   Tue Jun 28 11:34:43 2022 +0200

    ESource: Reconnect signal handlers when the D-Bus 'source' interface changes
    
    It can happen the GDBus object resets the interface on its own. As the ESource
    connects signals on the 'source' interface, it could happen that the authentication
    responses were not received due to them being emitted on a new 'source' interface,
    which the ESource did not listen to.

 src/libedataserver/e-source.c | 40 ++++++++++++++++++++++++++++++++++------
 1 file changed, 34 insertions(+), 6 deletions(-)
---
diff --git a/src/libedataserver/e-source.c b/src/libedataserver/e-source.c
index 9490e420c..31d851e21 100644
--- a/src/libedataserver/e-source.c
+++ b/src/libedataserver/e-source.c
@@ -1042,6 +1042,20 @@ source_idle_changed_cb (gpointer user_data)
        return FALSE;
 }
 
+static void source_connect_dbus_source (ESource *source);
+
+static void
+e_source_dbus_object_notify_source_cb (GObject *dbus_object,
+                                      GParamSpec *param,
+                                      gpointer user_data)
+{
+       ESource *source = user_data;
+
+       g_return_if_fail (E_IS_SOURCE (source));
+
+       source_connect_dbus_source (source);
+}
+
 static void
 source_set_dbus_object (ESource *source,
                         EDBusObject *dbus_object)
@@ -1054,6 +1068,9 @@ source_set_dbus_object (ESource *source,
        g_return_if_fail (source->priv->dbus_object == NULL);
 
        source->priv->dbus_object = G_DBUS_OBJECT (g_object_ref (dbus_object));
+
+       g_signal_connect_object (source->priv->dbus_object, "notify::source",
+               G_CALLBACK (e_source_dbus_object_notify_source_cb), source, 0);
 }
 
 static void
@@ -1231,14 +1248,13 @@ source_dispose (GObject *object)
 
                dbus_source = e_dbus_object_get_source (dbus_object);
                if (dbus_source != NULL) {
-                       g_signal_handlers_disconnect_matched (
-                               dbus_source, G_SIGNAL_MATCH_DATA,
-                               0, 0, NULL, NULL, object);
+                       g_signal_handlers_disconnect_by_data (dbus_source, object);
                        g_object_unref (dbus_source);
                }
 
-               g_object_unref (priv->dbus_object);
-               priv->dbus_object = NULL;
+               g_signal_handlers_disconnect_by_data (priv->dbus_object, object);
+
+               g_clear_object (&priv->dbus_object);
        }
 
        g_mutex_unlock (&priv->property_lock);
@@ -2014,6 +2030,11 @@ source_connect_dbus_source (ESource *source)
        dbus_source = e_dbus_object_get_source (dbus_object);
        g_return_if_fail (E_DBUS_IS_SOURCE (dbus_source));
 
+       g_signal_handlers_disconnect_by_func (dbus_source, source_notify_dbus_data_cb, source);
+       g_signal_handlers_disconnect_by_func (dbus_source, source_notify_dbus_connection_status_cb, source);
+       g_signal_handlers_disconnect_by_func (dbus_source, source_dbus_credentials_required_cb, source);
+       g_signal_handlers_disconnect_by_func (dbus_source, source_dbus_authenticate_cb, source);
+
        g_signal_connect_object (
                dbus_source, "notify::data",
                G_CALLBACK (source_notify_dbus_data_cb), source, 0);
@@ -2504,14 +2525,21 @@ __e_source_private_replace_dbus_object (ESource *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_signal_handlers_disconnect_by_data (dbus_source, source);
                        g_object_unref (dbus_source);
                }
+
+               g_signal_handlers_disconnect_by_func (source->priv->dbus_object, 
e_source_dbus_object_notify_source_cb, source);
        }
 
        g_clear_object (&source->priv->dbus_object);
        source->priv->dbus_object = dbus_object;
 
+       if (source->priv->dbus_object) {
+               g_signal_connect_object (source->priv->dbus_object, "notify::source",
+                       G_CALLBACK (e_source_dbus_object_notify_source_cb), source, 0);
+       }
+
        g_mutex_unlock (&source->priv->property_lock);
 
        source_connect_dbus_source (source);


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