[evolution-data-server/gnome-40] Data Factories: Miscellaneous fixes



commit d78c7ebc5ca8ec90f5b4831db097c47c6fd0a15b
Author: Milan Crha <mcrha redhat com>
Date:   Thu May 6 13:40:07 2021 +0200

    Data Factories: Miscellaneous fixes
    
    These will help to avoid use-after-free issues:
    a) the book/calendar factories will disconnect from the signal
       handler when freed automatically;
    b) the data factory will make sure it listens for the ref toggle
       notify only when it's interested in it. That worked until
       free of the data factory with still opened backends.

 .../libedata-book/e-data-book-factory.c            |  8 +++----
 src/calendar/libedata-cal/e-data-cal-factory.c     | 16 ++++++-------
 src/libebackend/e-data-factory.c                   | 28 ++++++++++++++--------
 3 files changed, 30 insertions(+), 22 deletions(-)
---
diff --git a/src/addressbook/libedata-book/e-data-book-factory.c 
b/src/addressbook/libedata-book/e-data-book-factory.c
index f362f89df..02adb19b4 100644
--- a/src/addressbook/libedata-book/e-data-book-factory.c
+++ b/src/addressbook/libedata-book/e-data-book-factory.c
@@ -156,8 +156,8 @@ data_book_factory_create_backend (EDataFactory *data_factory,
        }
 
        if (backend) {
-               g_signal_connect (backend, "closed",
-                       G_CALLBACK (data_book_factory_backend_closed_cb), data_factory);
+               g_signal_connect_object (backend, "closed",
+                       G_CALLBACK (data_book_factory_backend_closed_cb), data_factory, 0);
        }
 
        return backend;
@@ -343,10 +343,10 @@ e_data_book_factory_init (EDataBookFactory *factory)
        factory->priv->dbus_factory =
                e_dbus_address_book_factory_skeleton_new ();
 
-       g_signal_connect (
+       g_signal_connect_object (
                factory->priv->dbus_factory, "handle-open-address-book",
                G_CALLBACK (data_book_factory_handle_open_address_book_cb),
-               factory);
+               factory, 0);
 }
 
 EDBusServer *
diff --git a/src/calendar/libedata-cal/e-data-cal-factory.c b/src/calendar/libedata-cal/e-data-cal-factory.c
index 575723007..e0790e17d 100644
--- a/src/calendar/libedata-cal/e-data-cal-factory.c
+++ b/src/calendar/libedata-cal/e-data-cal-factory.c
@@ -186,8 +186,8 @@ data_cal_factory_create_backend (EDataFactory *data_factory,
        }
 
        if (backend) {
-               g_signal_connect (backend, "closed",
-                       G_CALLBACK (data_cal_factory_backend_closed_cb), data_factory);
+               g_signal_connect_object (backend, "closed",
+                       G_CALLBACK (data_cal_factory_backend_closed_cb), data_factory, 0);
        }
 
        return backend;
@@ -338,20 +338,20 @@ e_data_cal_factory_init (EDataCalFactory *factory)
        factory->priv->dbus_factory =
                e_dbus_calendar_factory_skeleton_new ();
 
-       g_signal_connect (
+       g_signal_connect_object (
                factory->priv->dbus_factory, "handle-open-calendar",
                G_CALLBACK (data_cal_factory_handle_open_calendar_cb),
-               factory);
+               factory, 0);
 
-       g_signal_connect (
+       g_signal_connect_object (
                factory->priv->dbus_factory, "handle-open-task-list",
                G_CALLBACK (data_cal_factory_handle_open_task_list_cb),
-               factory);
+               factory, 0);
 
-       g_signal_connect (
+       g_signal_connect_object (
                factory->priv->dbus_factory, "handle-open-memo-list",
                G_CALLBACK (data_cal_factory_handle_open_memo_list_cb),
-               factory);
+               factory, 0);
 }
 
 EDBusServer *
diff --git a/src/libebackend/e-data-factory.c b/src/libebackend/e-data-factory.c
index 7c4106a68..63b3ccf9b 100644
--- a/src/libebackend/e-data-factory.c
+++ b/src/libebackend/e-data-factory.c
@@ -188,18 +188,31 @@ data_factory_subprocess_helper_free (DataFactorySubprocessHelper *helper)
        }
 }
 
+static void
+data_factory_backend_toggle_notify_cb (gpointer user_data,
+                                      GObject *backend,
+                                      gboolean is_last_ref);
+
 typedef struct _OpenedBackendData {
+       EDataFactory *data_factory;
        EBackend *backend;
        gchar *object_path;
 } OpenedBackendData;
 
 static OpenedBackendData *
-opened_backend_data_new (EBackend *backend, /* assumes ownership of 'backend' */
+opened_backend_data_new (EDataFactory *data_factory,
+                        EBackend *backend, /* assumes ownership of 'backend' */
                         const gchar *object_path)
 {
        OpenedBackendData *obd;
 
+       g_object_add_toggle_ref (
+               G_OBJECT (backend),
+               data_factory_backend_toggle_notify_cb,
+               data_factory);
+
        obd = g_slice_new0 (OpenedBackendData);
+       obd->data_factory = data_factory;
        obd->backend = backend;
        obd->object_path = g_strdup (object_path);
 
@@ -212,6 +225,9 @@ opened_backend_data_free (gpointer ptr)
        OpenedBackendData *obd = ptr;
 
        if (obd) {
+               if (obd->backend)
+                       g_object_remove_toggle_ref (G_OBJECT (obd->backend), 
data_factory_backend_toggle_notify_cb, obd->data_factory);
+
                g_clear_object (&obd->backend);
                g_free (obd->object_path);
                g_slice_free (OpenedBackendData, obd);
@@ -1347,9 +1363,6 @@ data_factory_backend_toggle_notify_cb (gpointer user_data,
 
                g_object_ref (backend);
 
-               g_object_remove_toggle_ref (
-                       backend, data_factory_backend_toggle_notify_cb, user_data);
-
                g_signal_emit_by_name (backend, "shutdown");
 
                g_mutex_lock (&data_factory->priv->mutex);
@@ -1465,14 +1478,9 @@ data_factory_spawn_subprocess_backend (EDataFactory *data_factory,
                        backend = e_data_factory_create_backend (data_factory, backend_factory, source);
                        object_path = e_data_factory_open_backend (data_factory, backend, 
g_dbus_method_invocation_get_connection (invocation), NULL, &error);
                        if (object_path) {
-                               g_object_add_toggle_ref (
-                                       G_OBJECT (backend),
-                                       data_factory_backend_toggle_notify_cb,
-                                       data_factory);
-
                                g_mutex_lock (&data_factory->priv->mutex);
                                g_hash_table_insert (data_factory->priv->opened_backends, backend_key,
-                                       opened_backend_data_new (backend, object_path));
+                                       opened_backend_data_new (data_factory, backend, object_path));
                                g_mutex_unlock (&data_factory->priv->mutex);
 
                                backend_key = NULL;


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