destroy all signals that the finalized obejct type introduced.
authorTim Janik <timj@gtk.org>
Wed, 1 Nov 2000 03:03:04 +0000 (03:03 +0000)
committerTim Janik <timj@src.gnome.org>
Wed, 1 Nov 2000 03:03:04 +0000 (03:03 +0000)
Wed Nov  1 03:36:54 2000  Tim Janik  <timj@gtk.org>

        * gobject.c (g_object_base_class_finalize): destroy all signals that
        the finalized obejct type introduced.

        * gsignal.c (g_signals_destroy): don't require itype to have
        signals.

        * gobject.c (g_object_do_finalize): make sure all signal handlers
        are destroyed.

        * gsignal.[hc]:
        (g_signal_handler_find): only match on non-0 masks.
        (g_signal_handlers_block_matched):
        (g_signal_handlers_unblock_matched):
        (g_signal_handlers_disconnect_matched): new functions to block/unblock
        or disconnect handlers in groups.

docs/reference/gobject/gobject-sections.txt
docs/reference/gobject/tmpl/signals.sgml
gobject/ChangeLog
gobject/gobject.c
gobject/gsignal.c
gobject/gsignal.h

index 8f352b49d2d151e2c89279ade15571908c1642db..8046cd62366991232cd77bf01e6818aa91b92369 100644 (file)
@@ -337,10 +337,13 @@ g_signal_name
 g_signal_query
 g_signal_list_ids
 g_signal_connect_closure
-g_signal_handler_find
 g_signal_handler_block
 g_signal_handler_unblock
 g_signal_handler_disconnect
+g_signal_handler_find
+g_signal_handlers_block_matched
+g_signal_handlers_unblock_matched
+g_signal_handlers_disconnect_matched
 g_signal_has_handler_pending
 g_signal_stop_emission
 g_signal_type_closure_new
index 265d1651321413a3271e2d33a6408f240d298df9..5f3c351182a3d270d6ba2ceb691bd0b050fb3bc8 100644 (file)
@@ -76,9 +76,9 @@ The @GSignalInvocationHint structure is used to pass on additional information
 to callbacks during a signal emission.
 </para>
 
-@signal_id:    The signal id of the signal invoking the callback
-@detail:       The detail passed on for this emission
-@run_type:     The stage the signal emission is currently in, this
+@signal_id: The signal id of the signal invoking the callback
+@detail: The detail passed on for this emission
+@run_type: The stage the signal emission is currently in, this
                field will contain one of @G_SIGNAL_RUN_FIRST,
                @G_SIGNAL_RUN_LAST or @G_SIGNAL_RUN_CLEANUP.
 
@@ -92,11 +92,11 @@ values is perfomed. The return value of signal emissions is then the
 value returned by the last callback.
 </para>
 
-@ihint:                Signal invokation hint, see @GSignalInvocationHint
-@return_accu:  Accumulator to collect callback return values in, this
+@ihint: Signal invokation hint, see @GSignalInvocationHint
+@return_accu: Accumulator to collect callback return values in, this
                is the return value of the current signal emission
-@return_value: The return value of the most recent callback function
-@Returns:      The accumulator function returns whether the signal emission
+@return_value: The return value of the most recent callback function
+@Returns: The accumulator function returns whether the signal emission
                should be aborted. Returning @FALSE means to abort the
                current emission and @TRUE is returned for continuation.
 
@@ -153,14 +153,14 @@ A structure holding in-depth information for a specific signal. It is
 filled in by the g_signal_query() function.
 </para>
 
-@signal_id:    The signal id of the signal being querried, or 0 if the
+@signal_id: The signal id of the signal being querried, or 0 if the
                signal to be querried was unknown
