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



commit 3d11eaa3f8aaad20c3b03e5b4dd590e424543581
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 | 42 +++++++++++++++++++++++++++++++++++-------
 1 file changed, 35 insertions(+), 7 deletions(-)
---
diff --git a/src/libedataserver/e-source.c b/src/libedataserver/e-source.c
index b2fb6102d..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)
@@ -1053,7 +1067,10 @@ source_set_dbus_object (ESource *source,
        g_return_if_fail (E_DBUS_IS_OBJECT (dbus_object));
        g_return_if_fail (source->priv->dbus_object == NULL);
 
-       source->priv->dbus_object = g_object_ref (dbus_object);
+       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]