mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-01-26 14:06:15 +01:00
signals: Ensure we ref handler in emission fast path
We need to keep a reference to the handler in the fast path, just like in the slow path, otherwise if another thread disconnects the handler we may destroy the closure while we're using it without the lock held. We also move the freeing of the instance to after the emission is totally done as the handler_unref_R (and the tracepoint) reference it. https://bugzilla.gnome.org/show_bug.cgi?id=694253
This commit is contained in:
parent
3e274423ba
commit
aede774642
@ -3127,6 +3127,7 @@ g_signal_emit_valist (gpointer instance,
|
||||
)
|
||||
{
|
||||
HandlerList* hlist = handler_list_lookup (node->signal_id, instance);
|
||||
Handler *fastpath_handler = NULL;
|
||||
Handler *l;
|
||||
GClosure *closure = NULL;
|
||||
gboolean fastpath = TRUE;
|
||||
@ -3159,6 +3160,7 @@ g_signal_emit_valist (gpointer instance,
|
||||
}
|
||||
else
|
||||
{
|
||||
fastpath_handler = l;
|
||||
closure = l->closure;
|
||||
if (l->after)
|
||||
run_type = G_SIGNAL_RUN_LAST;
|
||||
@ -3207,6 +3209,9 @@ g_signal_emit_valist (gpointer instance,
|
||||
emission.chain_type = instance_type;
|
||||
emission_push (&g_recursive_emissions, &emission);
|
||||
|
||||
if (fastpath_handler)
|
||||
handler_ref (fastpath_handler);
|
||||
|
||||
SIGNAL_UNLOCK ();
|
||||
|
||||
TRACE(GOBJECT_SIGNAL_EMIT(signal_id, detail, instance, instance_type));
|
||||
@ -3227,7 +3232,6 @@ g_signal_emit_valist (gpointer instance,
|
||||
node->n_params,
|
||||
node->param_types);
|
||||
accumulate (&emission.ihint, &emission_return, &accu, accumulator);
|
||||
g_object_unref (instance);
|
||||
}
|
||||
|
||||
SIGNAL_LOCK ();
|
||||
@ -3235,6 +3239,9 @@ g_signal_emit_valist (gpointer instance,
|
||||
emission.chain_type = G_TYPE_NONE;
|
||||
emission_pop (&g_recursive_emissions, &emission);
|
||||
|
||||
if (fastpath_handler)
|
||||
handler_unref_R (signal_id, instance, fastpath_handler);
|
||||
|
||||
SIGNAL_UNLOCK ();
|
||||
|
||||
if (accumulator)
|
||||
@ -3267,6 +3274,9 @@ g_signal_emit_valist (gpointer instance,
|
||||
|
||||
TRACE(GOBJECT_SIGNAL_EMIT_END(signal_id, detail, instance, instance_type));
|
||||
|
||||
if (closure != NULL)
|
||||
g_object_unref (instance);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user