libgdbus: Add a context to handle pending event sources 53/324453/4 accepted/tizen/unified/20250520.080523 accepted/tizen/unified/x/20250520.211444
authorUnsung Lee <unsung.lee@samsung.com>
Sun, 18 May 2025 11:52:21 +0000 (20:52 +0900)
committerUnsung Lee <unsung.lee@samsung.com>
Mon, 19 May 2025 07:27:11 +0000 (16:27 +0900)
Add a context in dbus_handle to handle pending an event source after calling g_dbus_connection_close_sync().
This is because, g_dbus_connection_close_sync() adds an idle source to the context.
If this event source is not handled, then connection ref_cnt is not decremented.
It causes that the connection structures and the corresponding threads are left after free.

Change-Id: Ibc5597b26ef264e03fb86aef92d72627c7d2b8d1
Signed-off-by: Unsung Lee <unsung.lee@samsung.com>
src/libgdbus/libgdbus.c

index d206064ebfe69487ef67f016139ed6e60caa7b6d..91709ba9f6ece80c19d3ad7eebd6304a313f8de0 100644 (file)
@@ -70,6 +70,7 @@ typedef struct {
        GList *list_names;      /* dbus_name */
        GList *list_object;     /* dbus_object_handle_s */
        pthread_mutex_t mutex;
+       GMainContext *main_context;
 } dbus_handle_s;
 
 /* path + interfaces */
@@ -247,7 +248,10 @@ static dbus_handle_s *_gdbus_get_connection_private(GBusType bus_type)
        gdbus_lock(dh);
 
        if (!dh->conn) {
+               dh->main_context = g_main_context_new();
+               g_main_context_push_thread_default(dh->main_context);
                dh->conn = _get_bus_private(bus_type);
+               g_main_context_pop_thread_default(dh->main_context);
                dh->priv = TRUE;
                dh->bus_type = bus_type;
                if (!dh->conn)
@@ -259,6 +263,7 @@ static dbus_handle_s *_gdbus_get_connection_private(GBusType bus_type)
        return dh;
 err:
        if (dh) {
+               g_main_context_unref(dh->main_context);
                gdbus_unlock(dh);
                free(dh);
        }
@@ -652,6 +657,13 @@ int gdbus_free_connection(dbus_handle_h handle)
                        g_error_free(err);
                        err = NULL;
                }
+
+               if (!g_main_context_iteration(pdh->main_context, FALSE)) {
+                       _W("Cannot dispatch and handle an idle source from connection close");
+                       g_object_unref(pdh->conn);
+               }
+
+               g_main_context_unref(pdh->main_context);
        }
 
        /* _free_func_object callback free the data */