mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-01-14 00:06:24 +01:00
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:
parent
887f73d34e
commit
4f5da83381
@ -4367,6 +4367,9 @@ g_main_loop_run (GMainLoop *loop)
|
|||||||
g_return_if_fail (loop != NULL);
|
g_return_if_fail (loop != NULL);
|
||||||
g_return_if_fail (g_atomic_int_get (&loop->ref_count) > 0);
|
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))
|
if (!g_main_context_acquire (loop->context))
|
||||||
{
|
{
|
||||||
gboolean got_ownership = FALSE;
|
gboolean got_ownership = FALSE;
|
||||||
@ -4374,7 +4377,6 @@ g_main_loop_run (GMainLoop *loop)
|
|||||||
/* Another thread owns this context */
|
/* Another thread owns this context */
|
||||||
LOCK_CONTEXT (loop->context);
|
LOCK_CONTEXT (loop->context);
|
||||||
|
|
||||||
g_atomic_int_inc (&loop->ref_count);
|
|
||||||
g_atomic_int_set (&loop->is_running, TRUE);
|
g_atomic_int_set (&loop->is_running, TRUE);
|
||||||
|
|
||||||
while (g_atomic_int_get (&loop->is_running) && !got_ownership)
|
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 "
|
g_warning ("g_main_loop_run(): called recursively from within a source's "
|
||||||
"check() or prepare() member, iteration not possible.");
|
"check() or prepare() member, iteration not possible.");
|
||||||
|
g_main_loop_unref (loop);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
g_atomic_int_inc (&loop->ref_count);
|
|
||||||
g_atomic_int_set (&loop->is_running, TRUE);
|
g_atomic_int_set (&loop->is_running, TRUE);
|
||||||
while (g_atomic_int_get (&loop->is_running))
|
while (g_atomic_int_get (&loop->is_running))
|
||||||
g_main_context_iterate (loop->context, TRUE, TRUE, self);
|
g_main_context_iterate (loop->context, TRUE, TRUE, self);
|
||||||
|
Loading…
Reference in New Issue
Block a user