Commit d73f8eec authored by Philip Withnall's avatar Philip Withnall Committed by Philip Withnall
Browse files

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== 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)
parent 030efac0
......@@ -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;
g_atomic_int_inc (&callback->ref_count);
static void
......@@ -1559,8 +1559,7 @@ g_source_callback_unref (gpointer cb_data)
GSourceCallback *callback = cb_data;
if (callback->ref_count == 0)
if (g_atomic_int_dec_and_test (&callback->ref_count))
if (callback->notify)
callback->notify (callback->data);
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment