mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-02-03 01:36:17 +01:00
gmain: make g_source_add_child_source() thread safe
g_source_add_child_source() releases the context lock before attaching child_source to context. And this causes trouble if parent source is blocked and g_main_dispatch() manages to lock the context mutex and call unblock_source() before child_source gets attached to context. To fix this we call g_source_attach_unlocked() before releasing the context mutex. https://bugzilla.gnome.org/show_bug.cgi?id=711064
This commit is contained in:
parent
89f9615835
commit
64909ff740
21
glib/gmain.c
21
glib/gmain.c
@ -1111,7 +1111,8 @@ assign_source_id_unlocked (GMainContext *context,
|
|||||||
|
|
||||||
static guint
|
static guint
|
||||||
g_source_attach_unlocked (GSource *source,
|
g_source_attach_unlocked (GSource *source,
|
||||||
GMainContext *context)
|
GMainContext *context,
|
||||||
|
gboolean do_wakeup)
|
||||||
{
|
{
|
||||||
GSList *tmp_list;
|
GSList *tmp_list;
|
||||||
|
|
||||||
@ -1136,10 +1137,16 @@ g_source_attach_unlocked (GSource *source,
|
|||||||
tmp_list = source->priv->child_sources;
|
tmp_list = source->priv->child_sources;
|
||||||
while (tmp_list)
|
while (tmp_list)
|
||||||
{
|
{
|
||||||
g_source_attach_unlocked (tmp_list->data, context);
|
g_source_attach_unlocked (tmp_list->data, context, FALSE);
|
||||||
tmp_list = tmp_list->next;
|
tmp_list = tmp_list->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* If another thread has acquired the context, wake it up since it
|
||||||
|
* might be in poll() right now.
|
||||||
|
*/
|
||||||
|
if (do_wakeup && context->owner && context->owner != G_THREAD_SELF)
|
||||||
|
g_wakeup_signal (context->wakeup);
|
||||||
|
|
||||||
return source->source_id;
|
return source->source_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1168,13 +1175,7 @@ g_source_attach (GSource *source,
|
|||||||
|
|
||||||
LOCK_CONTEXT (context);
|
LOCK_CONTEXT (context);
|
||||||
|
|
||||||
result = g_source_attach_unlocked (source, context);
|
result = g_source_attach_unlocked (source, context, TRUE);
|
||||||
|
|
||||||
/* If another thread has acquired the context, wake it up since it
|
|
||||||
* might be in poll() right now.
|
|
||||||
*/
|
|
||||||
if (context->owner && context->owner != G_THREAD_SELF)
|
|
||||||
g_wakeup_signal (context->wakeup);
|
|
||||||
|
|
||||||
UNLOCK_CONTEXT (context);
|
UNLOCK_CONTEXT (context);
|
||||||
|
|
||||||
@ -1433,8 +1434,8 @@ g_source_add_child_source (GSource *source,
|
|||||||
|
|
||||||
if (context)
|
if (context)
|
||||||
{
|
{
|
||||||
|
g_source_attach_unlocked (child_source, context, TRUE);
|
||||||
UNLOCK_CONTEXT (context);
|
UNLOCK_CONTEXT (context);
|
||||||
g_source_attach (child_source, context);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user