-@signal_name:  The signal name
-@itype:                The interface/instance type that this signal can be emitted for
-@signal_flags: The signal flags as passed in to @g_signal_new()
-@return_type:  The return type for user callbacks
-@n_params:     The number of parameters that user callbacks take
-@param_types:  The individual parameter types for user callbacks, note that the
+@signal_name: The signal name
+@itype: The interface/instance type that this signal can be emitted for
+@signal_flags: The signal flags as passed in to @g_signal_new()
+@return_type: The return type for user callbacks
+@n_params: The number of parameters that user callbacks take
+@param_types: The individual parameter types for user callbacks, note that the
                effective callback signature is:
 <msgtext><programlisting>
 @return_type callback (@gpointer     data1,
@@ -225,8 +225,8 @@ is 0. All members filled into the @GSignalQuery structure should
 be considered constant and have to be left untouched.
 </para>
 
-@signal_id:    The signal id of the signal to query information for
-@query:                A user provided structure that is filled in with constant
+@signal_id: The signal id of the signal to query information for
+@query: A user provided structure that is filled in with constant
                values upon success.
 
 
@@ -237,9 +237,9 @@ created. Further information about the signals can be aquired through
 g_signal_query().
 </para>
 
-@itype:                Instance or interface type
-@n_ids:                Location to store the number of signal ids for @itype
-@Returns:      Newly allocated array of signal ids
+@itype: Instance or interface type
+@n_ids: Location to store the number of signal ids for @itype
+@Returns: Newly allocated array of signal ids
 
 
 <!-- ##### FUNCTION g_signal_connect_closure ##### -->
@@ -255,46 +255,144 @@ g_signal_query().
 @Returns: 
 
 
-<!-- ##### FUNCTION g_signal_handler_find ##### -->
+<!-- ##### FUNCTION g_signal_handler_block ##### -->
 <para>
+g_signal_handler_block() blocks a handler of an
+instance so it will not be called during any signal emissions
+unless it is unblocked again. Thus "blocking" a signal handler
+means to temporarily deactive it, a signal handler has to be
+unblocked exactly the same amount of times it has been blocked
+before to become active again.
+The @handler_id passed into g_signal_handler_block() has
+to be a valid signal handler id, connected to a signal of
+@instance.
+</para>
+
+@instance: The instance to block the signal handler of
+@handler_id: Handler id of the handler to be blocked
 
+<!-- ##### FUNCTION g_signal_handler_unblock ##### -->
+<para>
+g_signal_handler_unblock() undoes the effect of a previous
+g_signal_handler_block() call. A blocked handler is skipped
+during signal emissions and will not be invoked, unblocking
+it (for exactly the amount of times it has been blocked before)
+reverts its "blocked" state, so the handler will be recognized
+by the signal system and is called upon future or currently
+ongoing signal emissions (since the order in which handlers are
+called during signal emissions is deterministic, whether the
+unblocked handler in question is called as part of a currently
+ongoing emission depends on how far that emission has proceeded
+yet).
+The @handler_id passed into g_signal_handler_unblock() has
+to be a valid id of a signal handler that is connected to a
+signal of @instance and is currently blocked.
 </para>
 
-@instance: 
-@mask: 
-@signal_id: 
-@detail: 
-@closure: 
-@func: 
-@data: 
-@Returns: 
+@instance: The instance to unblock the signal handler of
+@handler_id: Handler id of the handler to be unblocked
 
 
-<!-- ##### FUNCTION g_signal_handler_block ##### -->
+<!-- ##### FUNCTION g_signal_handler_disconnect ##### -->
 <para>
-
+g_signal_handler_disconnect() disconnects a handler from an
+instance so it will not be called during any future or currently
+ongoing emissions of the signal it has been connected to.
+The @handler_id becomes invalid and may be reused.
+The @handler_id passed into g_signal_handler_disconnect() has
+to be a valid signal handler id, connected to a signal of
+@instance.
 </para>
 
-@instance: 
-@handler_id: 
+@instance: The instance to remove the signal handler from
+@handler_id: Handler id of the handler to be disconnected
 
 
-<!-- ##### FUNCTION g_signal_handler_unblock ##### -->
+<!-- ##### FUNCTION g_signal_handler_find ##### -->
 <para>
+Find the first signal handler that matches certain selection criteria.
+The criteria mask is passed as an OR-ed combination of #GSignalMatchType
+flags, and the criteria values are passed as arguments.
+The match @mask has to be non-0 for successfull matches.
+If no handler was found, 0 is returned.
+</para>
 
+@instance: The instance owning the signal handler to be found
+@mask: Mask indicating which of @signal_id, @detail,
+               @closure, @func and/or @data the handler has to match
+@signal_id: Signal the handler has to be connected to
+@detail: Signal detail the handler has to be connected to
+@closure: The closure the handler will invoke
+@func: The C closure callback of the handler (useless for non-C closures)
+@data: The closure data of the handler's closure
+@Returns: A valid non-0 signal handler id for a successfull match
+
+
+<!-- ##### FUNCTION g_signal_handlers_block_matched ##### -->
+<para>
+This function blocks all handlers on an instance that match a certain
+selection criteria. The criteria mask is passed as an OR-ed combination of
+#GSignalMatchType flags, and the criteria values are passed as arguments.
+Passing at least one of the %G_SIGNAL_MATCH_CLOSURE, %G_SIGNAL_MATCH_FUNC
+or %G_SIGNAL_MATCH_DATA match flags is required for successfull matches.
+If no handlers were found, 0 is returned, the number of blocked handlers
+otherwise.
 </para>
 
-@instance: 
-@handler_id: 
+@instance: The instance to block handlers from
+@mask: Mask indicating which of @signal_id, @detail,
+       @closure, @func and/or @data the handlers have to match
+@signal_id: Signal the handlers have to be connected to
+@detail: Signal detail the handlers have to be connected to
+@closure: The closure the handlers will invoke
+@func: The C closure callback of the handlers (useless for non-C closures)
+@data: The closure data of the handlers' closures
+@Returns: The amount of handlers that got blocked
 
 
-<!-- ##### FUNCTION g_signal_handler_disconnect ##### -->
+<!-- ##### FUNCTION g_signal_handlers_unblock_matched ##### -->
 <para>
+This function unblocks all handlers on an instance that match a certain
+selection criteria. The criteria mask is passed as an OR-ed combination of
+#GSignalMatchType flags, and the criteria values are passed as arguments.
+Passing at least one of the %G_SIGNAL_MATCH_CLOSURE, %G_SIGNAL_MATCH_FUNC
+or %G_SIGNAL_MATCH_DATA match flags is required for successfull matches.
+If no handlers were found, 0 is returned, the number of unblocked handlers
+otherwise. The match criteria should not apply to any handlers that are
+not currently blocked.
+</para>
+
+@instance: The instance to unblock handlers from
+@mask: Mask indicating which of @signal_id, @detail,
+               @closure, @func and/or @data the handlers have to match
+@signal_id: Signal the handlers have to be connected to
+@detail: Signal detail the handlers have to be connected to
+@closure: The closure the handlers will invoke
+@func: The C closure callback of the handlers (useless for non-C closures)
+@data: The closure data of the handlers' closures
+@Returns: The amount of handlers that got unblocked
 
+
+<!-- ##### FUNCTION g_signal_handlers_disconnect_matched ##### -->
+<para>
+This function disconnects all handlers on an instance that match a certain
+selection criteria. The criteria mask is passed as an OR-ed combination of
+#GSignalMatchType flags, and the criteria values are passed as arguments.
+Passing at least one of the %G_SIGNAL_MATCH_CLOSURE, %G_SIGNAL_MATCH_FUNC
+or %G_SIGNAL_MATCH_DATA match flags is required for successfull matches.
+If no handlers were found, 0 is returned, the number of disconnected handlers
+otherwise.
 </para>
 
-@instance: 
-@handler_id: 
+@instance: The instance to remove handlers from
+@mask: Mask indicating which of @signal_id, @detail,
+       @closure, @func and/or @data the handlers have to match
+@signal_id: Signal the handlers have to be connected to
+@detail: Signal detail the handlers have to be connected to
+@closure: The closure the handlers will invoke
+@func: The C closure callback of the handlers (useless for non-C closures)
+@data: The closure data of the handlers' closures
+@Returns: The amount of handlers that got disconnected
 
 
 <!-- ##### FUNCTION g_signal_has_handler_pending ##### -->
index 312b4615861993d8ff10b33c998aa79a9e114ac6..85e21cc5078f113b25e317f450ae22dd082211c8 100644 (file)
@@ -1,3 +1,21 @@
+Wed Nov  1 03:36:54 2000  Tim Janik  <timj@gtk.org>
+
+       * gobject.c (g_object_base_class_finalize): destroy all signals that
+       the finalized obejct type introduced.
+
+       * gsignal.c (g_signals_destroy): don't require itype to have
+       signals.
+
+       * gobject.c (g_object_do_finalize): make sure all signal handlers
+       are destroyed.
+
+       * gsignal.[hc]:
+       (g_signal_handler_find): only match on non-0 masks.
+       (g_signal_handlers_block_matched):
+       (g_signal_handlers_unblock_matched):
+       (g_signal_handlers_disconnect_matched): new functions to block/unblock
+       or disconnect handlers in groups.
+
 2000-10-30  Sebastian Wilhelmi  <wilhelmi@ira.uka.de>
 
        * gvalue.c (exchange_entries_equal), gparam.c (param_spec_equals):
index f50f346ea82a81b3dff2f455af5237d670b29e16..5aa99d8bc8114ecc2893fee4add69a3ad7393e36 100644 (file)
  * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
  * Boston, MA 02111-1307, USA.
  */
+#include "gobject.h"
 
-#include <string.h>
 
-#include "gobject.h"
 #include "gvaluecollector.h"
+#include "gsignal.h"
+#include <string.h>
 
 
 #define        DEBUG_OBJECTS
@@ -162,6 +163,8 @@ g_object_base_class_finalize (GObjectClass *class)
   guint i;
   
   g_message ("finallizing base class of %s", G_OBJECT_CLASS_NAME (class));
+
+  g_signals_destroy (G_OBJECT_CLASS_TYPE (class));
   
   for (i = 0; i < class->n_param_specs; i++)
     {
@@ -292,6 +295,7 @@ g_object_do_shutdown (GObject *object)
 static void
 g_object_do_finalize (GObject *object)
 {
+  g_signal_handlers_destroy (object);
   g_datalist_clear (&object->qdata);
   
 #ifdef DEBUG_OBJECTS
index 26f317658797d7c31e2ad8249f65ff3d57bf4817..35fe060a6aab54b3c0ac2d4d0d4b57458aac6f9e 100644 (file)
@@ -344,7 +344,7 @@ handler_find (gpointer         instance,
            ((mask & G_SIGNAL_MATCH_FUNC) || (handler->closure->marshal == node->c_marshaller &&
                                              handler->closure->meta_marshal == 0 &&
                                              ((GCClosure*) handler->closure)->callback == func)))
-          return handler;
+         return handler;
     }
   else
     {
@@ -376,7 +376,7 @@ handler_find (gpointer         instance,
                    ((mask & G_SIGNAL_MATCH_FUNC) || (handler->closure->marshal == node->c_marshaller &&
                                                      handler->closure->meta_marshal == 0 &&
                                                      ((GCClosure*) handler->closure)->callback == func)))
-                  return handler;
+                 return handler;
             }
         }
     }
