gmain: Synchronize access to is_running flag of GMainLoop

Synchronize access to is_running field of GMainLoop to ensure that
g_main_loop_is_running is thread safe.
This commit is contained in:
Tomasz Miąsko 2019-02-21 00:00:00 +00:00
parent fba7f7e097
commit a3060bc84f

View File

@ -309,7 +309,7 @@ struct _GSourceCallback
struct _GMainLoop struct _GMainLoop
{ {
GMainContext *context; GMainContext *context;
gboolean is_running; gboolean is_running; /* (atomic) */
volatile gint ref_count; volatile gint ref_count;
}; };
@ -4087,16 +4087,14 @@ g_main_loop_run (GMainLoop *loop)
LOCK_CONTEXT (loop->context); LOCK_CONTEXT (loop->context);
g_atomic_int_inc (&loop->ref_count); g_atomic_int_inc (&loop->ref_count);
g_atomic_int_set (&loop->is_running, TRUE);
if (!loop->is_running) while (g_atomic_int_get (&loop->is_running) && !got_ownership)
loop->is_running = TRUE;
while (loop->is_running && !got_ownership)
got_ownership = g_main_context_wait_internal (loop->context, got_ownership = g_main_context_wait_internal (loop->context,
&loop->context->cond, &loop->context->cond,
&loop->context->mutex); &loop->context->mutex);
if (!loop->is_running) if (!g_atomic_int_get (&loop->is_running))
{ {
UNLOCK_CONTEXT (loop->context); UNLOCK_CONTEXT (loop->context);
if (got_ownership) if (got_ownership)
@ -4118,8 +4116,8 @@ g_main_loop_run (GMainLoop *loop)
} }
g_atomic_int_inc (&loop->ref_count); g_atomic_int_inc (&loop->ref_count);
loop->is_running = TRUE; g_atomic_int_set (&loop->is_running, TRUE);
while (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);
UNLOCK_CONTEXT (loop->context); UNLOCK_CONTEXT (loop->context);
@ -4146,7 +4144,7 @@ g_main_loop_quit (GMainLoop *loop)
g_return_if_fail (g_atomic_int_get (&loop->ref_count) > 0); g_return_if_fail (g_atomic_int_get (&loop->ref_count) > 0);
LOCK_CONTEXT (loop->context); LOCK_CONTEXT (loop->context);
loop->is_running = FALSE; g_atomic_int_set (&loop->is_running, FALSE);
g_wakeup_signal (loop->context->wakeup); g_wakeup_signal (loop->context->wakeup);
g_cond_broadcast (&loop->context->cond); g_cond_broadcast (&loop->context->cond);
@ -4170,7 +4168,7 @@ g_main_loop_is_running (GMainLoop *loop)
g_return_val_if_fail (loop != NULL, FALSE); g_return_val_if_fail (loop != NULL, FALSE);
g_return_val_if_fail (g_atomic_int_get (&loop->ref_count) > 0, FALSE); g_return_val_if_fail (g_atomic_int_get (&loop->ref_count) > 0, FALSE);
return loop->is_running; return g_atomic_int_get (&loop->is_running);
} }
/** /**