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_id = signal_parse_name (detailed_signal, itype, &detail, force_detail_quark);
SIGNAL_UNLOCK ();
node = signal_id ? LOOKUP_SIGNAL_NODE (signal_id) : NULL;
if (!node || node->destroyed ||
(detail && !(node->flags & G_SIGNAL_DETAILED)))
return FALSE;
{
SIGNAL_UNLOCK ();
return FALSE;
}
SIGNAL_UNLOCK ();
if (signal_id_p)
*signal_id_p = signal_id;
@ -2618,6 +2623,10 @@ g_signal_connect_data (gpointer instance,
return handler_seq_no;
}
static void
signal_handler_block_unlocked (gpointer instance,
gulong handler_id);
/**
* g_signal_handler_block:
* @instance: (type GObject.Object): The instance to block the signal handler of.
@ -2636,12 +2645,20 @@ void
g_signal_handler_block (gpointer instance,
gulong handler_id)
{
Handler *handler;
g_return_if_fail (G_TYPE_CHECK_INSTANCE (instance));
g_return_if_fail (handler_id > 0);
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);
if (handler)
{
@ -2653,9 +2670,12 @@ g_signal_handler_block (gpointer instance,
}
else
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:
* @instance: (type GObject.Object): The instance to unblock the signal handler of.
@ -2679,12 +2699,20 @@ void
g_signal_handler_unblock (gpointer instance,
gulong handler_id)
{
Handler *handler;
g_return_if_fail (G_TYPE_CHECK_INSTANCE (instance));
g_return_if_fail (handler_id > 0);
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);
if (handler)
{
@ -2695,9 +2723,12 @@ g_signal_handler_unblock (gpointer instance,
}
else
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:
* @instance: (type GObject.Object): The instance to remove the signal handler from.
@ -2714,12 +2745,20 @@ void
g_signal_handler_disconnect (gpointer instance,
gulong handler_id)
{
Handler *handler;
g_return_if_fail (G_TYPE_CHECK_INSTANCE (instance));
g_return_if_fail (handler_id > 0);
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);
if (handler)
{
@ -2731,7 +2770,6 @@ g_signal_handler_disconnect (gpointer instance,
}
else
g_warning ("%s: instance '%p' has no handler with id '%lu'", G_STRLOC, instance, handler_id);
SIGNAL_UNLOCK ();
}
/**
@ -2862,33 +2900,31 @@ g_signal_handler_find (gpointer instance,
return handler_seq_no;
}
typedef void (*CallbackHandlerFunc) (gpointer instance, gulong handler_seq_no);
static guint
signal_handlers_foreach_matched_R (gpointer instance,
GSignalMatchType mask,
guint signal_id,
GQuark detail,
GClosure *closure,
gpointer func,
gpointer data,
void (*callback) (gpointer instance,
gulong handler_seq_no))
signal_handlers_foreach_matched_unlocked_R (gpointer instance,
GSignalMatchType mask,
guint signal_id,
GQuark detail,
GClosure *closure,
gpointer func,
gpointer data,
CallbackHandlerFunc callback)
{
HandlerMatch *mlist;
guint n_handlers = 0;
mlist = handlers_find (instance, mask, signal_id, detail, closure, func, data, FALSE);
while (mlist)
{
n_handlers++;
if (mlist->handler->sequential_number)
{
SIGNAL_UNLOCK ();
callback (instance, mlist->handler->sequential_number);
SIGNAL_LOCK ();
}
callback (instance, mlist->handler->sequential_number);
mlist = handler_match_free1_R (mlist, instance);
}
return n_handlers;
}
@ -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))
{
SIGNAL_LOCK ();
n_handlers = signal_handlers_foreach_matched_R (instance, mask, signal_id, detail,
closure, func, data,
g_signal_handler_block);
n_handlers =
signal_handlers_foreach_matched_unlocked_R (instance, mask, signal_id, detail,
closure, func, data,
signal_handler_block_unlocked);
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))
{
SIGNAL_LOCK ();
n_handlers = signal_handlers_foreach_matched_R (instance, mask, signal_id, detail,
closure, func, data,
g_signal_handler_unblock);
n_handlers =
signal_handlers_foreach_matched_unlocked_R (instance, mask, signal_id, detail,
closure, func, data,
signal_handler_unblock_unlocked);
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))
{
SIGNAL_LOCK ();
n_handlers = signal_handlers_foreach_matched_R (instance, mask, signal_id, detail,
closure, func, data,
g_signal_handler_disconnect);
n_handlers =
signal_handlers_foreach_matched_unlocked_R (instance, mask, signal_id, detail,
closure, func, data,
signal_handler_disconnect_unlocked);
SIGNAL_UNLOCK ();
}