mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-01-26 22:16:16 +01:00
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:
parent
fba7f7e097
commit
a3060bc84f
18
glib/gmain.c
18
glib/gmain.c
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
Reference in New Issue
Block a user