diff --git a/gobject/gsignal.c b/gobject/gsignal.c index deaf66e47..32453bc51 100644 --- a/gobject/gsignal.c +++ b/gobject/gsignal.c @@ -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 (); }