@@ -571,7 +571,6 @@ void
 g_signals_destroy (GType itype)
 {
   guint i;
-  gboolean found_one = FALSE;
   
   G_LOCK (g_signal_mutex);
   for (i = 0; i < g_n_signal_nodes; i++)
@@ -585,15 +584,9 @@ g_signals_destroy (GType itype)
                        node->name,
                        g_type_name (node->itype));
           else
-            {
-              found_one = TRUE;
-              signal_destroy_R (node);
-            }
+           signal_destroy_R (node);
         }
     }
-  if (!found_one)
-    g_warning (G_STRLOC ": type `%s' has no signals that could be destroyed",
-               g_type_name (itype));
   G_UNLOCK (g_signal_mutex);
 }
 
@@ -917,6 +910,54 @@ g_signal_connect_closure (gpointer  instance,
   return handler_id;
 }
 
+void
+g_signal_handler_block (gpointer instance,
+                        guint    handler_id)
+{
+  Handler *handler;
+  
+  g_return_if_fail (G_TYPE_CHECK_INSTANCE (instance));
+  g_return_if_fail (handler_id > 0);
+  
+  G_LOCK (g_signal_mutex);
+  handler = handler_lookup (instance, handler_id, NULL);
+  if (handler)
+    {
+#ifndef G_DISABLE_CHECKS
+      if (handler->block_count >= HANDLER_MAX_BLOCK_COUNT - 1)
+        g_error (G_STRLOC ": handler block_count overflow, %s", REPORT_BUG);
+#endif
+      
+      handler->block_count += 1;
+    }
+  else
+    g_warning ("%s: instance `%p' has no handler with id `%u'", G_STRLOC, instance, handler_id);
+  G_UNLOCK (g_signal_mutex);
+}
+
+void
+g_signal_handler_unblock (gpointer instance,
+                          guint    handler_id)
+{
+  Handler *handler;
+  
+  g_return_if_fail (G_TYPE_CHECK_INSTANCE (instance));
+  g_return_if_fail (handler_id > 0);
+  
+  G_LOCK (g_signal_mutex);
+  handler = handler_lookup (instance, handler_id, NULL);
+  if (handler)
+    {
+      if (handler->block_count)
+        handler->block_count -= 1;
+      else
+        g_warning (G_STRLOC ": handler `%u' of instance `%p' is not blocked", handler_id, instance);
+    }
+  else
+    g_warning ("%s: instance `%p' has no handler with id `%u'", G_STRLOC, instance, handler_id);
+  G_UNLOCK (g_signal_mutex);
+}
+
 void
 g_signal_handler_disconnect (gpointer instance,
                              guint    handler_id)
