gmain: Fix reference leak of GMainLoop in some situations

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 <pwithnall@endlessos.org>

Fixes: #2598
This commit is contained in:
Philip Withnall 2022-03-04 17:37:09 +00:00
parent 887f73d34e
commit 4f5da83381

View File

@ -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);