Merge branch 'gsignal-threading-cleanup' into 'main'

gsignal: Perform signal unlocked handlers block, unblock and disconnect ops

See merge request GNOME/glib!2823
This commit is contained in:
Philip Withnall 2022-07-15 21:36:28 +00:00
commit b33ba73532

View File

@ -1216,12 +1216,17 @@ g_signal_parse_name (const gchar *detailed_signal,
SIGNAL_LOCK (); SIGNAL_LOCK ();
signal_id = signal_parse_name (detailed_signal, itype, &detail, force_detail_quark); signal_id = signal_parse_name (detailed_signal, itype, &detail, force_detail_quark);
SIGNAL_UNLOCK ();
node = signal_id ? LOOKUP_SIGNAL_NODE (signal_id) : NULL; node = signal_id ? LOOKUP_SIGNAL_NODE (signal_id) : NULL;
if (!node || node->destroyed || if (!node || node->destroyed ||
(detail && !(node->flags & G_SIGNAL_DETAILED))) (detail && !(node->flags & G_SIGNAL_DETAILED)))
return FALSE; {
SIGNAL_UNLOCK ();
return FALSE;
}
SIGNAL_UNLOCK ();
if (signal_id_p) if (signal_id_p)
*signal_id_p = signal_id; *signal_id_p = signal_id;
@ -2618,6 +2623,10 @@ g_signal_connect_data (gpointer instance,
return handler_seq_no; return handler_seq_no;
} }
static void
signal_handler_block_unlocked (gpointer instance,
gulong handler_id);
/** /**
* g_signal_handler_block: * g_signal_handler_block:
* @instance: (type GObject.Object): The instance to block the signal handler of. * @instance: (type GObject.Object): The instance to block the signal handler of.
@ -2636,12 +2645,20 @@ void
g_signal_handler_block (gpointer instance, g_signal_handler_block (gpointer instance,
gulong handler_id) gulong handler_id)
{ {
Handler *handler;
g_return_if_fail (G_TYPE_CHECK_INSTANCE (instance)); g_return_if_fail (G_TYPE_CHECK_INSTANCE (instance));
g_return_if_fail (handler_id > 0); g_return_if_fail (handler_id > 0);
SIGNAL_LOCK (); SIGNAL_LOCK ();
signal_handler_block_unlocked (instance, handler_id);
SIGNAL_UNLOCK ();
}
static void
signal_handler_block_unlocked (gpointer instance,
gulong handler_id)
{
Handler *handler;
handler = handler_lookup (instance, handler_id, NULL, NULL); handler = handler_lookup (instance, handler_id, NULL, NULL);
if (handler) if (handler)
{ {
@ -2653,9 +2670,12 @@ g_signal_handler_block (gpointer instance,
} }
else else
g_warning ("%s: instance '%p' has no handler with id '%lu'", G_STRLOC, instance, handler_id); g_warning ("%s: instance '%p' has no handler with id '%lu'", G_STRLOC, instance, handler_id);
SIGNAL_UNLOCK ();
} }
static void
signal_handler_unblock_unlocked (gpointer instance,
gulong handler_id);
/** /**
* g_signal_handler_unblock: * g_signal_handler_unblock:
* @instance: (type GObject.Object): The instance to unblock the signal handler of. * @instance: (type GObject.Object): The instance to unblock the signal handler of.
@ -2679,12 +2699,20 @@ void
g_signal_handler_unblock (gpointer instance, g_signal_handler_unblock (gpointer instance,
gulong handler_id) gulong handler_id)
{ {
Handler *handler;
g_return_if_fail (G_TYPE_CHECK_INSTANCE (instance)); g_return_if_fail (G_TYPE_CHECK_INSTANCE (instance));
g_return_if_fail (handler_id > 0); g_return_if_fail (handler_id > 0);
SIGNAL_LOCK (); SIGNAL_LOCK ();
signal_handler_unblock_unlocked (instance, handler_id);
SIGNAL_UNLOCK ();
}
static void
signal_handler_unblock_unlocked (gpointer instance,
gulong handler_id)
{
Handler *handler;
handler = handler_lookup (instance, handler_id, NULL, NULL); handler = handler_lookup (instance, handler_id, NULL, NULL);
if (handler) if (handler)
{ {
@ -2695,9 +2723,12 @@ g_signal_handler_unblock (gpointer instance,
} }
else else
g_warning ("%s: instance '%p' has no handler with id '%lu'", G_STRLOC, instance, handler_id); g_warning ("%s: instance '%p' has no handler with id '%lu'", G_STRLOC, instance, handler_id);
SIGNAL_UNLOCK ();
} }
static void
signal_handler_disconnect_unlocked (gpointer instance,
gulong handler_id);
/** /**
* g_signal_handler_disconnect: * g_signal_handler_disconnect:
* @instance: (type GObject.Object): The instance to remove the signal handler from. * @instance: (type GObject.Object): The instance to remove the signal handler from.
@ -2714,12 +2745,20 @@ void
g_signal_handler_disconnect (gpointer instance, g_signal_handler_disconnect (gpointer instance,
gulong handler_id) gulong handler_id)
{ {
Handler *handler;
g_return_if_fail (G_TYPE_CHECK_INSTANCE (instance)); g_return_if_fail (G_TYPE_CHECK_INSTANCE (instance));
g_return_if_fail (handler_id > 0); g_return_if_fail (handler_id > 0);
SIGNAL_LOCK (); SIGNAL_LOCK ();
signal_handler_disconnect_unlocked (instance, handler_id);
SIGNAL_UNLOCK ();
}
static void
signal_handler_disconnect_unlocked (gpointer instance,
gulong handler_id)
{
Handler *handler;
handler = handler_lookup (instance, handler_id, 0, 0); handler = handler_lookup (instance, handler_id, 0, 0);
if (handler) if (handler)
{ {
@ -2731,7 +2770,6 @@ g_signal_handler_disconnect (gpointer instance,
} }
else else
g_warning ("%s: instance '%p' has no handler with id '%lu'", G_STRLOC, instance, handler_id); g_warning ("%s: instance '%p' has no handler with id '%lu'", G_STRLOC, instance, handler_id);
SIGNAL_UNLOCK ();
} }
/** /**
@ -2862,16 +2900,17 @@ g_signal_handler_find (gpointer instance,
return handler_seq_no; return handler_seq_no;
} }
typedef void (*CallbackHandlerFunc) (gpointer instance, gulong handler_seq_no);
static guint static guint
signal_handlers_foreach_matched_R (gpointer instance, signal_handlers_foreach_matched_unlocked_R (gpointer instance,
GSignalMatchType mask, GSignalMatchType mask,
guint signal_id, guint signal_id,
GQuark detail, GQuark detail,
GClosure *closure, GClosure *closure,
gpointer func, gpointer func,
gpointer data, gpointer data,
void (*callback) (gpointer instance, CallbackHandlerFunc callback)
gulong handler_seq_no))
{ {
HandlerMatch *mlist; HandlerMatch *mlist;
guint n_handlers = 0; guint n_handlers = 0;
@ -2881,11 +2920,8 @@ signal_handlers_foreach_matched_R (gpointer instance,
{ {
n_handlers++; n_handlers++;
if (mlist->handler->sequential_number) if (mlist->handler->sequential_number)
{ callback (instance, mlist->handler->sequential_number);
SIGNAL_UNLOCK ();
callback (instance, mlist->handler->sequential_number);
SIGNAL_LOCK ();
}
mlist = handler_match_free1_R (mlist, instance); mlist = handler_match_free1_R (mlist, instance);
} }
@ -2930,9 +2966,10 @@ g_signal_handlers_block_matched (gpointer instance,
if (mask & (G_SIGNAL_MATCH_CLOSURE | G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA)) if (mask & (G_SIGNAL_MATCH_CLOSURE | G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA))
{ {
SIGNAL_LOCK (); SIGNAL_LOCK ();
n_handlers = signal_handlers_foreach_matched_R (instance, mask, signal_id, detail, n_handlers =
closure, func, data, signal_handlers_foreach_matched_unlocked_R (instance, mask, signal_id, detail,
g_signal_handler_block); closure, func, data,
signal_handler_block_unlocked);
SIGNAL_UNLOCK (); SIGNAL_UNLOCK ();
} }
@ -2978,9 +3015,10 @@ g_signal_handlers_unblock_matched (gpointer instance,
if (mask & (G_SIGNAL_MATCH_CLOSURE | G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA)) if (mask & (G_SIGNAL_MATCH_CLOSURE | G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA))
{ {
SIGNAL_LOCK (); SIGNAL_LOCK ();
n_handlers = signal_handlers_foreach_matched_R (instance, mask, signal_id, detail, n_handlers =
closure, func, data, signal_handlers_foreach_matched_unlocked_R (instance, mask, signal_id, detail,
g_signal_handler_unblock); closure, func, data,
signal_handler_unblock_unlocked);
SIGNAL_UNLOCK (); SIGNAL_UNLOCK ();
} }
@ -3026,9 +3064,10 @@ g_signal_handlers_disconnect_matched (gpointer instance,
if (mask & (G_SIGNAL_MATCH_CLOSURE | G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA)) if (mask & (G_SIGNAL_MATCH_CLOSURE | G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA))
{ {
SIGNAL_LOCK (); SIGNAL_LOCK ();
n_handlers = signal_handlers_foreach_matched_R (instance, mask, signal_id, detail, n_handlers =
closure, func, data, signal_handlers_foreach_matched_unlocked_R (instance, mask, signal_id, detail,
g_signal_handler_disconnect); closure, func, data,
signal_handler_disconnect_unlocked);
SIGNAL_UNLOCK (); SIGNAL_UNLOCK ();
} }