From 95e7114badc115bdde57db9ffd5ac48b2840ecfc Mon Sep 17 00:00:00 2001 From: Michal Bloch Date: Wed, 21 Aug 2024 18:46:04 +0200 Subject: [PATCH] Add ensure_required_types constructor Attempt to work around a deadlock bug. Change-Id: Ic9d46c0d0946738b19070eb3c22f61dc7c8f80ca --- gio/gdbusprivate.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/gio/gdbusprivate.c b/gio/gdbusprivate.c index 2c9238c..f5cebcb 100644 --- a/gio/gdbusprivate.c +++ b/gio/gdbusprivate.c @@ -238,8 +238,10 @@ release_required_types (void) static void ensure_required_types (void) { - g_assert (ensured_classes == NULL); + if (ensured_classes != NULL) + return; ensured_classes = g_ptr_array_new (); + /* Generally in this list, you should initialize types which are used as * properties first, then the class which has them. For example, GDBusProxy * has a type of GDBusConnection, so we initialize GDBusConnection first. @@ -289,6 +291,18 @@ gdbus_shared_thread_func (gpointer user_data) return NULL; } +/* See `ensure_required_types` for rationale. Doing this in a library constructor + * is to ensure extra hard that it happens before there are any extra threads that + * could produce a deadlock. */ +static void __attribute__ ((constructor)) ensure_required_types_constructor (void) +{ + /* No thread safety (e.g. `g_init_once`) should be needed, as + * constructors run at library load, before other threads can use + * the library or even before other threads are even spawned. */ + g_assert (ensured_classes == NULL); + ensure_required_types(); +} + /* ---------------------------------------------------------------------------------------------------- */ static SharedThreadData * -- 2.7.4