[evolution-data-server] Data Factories: Miscellaneous fixes



commit 13ba9492c8bef837330219455c39460514a83393
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]