summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMilan Crha <mcrha@redhat.com>2021-05-06 13:40:07 +0200
committerMilan Crha <mcrha@redhat.com>2021-05-06 13:45:10 +0200
commitd78c7ebc5ca8ec90f5b4831db097c47c6fd0a15b (patch)
treef6d6b9937eed6ac0f85812193eb5ef3d2bbf356f
parentd9ec385d6c53a58e0dbcd6e4d227718dc57f2b24 (diff)
downloadevolution-data-server-d78c7ebc5ca8ec90f5b4831db097c47c6fd0a15b.tar.gz
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.
-rw-r--r--src/addressbook/libedata-book/e-data-book-factory.c8
-rw-r--r--src/calendar/libedata-cal/e-data-cal-factory.c16
-rw-r--r--src/libebackend/e-data-factory.c28
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;