@@ -983,82 +1024,143 @@ g_signal_handlers_destroy (gpointer instance)
   G_UNLOCK (g_signal_mutex);
 }
 
-void
-g_signal_handler_block (gpointer instance,
-                        guint    handler_id)
+guint
+g_signal_handler_find (gpointer         instance,
+                       GSignalMatchType mask,
+                       guint            signal_id,
+                      GQuark           detail,
+                       GClosure        *closure,
+                       gpointer         func,
+                       gpointer         data)
 {
   Handler *handler;
+  guint handler_id = 0;
   
-  g_return_if_fail (G_TYPE_CHECK_INSTANCE (instance));
-  g_return_if_fail (handler_id > 0);
-  
-  G_LOCK (g_signal_mutex);
-  handler = handler_lookup (instance, handler_id, NULL);
-  if (handler)
+  g_return_val_if_fail (G_TYPE_CHECK_INSTANCE (instance), 0);
+  g_return_val_if_fail ((mask & ~G_SIGNAL_MATCH_MASK) == 0, 0);
+
+  if (mask & G_SIGNAL_MATCH_MASK)
     {
-#ifndef G_DISABLE_CHECKS
-      if (handler->block_count >= HANDLER_MAX_BLOCK_COUNT - 1)
-        g_error (G_STRLOC ": handler block_count overflow, %s", REPORT_BUG);
-#endif
-      
-      handler->block_count += 1;
+      G_LOCK (g_signal_mutex);
+      handler = handler_find (instance, mask, signal_id, detail, closure, func, data);
+      handler_id = handler ? handler->id : 0;
+      G_UNLOCK (g_signal_mutex);
     }
-  else
-    g_warning ("%s: instance `%p' has no handler with id `%u'", G_STRLOC, instance, handler_id);
-  G_UNLOCK (g_signal_mutex);
+
+  return handler_id;
 }
 
