mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-02-24 11:12:11 +01:00
gmain: Make GSourceCallback thread-safe
Otherwise there is a race in finalising the GSourceCallback if one thread is finishing off a g_main_dispatch() while another thread is destroying the GSource which owns the GSourceCallback. A helgrind log: ==21707== Possible data race during write of size 4 at 0x54EACB0 by thread #12 ==21707== Locks held: none ==21707== at 0x4ECC174: g_source_callback_unref (gmain.c:1528) ==21707== by 0x4ECD953: g_main_dispatch (gmain.c:3081) ==21707== by 0x4ECE667: g_main_context_dispatch (gmain.c:3673) ==21707== by 0x4ECE859: g_main_context_iterate (gmain.c:3744) ==21707== by 0x4ECEC7F: g_main_loop_run (gmain.c:3938) ==21707== by 0x41C197: some_thread (some-code.c:224) ==21707== ==21707== This conflicts with a previous write of size 4 by thread #5 ==21707== Locks held: 1, at address 0x54CF320 ==21707== at 0x4ECC174: g_source_callback_unref (gmain.c:1528) ==21707== by 0x4ECB86F: g_source_destroy_internal (gmain.c:1178) ==21707== by 0x4ECB9D4: g_source_destroy (gmain.c:1227) ==21707== by 0x41CF09: some_other_thread (some-other-code.c:410) https://bugzilla.gnome.org/show_bug.cgi?id=737677
This commit is contained in:
parent
030efac077
commit
d73f8eec48
@ -300,7 +300,7 @@ struct _GMainContext
|
||||
|
||||
struct _GSourceCallback
|
||||
{
|
||||
guint ref_count;
|
||||
volatile gint ref_count;
|
||||
GSourceFunc func;
|
||||
gpointer data;
|
||||
GDestroyNotify notify;
|
||||
@ -1551,7 +1551,7 @@ g_source_callback_ref (gpointer cb_data)
|
||||
{
|
||||
GSourceCallback *callback = cb_data;
|
||||
|
||||
callback->ref_count++;
|
||||
g_atomic_int_inc (&callback->ref_count);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1559,8 +1559,7 @@ g_source_callback_unref (gpointer cb_data)
|
||||
{
|
||||
GSourceCallback *callback = cb_data;
|
||||
|
||||
callback->ref_count--;
|
||||
if (callback->ref_count == 0)
|
||||
if (g_atomic_int_dec_and_test (&callback->ref_count))
|
||||
{
|
||||
if (callback->notify)
|
||||
callback->notify (callback->data);
|
||||
|
Loading…
x
Reference in New Issue
Block a user