From 4f5da8338127e25e5ebb54f5a4a95ffc2e40adcc Mon Sep 17 00:00:00 2001 From: Philip Withnall Date: Fri, 4 Mar 2022 17:37:09 +0000 Subject: [PATCH] gmain: Fix reference leak of GMainLoop in some situations MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When calling `g_main_loop_run()` it’s possible for a reference to the `GMainLoop` to leak if this thread had to wait to acquire ownership of the `GMainContext`. Signed-off-by: Philip Withnall Fixes: #2598 --- glib/gmain.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/glib/gmain.c b/glib/gmain.c index 0e757a6f6..94aa1152a 100644 --- a/glib/gmain.c +++ b/glib/gmain.c @@ -4367,6 +4367,9 @@ g_main_loop_run (GMainLoop *loop) g_return_if_fail (loop != NULL); g_return_if_fail (g_atomic_int_get (&loop->ref_count) > 0); + /* Hold a reference in case the loop is unreffed from a callback function */ + g_atomic_int_inc (&loop->ref_count); + if (!g_main_context_acquire (loop->context)) { gboolean got_ownership = FALSE; @@ -4374,7 +4377,6 @@ g_main_loop_run (GMainLoop *loop) /* Another thread owns this context */ LOCK_CONTEXT (loop->context); - g_atomic_int_inc (&loop->ref_count); g_atomic_int_set (&loop->is_running, TRUE); while (g_atomic_int_get (&loop->is_running) && !got_ownership) @@ -4400,10 +4402,10 @@ g_main_loop_run (GMainLoop *loop) { g_warning ("g_main_loop_run(): called recursively from within a source's " "check() or prepare() member, iteration not possible."); + g_main_loop_unref (loop); return; } - g_atomic_int_inc (&loop->ref_count); g_atomic_int_set (&loop->is_running, TRUE); while (g_atomic_int_get (&loop->is_running)) g_main_context_iterate (loop->context, TRUE, TRUE, self);