-void
-g_signal_handler_unblock (gpointer instance,
-                          guint    handler_id)
+static guint
+signal_handlers_foreach_matched (gpointer         instance,
+                                GSignalMatchType mask,
+                                guint            signal_id,
+                                GQuark           detail,
+                                GClosure        *closure,
+                                gpointer         func,
+                                gpointer         data,
+                                void           (*callback) (gpointer instance,
+                                                            guint    handler_id))
 {
   Handler *handler;
-  
-  g_return_if_fail (G_TYPE_CHECK_INSTANCE (instance));
-  g_return_if_fail (handler_id > 0);
-  
-  G_LOCK (g_signal_mutex);
-  handler = handler_lookup (instance, handler_id, NULL);
-  if (handler)
+  guint n_handlers = 0;
+
+  handler = handler_find (instance, mask, signal_id, detail, closure, func, data);
+  while (handler && handler->id)
     {
-      if (handler->block_count)
-        handler->block_count -= 1;
-      else
-        g_warning (G_STRLOC ": handler `%u' of instance `%p' is not blocked", handler_id, instance);
+      n_handlers++;
+      G_UNLOCK (g_signal_mutex);
+      callback (instance, handler->id);
+      G_LOCK (g_signal_mutex);
+      /* need constant relookups due to callback */
+      handler = handler_find (instance, mask, signal_id, detail, closure, func, data);
     }
-  else
-    g_warning ("%s: instance `%p' has no handler with id `%u'", G_STRLOC, instance, handler_id);
-  G_UNLOCK (g_signal_mutex);
+
+  return n_handlers;
 }
 
 guint
-g_signal_handler_find (gpointer         instance,
-                       GSignalMatchType mask,
-                       guint            signal_id,
-                      GQuark           detail,
-                       GClosure        *closure,
-                       gpointer         func,
-                       gpointer         data)
+g_signal_handlers_block_matched (gpointer         instance,
+                                GSignalMatchType mask,
+                                guint            signal_id,
+                                GQuark           detail,
+                                GClosure        *closure,
+                                gpointer         func,
+                                gpointer         data)
 {
-  Handler *handler = NULL;
-  guint handler_id;
-  
-  g_return_val_if_fail (G_TYPE_CHECK_INSTANCE (instance), 0);
-  g_return_val_if_fail ((mask & ~G_SIGNAL_MATCH_MASK) == 0, 0);
+  guint n_handlers = 0;
+
+  g_return_val_if_fail (G_TYPE_CHECK_INSTANCE (instance), FALSE);
+  g_return_val_if_fail ((mask & ~G_SIGNAL_MATCH_MASK) == 0, FALSE);
+
+  if (mask & (G_SIGNAL_MATCH_CLOSURE | G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA))
+    {
+      G_LOCK (g_signal_mutex);
+      n_handlers = signal_handlers_foreach_matched (instance, mask, signal_id, detail,
+                                                   closure, func, data,
+                                                   g_signal_handler_block);
+      G_UNLOCK (g_signal_mutex);
+    }
+
+  return n_handlers;
+}
+
+guint
+g_signal_handlers_unblock_matched (gpointer         instance,
+                                  GSignalMatchType mask,
+                                  guint            signal_id,
+                                  GQuark           detail,
+                                  GClosure        *closure,
+                                  gpointer         func,
+                                  gpointer         data)
+{
+  guint n_handlers = 0;
   
-  G_LOCK (g_signal_mutex);
-  handler = handler_find (instance, mask, signal_id, detail, closure, func, data);
-  handler_id = handler ? handler->id : 0;
-  G_UNLOCK (g_signal_mutex);
+  g_return_val_if_fail (G_TYPE_CHECK_INSTANCE (instance), FALSE);
+  g_return_val_if_fail ((mask & ~G_SIGNAL_MATCH_MASK) == 0, FALSE);
   
-  return handler_id;
+  if (mask & (G_SIGNAL_MATCH_CLOSURE | G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA))
+    {
+      G_LOCK (g_signal_mutex);
+      n_handlers = signal_handlers_foreach_matched (instance, mask, signal_id, detail,
+                                                   closure, func, data,
+                                                   g_signal_handler_unblock);
+      G_UNLOCK (g_signal_mutex);
+    }
+
+  return n_handlers;
+}
+
+guint
+g_signal_handlers_disconnect_matched (gpointer         instance,
+                                     GSignalMatchType mask,
+                                     guint            signal_id,
+                                     GQuark           detail,
+                                     GClosure        *closure,
+                                     gpointer         func,
+                                     gpointer         data)
+{
+  guint n_handlers = 0;
+
+  g_return_val_if_fail (G_TYPE_CHECK_INSTANCE (instance), FALSE);
+  g_return_val_if_fail ((mask & ~G_SIGNAL_MATCH_MASK) == 0, FALSE);
+
+  if (mask & (G_SIGNAL_MATCH_CLOSURE | G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA))
+    {
+      G_LOCK (g_signal_mutex);
+      n_handlers = signal_handlers_foreach_matched (instance, mask, signal_id, detail,
+                                                   closure, func, data,
+                                                   g_signal_handler_disconnect);
+      G_UNLOCK (g_signal_mutex);
+    }
+
+  return n_handlers;
 }
 
 gboolean
-g_signal_handler_pending (gpointer instance,
-                          guint    signal_id,
-                         GQuark   detail,
-                          gboolean may_be_blocked)
+g_signal_has_handler_pending (gpointer instance,
+                             guint    signal_id,
+                             GQuark   detail,
+                             gboolean may_be_blocked)
 {
   Handler *handler = NULL;
   
@@ -1108,7 +1210,11 @@ g_signal_emitv (const GValue *instance_and_params,
   node = LOOKUP_SIGNAL_NODE (signal_id);
 #ifndef G_DISABLE_CHECKS
   if (!node || !g_type_conforms_to (G_TYPE_FROM_INSTANCE (instance), node->itype))
-    g_warning ("%s: signal id `%u' is invalid for instance `%p'", G_STRLOC, signal_id, instance);
+    {
+      g_warning ("%s: signal id `%u' is invalid for instance `%p'", G_STRLOC, signal_id, instance);
+      G_UNLOCK (g_signal_mutex);
+      return;
+    }
   if (detail && !(node->flags & G_SIGNAL_DETAILED))
     {
       g_warning ("%s: signal id `%u' does not support detail (%u)", G_STRLOC, signal_id, detail);
index f6db745630d0988496706c2577ca18f269dc945f..92e5a48140b7cc87ecb711f55634c28eb3ae6bba 100644 (file)
@@ -8,7 +8,7 @@
  *
  * This library is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General
@@ -31,9 +31,9 @@ extern "C" {
 
 
 /* --- typedefs --- */
-typedef struct _GSignalQuery            GSignalQuery;
-typedef struct _GSignalInvocationHint   GSignalInvocationHint;
-typedef        GClosureMarshal                  GSignalCMarshaller;
+typedef struct _GSignalQuery            GSignalQuery;
+typedef struct _GSignalInvocationHint   GSignalInvocationHint;
+typedef GClosureMarshal                         GSignalCMarshaller;
 typedef gboolean (*GSignalEmissionHook) (GSignalInvocationHint *ihint,
                                         guint                  n_param_values,
                                         const GValue          *param_values);
@@ -52,7 +52,7 @@ typedef enum
   G_SIGNAL_DETAILED    = 1 << 4,
   G_SIGNAL_ACTION      = 1 << 5,
   G_SIGNAL_NO_HOOKS    = 1 << 6
-#define        G_SIGNAL_FLAGS_MASK  0x7f
+#define G_SIGNAL_FLAGS_MASK  0x7f
 } GSignalFlags;
 typedef enum
 {
@@ -62,7 +62,7 @@ typedef enum
   G_SIGNAL_MATCH_FUNC     = 1 << 3,
   G_SIGNAL_MATCH_DATA     = 1 << 4,
   G_SIGNAL_MATCH_UNBLOCKED = 1 << 5
-#define        G_SIGNAL_MATCH_MASK  0x3f
+#define G_SIGNAL_MATCH_MASK  0x3f
 } GSignalMatchType;
 
 
@@ -86,64 +86,86 @@ struct _GSignalQuery
 
 
 /* --- signals --- */
-guint  g_signal_newv                   (const gchar            *signal_name,
-                                        GType                   itype,
-                                        GSignalFlags            signal_flags,
-                                        GClosure               *class_closure,
-                                        GSignalAccumulator      accumulator,
-                                        GSignalCMarshaller      c_marshaller,
-                                        GType                   return_type,
-                                        guint                   n_params,
-                                        GType                  *param_types);
-void   g_signal_emitv                  (const GValue           *instance_and_params,
-                                        guint                   signal_id,
-                                        GQuark                  detail,
-                                        GValue                 *return_value);
-guint  g_signal_lookup                 (const gchar            *name,
-                                        GType                   itype);
-gchar* g_signal_name                   (guint                   signal_id);
-void   g_signal_query                  (guint                   signal_id,
-                                        GSignalQuery           *query);
-guint* g_signal_list_ids               (GType                   itype,
-                                        guint                  *n_ids);
+guint  g_signal_newv                         (const gchar       *signal_name,
+                                              GType              itype,
+                                              GSignalFlags        signal_flags,
+                                              GClosure          *class_closure,
+                                              GSignalAccumulator accumulator,
+                                              GSignalCMarshaller c_marshaller,
+                                              GType              return_type,
+                                              guint              n_params,
+                                              GType             *param_types);
+void   g_signal_emitv                        (const GValue      *instance_and_params,
+                                              guint              signal_id,
+                                              GQuark             detail,
+                                              GValue            *return_value);
+guint  g_signal_lookup                       (const gchar       *name,
+                                              GType              itype);
+gchar* g_signal_name                         (guint              signal_id);
+void   g_signal_query                        (guint              signal_id,
+                                              GSignalQuery      *query);
+guint* g_signal_list_ids                     (GType              itype,
+                                              guint             *n_ids);
 
-/* --- signal handlers --- */
-guint   g_signal_connect_closure       (gpointer                instance,
-                                        guint                   signal_id,
-                                        GQuark                  detail,
-                                        GClosure               *closure,
-                                        gboolean                after);
-void    g_signal_handler_disconnect    (gpointer                instance,
-                                        guint                   handler_id);
-void    g_signal_handler_block         (gpointer                instance,
-                                        guint                   handler_id);
-void    g_signal_handler_unblock       (gpointer                instance,
-                                        guint                   handler_id);
-guint   g_signal_handler_find          (gpointer                instance,
-                                        GSignalMatchType        mask,
-                                        guint                   signal_id,
-                                        GQuark                  detail,
-                                        GClosure               *closure,
-                                        gpointer                func,
-                                        gpointer                data);
-gboolean g_signal_has_handler_pending  (gpointer                instance,
-                                        guint                   signal_id,
-                                        GQuark                  detail,
-                                        gboolean                may_be_blocked);
+/* --- signal emissions --- */
+void   g_signal_stop_emission                (gpointer           instance,
+                                              guint              signal_id,
+                                              GQuark             detail);
+guint  g_signal_add_emission_hook_full       (guint              signal_id,
+                                              GClosure          *closure);
+void   g_signal_remove_emission_hook         (guint              signal_id,
+                                              guint              hook_id);
 
 
-/* --- signal emissions --- */
-void   g_signal_stop_emission          (gpointer                instance,
-                                        guint                   signal_id,
-                                        GQuark                  detail);
-guint  g_signal_add_emission_hook_full (guint                   signal_id,
-                                        GClosure               *closure);
-void   g_signal_remove_emission_hook   (guint                   signal_id,
-                                        guint                   hook_id);
+/* --- signal handlers --- */
+gboolean g_signal_has_handler_pending        (gpointer           instance,
+                                              guint              signal_id,
+                                              GQuark             detail,
+                                              gboolean           may_be_blocked);
+guint   g_signal_connect_closure             (gpointer           instance,
+                                              guint              signal_id,
+                                              GQuark             detail,
+                                              GClosure          *closure,
+                                              gboolean           after);
+void    g_signal_handler_block               (gpointer           instance,
+                                              guint              handler_id);
+void    g_signal_handler_unblock             (gpointer           instance,
+                                              guint              handler_id);
+void    g_signal_handler_disconnect          (gpointer           instance,
+                                              guint              handler_id);
+guint   g_signal_handler_find                (gpointer           instance,
+                                              GSignalMatchType   mask,
+                                              guint              signal_id,
+                                              GQuark             detail,
+                                              GClosure          *closure,
+                                              gpointer           func,
+                                              gpointer           data);
+guint   g_signal_handlers_block_matched      (gpointer           instance,
+                                              GSignalMatchType   mask,
+                                              guint              signal_id,
+                                              GQuark             detail,
+                                              GClosure          *closure,
+                                              gpointer           func,
+                                              gpointer           data);
+guint   g_signal_handlers_unblock_matched    (gpointer           instance,
+                                              GSignalMatchType   mask,
+                                              guint              signal_id,
+                                              GQuark             detail,
+                                              GClosure          *closure,
+                                              gpointer           func,
+                                              gpointer           data);
+guint   g_signal_handlers_disconnect_matched (gpointer           instance,
+                                              GSignalMatchType   mask,
+                                              guint              signal_id,
+                                              GQuark             detail,
+                                              GClosure          *closure,
+                                              gpointer           func,
+                                              gpointer           data);
+
 
 /*< private >*/
-void   g_signal_handlers_destroy       (gpointer               instance);
-void   g_signals_destroy               (GType                  itype);
+void   g_signal_handlers_destroy             (gpointer           instance);
+void   g_signals_destroy                     (GType              itype);
 
 
 #ifdef __cplusplus