gsignal.c revision 9490f8d7e435d60b76d5fca12ba6332a5f058fa5
1/* GObject - GLib Type, Object, Parameter and Signal Library
2 * Copyright (C) 2000-2001 Red Hat, Inc.
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General
15 * Public License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
17 * Boston, MA 02111-1307, USA.
18 *
19 * this code is based on the original GtkSignal implementation
20 * for the Gtk+ library by Peter Mattis <petm@xcf.berkeley.edu>
21 */
22
23/*
24 * MT safe
25 */
26
27#include        "gsignal.h"
28#include        "gbsearcharray.h"
29#include        "gvaluecollector.h"
30#include	"gvaluetypes.h"
31#include	"gboxed.h"
32#include	<string.h>
33
34
35/* pre allocation configurations
36 */
37#define	MAX_STACK_VALUES	(16)
38#define BSA_PRE_ALLOC           (20)
39#define HANDLER_PRE_ALLOC       (48)
40#define EMISSION_PRE_ALLOC      (16)
41
42#define REPORT_BUG      "please report occourance circumstances to gtk-devel-list@gnome.org"
43#ifdef	G_ENABLE_DEBUG
44#define IF_DEBUG(debug_type, cond)	if ((_g_type_debug_flags & G_TYPE_DEBUG_ ## debug_type) || cond)
45static volatile gpointer *g_trace_instance_signals = NULL;
46static volatile gpointer *g_trap_instance_signals = NULL;
47#endif	/* G_ENABLE_DEBUG */
48
49
50/* --- generic allocation --- */
51/* we special case allocations generically by replacing
52 * these functions with more speed/memory aware variants
53 */
54#ifndef	DISABLE_MEM_POOLS
55static inline gpointer
56g_generic_node_alloc (GTrashStack **trash_stack_p,
57                      guint         sizeof_node,
58                      guint         nodes_pre_alloc)
59{
60  gpointer node = g_trash_stack_pop (trash_stack_p);
61
62  if (!node)
63    {
64      guint8 *block;
65
66      nodes_pre_alloc = MAX (nodes_pre_alloc, 1);
67      block = g_malloc (sizeof_node * nodes_pre_alloc);
68      while (--nodes_pre_alloc)
69        {
70          g_trash_stack_push (trash_stack_p, block);
71          block += sizeof_node;
72        }
73      node = block;
74    }
75
76  return node;
77}
78#define	g_generic_node_free(trash_stack_p, node) g_trash_stack_push (trash_stack_p, node)
79#else	/* !DISABLE_MEM_POOLS */
80#define	g_generic_node_alloc(t,sizeof_node,p)	 g_malloc (sizeof_node)
81#define	g_generic_node_free(t,node)		 g_free (node)
82#endif	/* !DISABLE_MEM_POOLS */
83
84
85/* --- typedefs --- */
86typedef struct _SignalNode   SignalNode;
87typedef struct _SignalKey    SignalKey;
88typedef struct _Emission     Emission;
89typedef struct _Handler      Handler;
90typedef struct _HandlerList  HandlerList;
91typedef struct _HandlerMatch HandlerMatch;
92typedef enum
93{
94  EMISSION_STOP,
95  EMISSION_RUN,
96  EMISSION_HOOK,
97  EMISSION_RESTART
98} EmissionState;
99
100
101/* --- prototypes --- */
102static inline guint		signal_id_lookup	(GQuark		  quark,
103							 GType		  itype);
104static	      void		signal_destroy_R	(SignalNode	 *signal_node);
105static inline HandlerList*	handler_list_ensure	(guint		  signal_id,
106							 gpointer	  instance);
107static inline HandlerList*	handler_list_lookup	(guint		  signal_id,
108							 gpointer	  instance);
109static inline Handler*		handler_new		(gboolean	  after);
110static	      void		handler_insert		(guint		  signal_id,
111							 gpointer	  instance,
112							 Handler	 *handler);
113static	      Handler*		handler_lookup		(gpointer	  instance,
114							 guint		  handler_id,
115							 guint		 *signal_id_p);
116static inline HandlerMatch*	handler_match_prepend	(HandlerMatch	 *list,
117							 Handler	 *handler,
118							 guint		  signal_id);
119static inline HandlerMatch*	handler_match_free1_R	(HandlerMatch	 *node,
120							 gpointer	  instance);
121static	      HandlerMatch*	handlers_find		(gpointer	  instance,
122							 GSignalMatchType mask,
123							 guint		  signal_id,
124							 GQuark		  detail,
125							 GClosure	 *closure,
126							 gpointer	  func,
127							 gpointer	  data,
128							 gboolean	  one_and_only);
129static inline void		handler_ref		(Handler	 *handler);
130static inline void		handler_unref_R		(guint		  signal_id,
131							 gpointer	  instance,
132							 Handler	 *handler);
133static inline void		emission_push		(Emission	**emission_list_p,
134							 guint		  signal_id,
135							 GQuark		  detail,
136							 gpointer	  instance,
137							 EmissionState	 *state_p);
138static inline void		emission_pop		(Emission	**emission_list_p,
139							 EmissionState	 *state_p);
140static inline Emission*		emission_find		(Emission	 *emission_list,
141							 guint		  signal_id,
142							 GQuark		  detail,
143							 gpointer	  instance);
144static	      gboolean		signal_emit_R		(SignalNode	 *node,
145							 GQuark		  detail,
146							 gpointer	  instance,
147							 GValue		 *return_value,
148							 const GValue	 *instance_and_params);
149
150
151/* --- structures --- */
152typedef struct
153{
154  GSignalAccumulator func;
155  gpointer           data;
156} SignalAccumulator;
157typedef struct
158{
159  GHook hook;
160  GQuark detail;
161} SignalHook;
162#define	SIGNAL_HOOK(hook)	((SignalHook*) (hook))
163
164struct _SignalNode
165{
166  /* permanent portion */
167  guint              signal_id;
168  GType              itype;
169  gchar             *name;
170  guint              destroyed : 1;
171
172  /* reinitializable portion */
173  guint              flags : 8;
174  guint              n_params : 8;
175  GType		    *param_types; /* mangled with G_SIGNAL_TYPE_STATIC_SCOPE flag */
176  GType		     return_type; /* mangled with G_SIGNAL_TYPE_STATIC_SCOPE flag */
177  GClosure          *class_closure;
178  SignalAccumulator *accumulator;
179  GSignalCMarshaller c_marshaller;
180  GHookList         *emission_hooks;
181};
182
183struct _SignalKey
184{
185  GType  itype;
186  GQuark quark;
187  guint  signal_id;
188};
189
190struct _Emission
191{
192  Emission      *next;
193  guint          signal_id;
194  GQuark	 detail;
195  gpointer       instance;
196  EmissionState *state_p;
197};
198
199struct _HandlerList
200{
201  guint    signal_id;
202  Handler *handlers;
203};
204struct _Handler
205{
206  guint         id;
207  Handler      *next;
208  Handler      *prev;
209  GQuark	detail;
210  guint         ref_count : 16;
211#define HANDLER_MAX_REF_COUNT   (1 << 16)
212  guint         block_count : 12;
213#define HANDLER_MAX_BLOCK_COUNT (1 << 12)
214  guint         after : 1;
215  GClosure     *closure;
216};
217struct _HandlerMatch
218{
219  Handler      *handler;
220  HandlerMatch *next;
221  union {
222    guint       signal_id;
223    gpointer	dummy;
224  } d;
225};
226
227
228/* --- variables --- */
229static GBSearchArray  g_signal_key_bsa = { NULL, 0, 0, 0, NULL };
230static GHashTable    *g_handler_list_bsa_ht = NULL;
231static Emission      *g_recursive_emissions = NULL;
232static Emission      *g_restart_emissions = NULL;
233static GTrashStack   *g_bsa_ts = NULL;
234static GTrashStack   *g_handler_ts = NULL;
235static GTrashStack   *g_emission_ts = NULL;
236G_LOCK_DEFINE_STATIC (g_signal_mutex);
237
238
239/* --- signal nodes --- */
240static guint          g_n_signal_nodes = 0;
241static SignalNode   **g_signal_nodes = NULL;
242
243static inline SignalNode*
244LOOKUP_SIGNAL_NODE (register guint signal_id)
245{
246  if (signal_id < g_n_signal_nodes)
247    return g_signal_nodes[signal_id];
248  else
249    return NULL;
250}
251
252
253/* --- functions --- */
254static inline guint
255signal_id_lookup (GQuark quark,
256		  GType  itype)
257{
258  GType *ifaces, type = itype;
259  SignalKey key;
260  guint n_ifaces;
261
262  key.quark = quark;
263
264  /* try looking up signals for this type and its anchestors */
265  do
266    {
267      SignalKey *signal_key;
268
269      key.itype = type;
270      signal_key = g_bsearch_array_lookup (&g_signal_key_bsa, &key);
271
272      if (signal_key)
273	return signal_key->signal_id;
274
275      type = g_type_parent (type);
276    }
277  while (type);
278
279  /* no luck, try interfaces it exports */
280  ifaces = g_type_interfaces (itype, &n_ifaces);
281  while (n_ifaces--)
282    {
283      SignalKey *signal_key;
284
285      key.itype = ifaces[n_ifaces];
286      signal_key = g_bsearch_array_lookup (&g_signal_key_bsa, &key);
287
288      if (signal_key)
289	{
290	  g_free (ifaces);
291	  return signal_key->signal_id;
292	}
293    }
294  g_free (ifaces);
295
296  return 0;
297}
298
299static gint
300handler_lists_cmp (gconstpointer node1,
301                   gconstpointer node2)
302{
303  const HandlerList *hlist1 = node1, *hlist2 = node2;
304
305  return G_BSEARCH_ARRAY_CMP (hlist1->signal_id, hlist2->signal_id);
306}
307
308static inline HandlerList*
309handler_list_ensure (guint    signal_id,
310		     gpointer instance)
311{
312  GBSearchArray *hlbsa = g_hash_table_lookup (g_handler_list_bsa_ht, instance);
313  HandlerList key;
314
315  if (!hlbsa)
316    {
317      hlbsa = g_generic_node_alloc (&g_bsa_ts,
318                                    sizeof (GBSearchArray),
319                                    BSA_PRE_ALLOC);
320      hlbsa->cmp_func = handler_lists_cmp;
321      hlbsa->sizeof_node = sizeof (HandlerList);
322      hlbsa->flags = G_BSEARCH_DEFER_SHRINK;
323      hlbsa->n_nodes = 0;
324      hlbsa->nodes = NULL;
325      g_hash_table_insert (g_handler_list_bsa_ht, instance, hlbsa);
326    }
327  key.signal_id = signal_id;
328  key.handlers = NULL;
329
330  return g_bsearch_array_insert (hlbsa, &key, FALSE);
331}
332
333static inline HandlerList*
334handler_list_lookup (guint    signal_id,
335		     gpointer instance)
336{
337  GBSearchArray *hlbsa = g_hash_table_lookup (g_handler_list_bsa_ht, instance);
338  HandlerList key;
339
340  key.signal_id = signal_id;
341
342  return hlbsa ? g_bsearch_array_lookup (hlbsa, &key) : NULL;
343}
344
345static Handler*
346handler_lookup (gpointer instance,
347		guint    handler_id,
348		guint   *signal_id_p)
349{
350  GBSearchArray *hlbsa = g_hash_table_lookup (g_handler_list_bsa_ht, instance);
351
352  if (hlbsa)
353    {
354      guint i;
355
356      for (i = 0; i < hlbsa->n_nodes; i++)
357        {
358          HandlerList *hlist = g_bsearch_array_get_nth (hlbsa, i);
359          Handler *handler;
360
361          for (handler = hlist->handlers; handler; handler = handler->next)
362            if (handler->id == handler_id)
363              {
364                if (signal_id_p)
365                  *signal_id_p = hlist->signal_id;
366
367                return handler;
368              }
369        }
370    }
371
372  return NULL;
373}
374
375static inline HandlerMatch*
376handler_match_prepend (HandlerMatch *list,
377		       Handler      *handler,
378		       guint	     signal_id)
379{
380  HandlerMatch *node;
381
382  /* yeah, we could use our own memchunk here, introducing yet more
383   * rarely used cached nodes and extra allocation overhead.
384   * instead, we use GList* nodes, since they are exactly the size
385   * we need and are already cached. g_signal_init() asserts this.
386   */
387  node = (HandlerMatch*) g_list_alloc ();
388  node->handler = handler;
389  node->next = list;
390  node->d.signal_id = signal_id;
391  handler_ref (handler);
392
393  return node;
394}
395static inline HandlerMatch*
396handler_match_free1_R (HandlerMatch *node,
397		       gpointer      instance)
398{
399  HandlerMatch *next = node->next;
400
401  handler_unref_R (node->d.signal_id, instance, node->handler);
402  g_list_free_1 ((GList*) node);
403
404  return next;
405}
406
407static HandlerMatch*
408handlers_find (gpointer         instance,
409	       GSignalMatchType mask,
410	       guint            signal_id,
411	       GQuark           detail,
412	       GClosure        *closure,
413	       gpointer         func,
414	       gpointer         data,
415	       gboolean         one_and_only)
416{
417  HandlerMatch *mlist = NULL;
418
419  if (mask & G_SIGNAL_MATCH_ID)
420    {
421      HandlerList *hlist = handler_list_lookup (signal_id, instance);
422      Handler *handler;
423      SignalNode *node = NULL;
424
425      if (mask & G_SIGNAL_MATCH_FUNC)
426	{
427	  node = LOOKUP_SIGNAL_NODE (signal_id);
428	  if (!node || !node->c_marshaller)
429	    return NULL;
430	}
431
432      mask = ~mask;
433      for (handler = hlist ? hlist->handlers : NULL; handler; handler = handler->next)
434        if (handler->id &&
435	    ((mask & G_SIGNAL_MATCH_DETAIL) || handler->detail == detail) &&
436	    ((mask & G_SIGNAL_MATCH_CLOSURE) || handler->closure == closure) &&
437            ((mask & G_SIGNAL_MATCH_DATA) || handler->closure->data == data) &&
438	    ((mask & G_SIGNAL_MATCH_UNBLOCKED) || handler->block_count == 0) &&
439	    ((mask & G_SIGNAL_MATCH_FUNC) || (handler->closure->marshal == node->c_marshaller &&
440					      handler->closure->meta_marshal == 0 &&
441					      ((GCClosure*) handler->closure)->callback == func)))
442	  {
443	    mlist = handler_match_prepend (mlist, handler, signal_id);
444	    if (one_and_only)
445	      return mlist;
446	  }
447    }
448  else
449    {
450      GBSearchArray *hlbsa = g_hash_table_lookup (g_handler_list_bsa_ht, instance);
451
452      mask = ~mask;
453      if (hlbsa)
454        {
455          guint i;
456
457          for (i = 0; i < hlbsa->n_nodes; i++)
458            {
459              HandlerList *hlist = g_bsearch_array_get_nth (hlbsa, i);
460	      SignalNode *node = NULL;
461              Handler *handler;
462
463	      if (!(mask & G_SIGNAL_MATCH_FUNC))
464		{
465		  node = LOOKUP_SIGNAL_NODE (hlist->signal_id);
466		  if (!node->c_marshaller)
467		    continue;
468		}
469
470              for (handler = hlist->handlers; handler; handler = handler->next)
471		if (handler->id &&
472		    ((mask & G_SIGNAL_MATCH_DETAIL) || handler->detail == detail) &&
473                    ((mask & G_SIGNAL_MATCH_CLOSURE) || handler->closure == closure) &&
474                    ((mask & G_SIGNAL_MATCH_DATA) || handler->closure->data == data) &&
475		    ((mask & G_SIGNAL_MATCH_UNBLOCKED) || handler->block_count == 0) &&
476		    ((mask & G_SIGNAL_MATCH_FUNC) || (handler->closure->marshal == node->c_marshaller &&
477						      handler->closure->meta_marshal == 0 &&
478						      ((GCClosure*) handler->closure)->callback == func)))
479		  {
480		    mlist = handler_match_prepend (mlist, handler, hlist->signal_id);
481		    if (one_and_only)
482		      return mlist;
483		  }
484            }
485        }
486    }
487
488  return mlist;
489}
490
491static inline Handler*
492handler_new (gboolean after)
493{
494  static guint handler_id = 1;
495  Handler *handler = g_generic_node_alloc (&g_handler_ts,
496                                           sizeof (Handler),
497                                           HANDLER_PRE_ALLOC);
498#ifndef G_DISABLE_CHECKS
499  if (handler_id == 0)
500    g_error (G_STRLOC ": handler id overflow, %s", REPORT_BUG);
501#endif
502
503  handler->id = handler_id++;
504  handler->prev = NULL;
505  handler->next = NULL;
506  handler->detail = 0;
507  handler->ref_count = 1;
508  handler->block_count = 0;
509  handler->after = after != FALSE;
510  handler->closure = NULL;
511
512  return handler;
513}
514
515static inline void
516handler_ref (Handler *handler)
517{
518  g_return_if_fail (handler->ref_count > 0);
519
520#ifndef G_DISABLE_CHECKS
521  if (handler->ref_count >= HANDLER_MAX_REF_COUNT - 1)
522    g_error (G_STRLOC ": handler ref_count overflow, %s", REPORT_BUG);
523#endif
524
525  handler->ref_count += 1;
526}
527
528static inline void
529handler_unref_R (guint    signal_id,
530		 gpointer instance,
531		 Handler *handler)
532{
533  g_return_if_fail (handler->ref_count > 0);
534
535  handler->ref_count -= 1;
536  if (!handler->ref_count)
537    {
538      if (handler->next)
539        handler->next->prev = handler->prev;
540      if (handler->prev)	/* watch out for g_signal_handlers_destroy()! */
541        handler->prev->next = handler->next;
542      else
543        {
544          HandlerList *hlist = handler_list_lookup (signal_id, instance);
545
546          hlist->handlers = handler->next;
547        }
548      G_UNLOCK (g_signal_mutex);
549      g_closure_unref (handler->closure);
550      G_LOCK (g_signal_mutex);
551      g_generic_node_free (&g_handler_ts, handler);
552    }
553}
554
555static void
556handler_insert (guint    signal_id,
557		gpointer instance,
558		Handler  *handler)
559{
560  HandlerList *hlist;
561
562  g_assert (handler->prev == NULL && handler->next == NULL); /* paranoid */
563
564  hlist = handler_list_ensure (signal_id, instance);
565  if (!hlist->handlers)
566    hlist->handlers = handler;
567  else if (hlist->handlers->after && !handler->after)
568    {
569      handler->next = hlist->handlers;
570      hlist->handlers->prev = handler;
571      hlist->handlers = handler;
572    }
573  else
574    {
575      Handler *tmp = hlist->handlers;
576
577      if (handler->after)
578        while (tmp->next)
579          tmp = tmp->next;
580      else
581        while (tmp->next && !tmp->next->after)
582          tmp = tmp->next;
583      if (tmp->next)
584        tmp->next->prev = handler;
585      handler->next = tmp->next;
586      handler->prev = tmp;
587      tmp->next = handler;
588    }
589}
590
591static inline void
592emission_push (Emission     **emission_list_p,
593	       guint          signal_id,
594	       GQuark	      detail,
595	       gpointer       instance,
596	       EmissionState *state_p)
597{
598  Emission *emission = g_generic_node_alloc (&g_emission_ts,
599                                             sizeof (Emission),
600                                             EMISSION_PRE_ALLOC);
601  emission->next = *emission_list_p;
602  emission->signal_id = signal_id;
603  emission->detail = detail;
604  emission->instance = instance;
605  emission->state_p = state_p;
606  *emission_list_p = emission;
607}
608
609static inline void
610emission_pop (Emission     **emission_list_p,
611	      EmissionState *state_p)
612{
613  Emission **loc = emission_list_p, *emission = *loc;
614
615  while (emission->state_p != state_p)
616    {
617      loc = &emission->next;
618      emission = *loc;
619    }
620  *loc = emission->next;
621  g_generic_node_free (&g_emission_ts, emission);
622}
623
624static inline Emission*
625emission_find (Emission *emission_list,
626	       guint     signal_id,
627	       GQuark    detail,
628	       gpointer  instance)
629{
630  Emission *emission;
631
632  for (emission = emission_list; emission; emission = emission->next)
633    if (emission->instance == instance &&
634	emission->signal_id == signal_id &&
635	emission->detail == detail)
636      return emission;
637  return NULL;
638}
639
640static gint
641signal_key_cmp (gconstpointer node1,
642                gconstpointer node2)
643{
644  const SignalKey *key1 = node1, *key2 = node2;
645
646  if (key1->itype == key2->itype)
647    return G_BSEARCH_ARRAY_CMP (key1->quark, key2->quark);
648  else
649    return G_BSEARCH_ARRAY_CMP (key1->itype, key2->itype);
650}
651
652void
653g_signal_init (void) /* sync with gtype.c */
654{
655  G_LOCK (g_signal_mutex);
656  if (!g_n_signal_nodes)
657    {
658      /* handler_id_node_prepend() requires this */
659      g_assert (sizeof (GList) == sizeof (HandlerMatch));
660
661      /* setup signal key array */
662      g_signal_key_bsa.cmp_func = signal_key_cmp;
663      g_signal_key_bsa.sizeof_node = sizeof (SignalKey);
664      g_signal_key_bsa.flags = G_BSEARCH_ALIGN_POWER2; /* alloc-only */
665
666      /* setup handler list binary searchable array hash table (in german, that'd be one word ;) */
667      g_handler_list_bsa_ht = g_hash_table_new (g_direct_hash, NULL);
668
669      /* invalid (0) signal_id */
670      g_n_signal_nodes = 1;
671      g_signal_nodes = g_renew (SignalNode*, g_signal_nodes, g_n_signal_nodes);
672      g_signal_nodes[0] = NULL;
673    }
674  G_UNLOCK (g_signal_mutex);
675}
676
677void
678_g_signals_destroy (GType itype)
679{
680  guint i;
681
682  G_LOCK (g_signal_mutex);
683  for (i = 1; i < g_n_signal_nodes; i++)
684    {
685      SignalNode *node = g_signal_nodes[i];
686
687      if (node->itype == itype)
688        {
689          if (node->destroyed)
690            g_warning (G_STRLOC ": signal \"%s\" of type `%s' already destroyed",
691                       node->name,
692                       g_type_name (node->itype));
693          else
694	    signal_destroy_R (node);
695        }
696    }
697  G_UNLOCK (g_signal_mutex);
698}
699
700void
701g_signal_stop_emission (gpointer instance,
702                        guint    signal_id,
703			GQuark   detail)
704{
705  SignalNode *node;
706
707  g_return_if_fail (G_TYPE_CHECK_INSTANCE (instance));
708  g_return_if_fail (signal_id > 0);
709
710  G_LOCK (g_signal_mutex);
711  node = LOOKUP_SIGNAL_NODE (signal_id);
712  if (node && detail && !(node->flags & G_SIGNAL_DETAILED))
713    {
714      g_warning ("%s: signal id `%u' does not support detail (%u)", G_STRLOC, signal_id, detail);
715      G_UNLOCK (g_signal_mutex);
716      return;
717    }
718  if (node && g_type_is_a (G_TYPE_FROM_INSTANCE (instance), node->itype))
719    {
720      Emission *emission_list = node->flags & G_SIGNAL_NO_RECURSE ? g_restart_emissions : g_recursive_emissions;
721      Emission *emission = emission_find (emission_list, signal_id, detail, instance);
722
723      if (emission)
724        {
725          if (*emission->state_p == EMISSION_HOOK)
726            g_warning (G_STRLOC ": emission of signal \"%s\" for instance `%p' cannot be stopped from emission hook",
727                       node->name, instance);
728          else if (*emission->state_p == EMISSION_RUN)
729            *emission->state_p = EMISSION_STOP;
730        }
731      else
732        g_warning (G_STRLOC ": no emission of signal \"%s\" to stop for instance `%p'",
733                   node->name, instance);
734    }
735  else
736    g_warning ("%s: signal id `%u' is invalid for instance `%p'", G_STRLOC, signal_id, instance);
737  G_UNLOCK (g_signal_mutex);
738}
739
740static void
741signal_finalize_hook (GHookList *hook_list,
742		      GHook     *hook)
743{
744  GDestroyNotify destroy = hook->destroy;
745
746  if (destroy)
747    {
748      hook->destroy = NULL;
749      G_UNLOCK (g_signal_mutex);
750      destroy (hook->data);
751      G_LOCK (g_signal_mutex);
752    }
753}
754
755guint
756g_signal_add_emission_hook (guint               signal_id,
757			    GQuark              detail,
758			    GSignalEmissionHook hook_func,
759			    gpointer            hook_data,
760			    GDestroyNotify      data_destroy)
761{
762  static guint seq_hook_id = 1;
763  SignalNode *node;
764  GHook *hook;
765  SignalHook *signal_hook;
766
767  g_return_val_if_fail (signal_id > 0, 0);
768  g_return_val_if_fail (hook_func != NULL, 0);
769
770  G_LOCK (g_signal_mutex);
771  node = LOOKUP_SIGNAL_NODE (signal_id);
772  if (!node || node->destroyed || (node->flags & G_SIGNAL_NO_HOOKS))
773    {
774      g_warning ("%s: invalid signal id `%u'", G_STRLOC, signal_id);
775      G_UNLOCK (g_signal_mutex);
776      return 0;
777    }
778  if (detail && !(node->flags & G_SIGNAL_DETAILED))
779    {
780      g_warning ("%s: signal id `%u' does not support detail (%u)", G_STRLOC, signal_id, detail);
781      G_UNLOCK (g_signal_mutex);
782      return 0;
783    }
784  if (!node->emission_hooks)
785    {
786      node->emission_hooks = g_new (GHookList, 1);
787      g_hook_list_init (node->emission_hooks, sizeof (SignalHook));
788      node->emission_hooks->finalize_hook = signal_finalize_hook;
789    }
790  hook = g_hook_alloc (node->emission_hooks);
791  hook->data = hook_data;
792  hook->func = hook_func;
793  hook->destroy = data_destroy;
794  signal_hook = SIGNAL_HOOK (hook);
795  signal_hook->detail = detail;
796  node->emission_hooks->seq_id = seq_hook_id;
797  g_hook_append (node->emission_hooks, hook);
798  seq_hook_id = node->emission_hooks->seq_id;
799  G_UNLOCK (g_signal_mutex);
800
801  return hook->hook_id;
802}
803
804void
805g_signal_remove_emission_hook (guint signal_id,
806			       guint hook_id)
807{
808  SignalNode *node;
809
810  g_return_if_fail (signal_id > 0);
811  g_return_if_fail (hook_id > 0);
812
813  G_LOCK (g_signal_mutex);
814  node = LOOKUP_SIGNAL_NODE (signal_id);
815  if (!node || node->destroyed)
816    g_warning ("%s: invalid signal id `%u'", G_STRLOC, signal_id);
817  else if (!node->emission_hooks || !g_hook_destroy (node->emission_hooks, hook_id))
818    g_warning ("%s: signal \"%s\" had no hook (%u) to remove", G_STRLOC, node->name, hook_id);
819  G_UNLOCK (g_signal_mutex);
820}
821
822static inline guint
823signal_parse_name (const gchar *name,
824		   GType        itype,
825		   GQuark      *detail_p,
826		   gboolean     force_quark)
827{
828  const gchar *colon = strchr (name, ':');
829  guint signal_id;
830
831  if (!colon)
832    {
833      signal_id = signal_id_lookup (g_quark_try_string (name), itype);
834      if (signal_id && detail_p)
835	*detail_p = 0;
836    }
837  else if (colon[1] == ':')
838    {
839      gchar buffer[32];
840      guint l = colon - name;
841
842      if (l < 32)
843	{
844	  memcpy (buffer, name, l);
845	  buffer[l] = 0;
846	  signal_id = signal_id_lookup (g_quark_try_string (buffer), itype);
847	}
848      else
849	{
850	  gchar *signal = g_new (gchar, l + 1);
851
852	  memcpy (signal, name, l);
853	  signal[l] = 0;
854	  signal_id = signal_id_lookup (g_quark_try_string (signal), itype);
855	  g_free (signal);
856	}
857
858      if (signal_id && detail_p)
859	*detail_p = colon[2] ? (force_quark ? g_quark_from_string : g_quark_try_string) (colon + 2) : 0;
860    }
861  else
862    signal_id = 0;
863  return signal_id;
864}
865
866gboolean
867g_signal_parse_name (const gchar *detailed_signal,
868		     GType        itype,
869		     guint       *signal_id_p,
870		     GQuark      *detail_p,
871		     gboolean	  force_detail_quark)
872{
873  SignalNode *node;
874  GQuark detail = 0;
875  guint signal_id;
876
877  g_return_val_if_fail (detailed_signal != NULL, FALSE);
878  g_return_val_if_fail (G_TYPE_IS_INSTANTIATABLE (itype) || G_TYPE_IS_INTERFACE (itype), FALSE);
879
880  G_LOCK (g_signal_mutex);
881  signal_id = signal_parse_name (detailed_signal, itype, &detail, force_detail_quark);
882  G_UNLOCK (g_signal_mutex);
883
884  node = signal_id ? LOOKUP_SIGNAL_NODE (signal_id) : NULL;
885  if (!node || node->destroyed ||
886      (detail && !(node->flags & G_SIGNAL_DETAILED)))
887    return FALSE;
888
889  if (signal_id_p)
890    *signal_id_p = signal_id;
891  if (detail_p)
892    *detail_p = detail;
893
894  return TRUE;
895}
896
897guint
898g_signal_lookup (const gchar *name,
899                 GType        itype)
900{
901  guint signal_id;
902
903  g_return_val_if_fail (name != NULL, 0);
904  g_return_val_if_fail (G_TYPE_IS_INSTANTIATABLE (itype) || G_TYPE_IS_INTERFACE (itype), 0);
905
906  G_LOCK (g_signal_mutex);
907  signal_id = signal_id_lookup (g_quark_try_string (name), itype);
908  G_UNLOCK (g_signal_mutex);
909
910  return signal_id;
911}
912
913G_CONST_RETURN gchar*
914g_signal_name (guint signal_id)
915{
916  SignalNode *node;
917  gchar *name;
918
919  G_LOCK (g_signal_mutex);
920  node = LOOKUP_SIGNAL_NODE (signal_id);
921  name = node ? node->name : NULL;
922  G_UNLOCK (g_signal_mutex);
923
924  return name;
925}
926
927void
928g_signal_query (guint         signal_id,
929		GSignalQuery *query)
930{
931  SignalNode *node;
932
933  g_return_if_fail (query != NULL);
934
935  G_LOCK (g_signal_mutex);
936  node = LOOKUP_SIGNAL_NODE (signal_id);
937  if (!node || node->destroyed)
938    query->signal_id = 0;
939  else
940    {
941      query->signal_id = node->signal_id;
942      query->signal_name = node->name;
943      query->itype = node->itype;
944      query->signal_flags = node->flags;
945      query->return_type = node->return_type;
946      query->n_params = node->n_params;
947      query->param_types = node->param_types;
948    }
949  G_UNLOCK (g_signal_mutex);
950}
951
952guint*
953g_signal_list_ids (GType  itype,
954		   guint *n_ids)
955{
956  SignalKey *keys;
957  GArray *result;
958  guint n_nodes;
959  guint i;
960
961  g_return_val_if_fail (G_TYPE_IS_INSTANTIATABLE (itype) || G_TYPE_IS_INTERFACE (itype), NULL);
962  g_return_val_if_fail (n_ids != NULL, NULL);
963
964  G_LOCK (g_signal_mutex);
965
966  keys = g_signal_key_bsa.nodes;
967  n_nodes  = g_signal_key_bsa.n_nodes;
968  result = g_array_new (FALSE, FALSE, sizeof (guint));
969
970  for (i = 0; i < n_nodes; i++)
971    if (keys[i].itype == itype)
972      {
973	const gchar *name = g_quark_to_string (keys[i].quark);
974
975	/* Signal names with "_" in them are aliases to the same
976	 * name with "-" instead of "_".
977	 */
978	if (!strchr (name, '_'))
979	  g_array_append_val (result, keys[i].signal_id);
980      }
981
982  *n_ids = result->len;
983
984  G_UNLOCK (g_signal_mutex);
985
986  return (guint *) g_array_free (result, FALSE);
987}
988
989guint
990g_signal_new_valist (const gchar       *signal_name,
991                     GType              itype,
992                     GSignalFlags       signal_flags,
993                     GClosure          *class_closure,
994                     GSignalAccumulator accumulator,
995		     gpointer		accu_data,
996                     GSignalCMarshaller c_marshaller,
997                     GType              return_type,
998                     guint              n_params,
999                     va_list            args)
1000{
1001  GType *param_types;
1002  guint i;
1003  guint signal_id;
1004
1005  if (n_params > 0)
1006    {
1007      param_types = g_new (GType, n_params);
1008
1009      for (i = 0; i < n_params; i++)
1010	param_types[i] = va_arg (args, GType);
1011    }
1012  else
1013    param_types = NULL;
1014
1015  signal_id = g_signal_newv (signal_name, itype, signal_flags,
1016			     class_closure, accumulator, accu_data, c_marshaller,
1017			     return_type, n_params, param_types);
1018  g_free (param_types);
1019
1020  return signal_id;
1021}
1022
1023guint
1024g_signal_newc (const gchar	 *signal_name,
1025               GType		  itype,
1026               GSignalFlags	  signal_flags,
1027               guint              class_offset,
1028	       GSignalAccumulator accumulator,
1029	       gpointer		  accu_data,
1030               GSignalCMarshaller c_marshaller,
1031               GType		  return_type,
1032               guint		  n_params,
1033               ...)
1034{
1035  va_list args;
1036  guint signal_id;
1037
1038  g_return_val_if_fail (signal_name != NULL, 0);
1039
1040  va_start (args, n_params);
1041
1042  signal_id = g_signal_new_valist (signal_name, itype, signal_flags,
1043                                   g_signal_type_cclosure_new (itype, class_offset),
1044				   accumulator, accu_data, c_marshaller,
1045                                   return_type, n_params, args);
1046
1047  va_end (args);
1048
1049  return signal_id;
1050}
1051
1052guint
1053g_signal_newv (const gchar       *signal_name,
1054               GType              itype,
1055               GSignalFlags       signal_flags,
1056               GClosure          *class_closure,
1057               GSignalAccumulator accumulator,
1058	       gpointer		  accu_data,
1059               GSignalCMarshaller c_marshaller,
1060               GType		  return_type,
1061               guint              n_params,
1062               GType		 *param_types)
1063{
1064  gchar *name;
1065  guint signal_id, i;
1066  SignalNode *node;
1067
1068  g_return_val_if_fail (signal_name != NULL, 0);
1069  g_return_val_if_fail (G_TYPE_IS_INSTANTIATABLE (itype) || G_TYPE_IS_INTERFACE (itype), 0);
1070  if (n_params)
1071    g_return_val_if_fail (param_types != NULL, 0);
1072  if (return_type == (G_TYPE_NONE & ~G_SIGNAL_TYPE_STATIC_SCOPE))
1073    g_return_val_if_fail (accumulator == NULL, 0);
1074  if (!accumulator)
1075    g_return_val_if_fail (accu_data == NULL, 0);
1076
1077  name = g_strdup (signal_name);
1078  g_strdelimit (name, G_STR_DELIMITERS ":^", '_');  // FIXME do character checks like for types
1079
1080  G_LOCK (g_signal_mutex);
1081
1082  signal_id = signal_id_lookup (g_quark_try_string (name), itype);
1083  node = LOOKUP_SIGNAL_NODE (signal_id);
1084  if (node && !node->destroyed)
1085    {
1086      g_warning (G_STRLOC ": signal \"%s\" already exists in the `%s' %s",
1087                 name,
1088                 g_type_name (node->itype),
1089                 G_TYPE_IS_INTERFACE (node->itype) ? "interface" : "class ancestry");
1090      g_free (name);
1091      G_UNLOCK (g_signal_mutex);
1092      return 0;
1093    }
1094  if (node && node->itype != itype)
1095    {
1096      g_warning (G_STRLOC ": signal \"%s\" for type `%s' was previously created for type `%s'",
1097                 name,
1098                 g_type_name (itype),
1099                 g_type_name (node->itype));
1100      g_free (name);
1101      G_UNLOCK (g_signal_mutex);
1102      return 0;
1103    }
1104  for (i = 0; i < n_params; i++)
1105    if (!G_TYPE_IS_VALUE (param_types[i] & ~G_SIGNAL_TYPE_STATIC_SCOPE))
1106      {
1107	g_warning (G_STRLOC ": parameter %d of type `%s' for signal \"%s::%s\" is not a value type",
1108		   i + 1, g_type_name (param_types[i] & ~G_SIGNAL_TYPE_STATIC_SCOPE), g_type_name (itype), name);
1109	g_free (name);
1110	G_UNLOCK (g_signal_mutex);
1111	return 0;
1112      }
1113  if (return_type != G_TYPE_NONE && !G_TYPE_IS_VALUE (return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE))
1114    {
1115      g_warning (G_STRLOC ": return value of type `%s' for signal \"%s::%s\" is not a value type",
1116		 g_type_name (return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE), g_type_name (itype), name);
1117      g_free (name);
1118      G_UNLOCK (g_signal_mutex);
1119      return 0;
1120    }
1121
1122  /* setup permanent portion of signal node */
1123  if (!node)
1124    {
1125      SignalKey key;
1126
1127      signal_id = g_n_signal_nodes++;
1128      node = g_new (SignalNode, 1);
1129      node->signal_id = signal_id;
1130      g_signal_nodes = g_renew (SignalNode*, g_signal_nodes, g_n_signal_nodes);
1131      g_signal_nodes[signal_id] = node;
1132      node->itype = itype;
1133      node->name = name;
1134      key.itype = itype;
1135      key.quark = g_quark_from_string (node->name);
1136      key.signal_id = signal_id;
1137      g_bsearch_array_insert (&g_signal_key_bsa, &key, FALSE);
1138      g_strdelimit (node->name, "_", '-');
1139      key.quark = g_quark_from_static_string (node->name);
1140      g_bsearch_array_insert (&g_signal_key_bsa, &key, FALSE);
1141    }
1142  node->destroyed = FALSE;
1143
1144  /* setup reinitializable portion */
1145  node->flags = signal_flags & G_SIGNAL_FLAGS_MASK;
1146  node->n_params = n_params;
1147  node->param_types = g_memdup (param_types, sizeof (GType) * n_params);
1148  node->return_type = return_type;
1149  node->class_closure = class_closure ? g_closure_ref (class_closure) : NULL;
1150  if (class_closure)
1151    g_closure_sink (class_closure);
1152  if (accumulator)
1153    {
1154      node->accumulator = g_new (SignalAccumulator, 1);
1155      node->accumulator->func = accumulator;
1156      node->accumulator->data = accu_data;
1157    }
1158  else
1159    node->accumulator = NULL;
1160  node->c_marshaller = c_marshaller;
1161  node->emission_hooks = NULL;
1162  if (node->c_marshaller && class_closure && G_CLOSURE_NEEDS_MARSHAL (class_closure))
1163    g_closure_set_marshal (class_closure, node->c_marshaller);
1164  G_UNLOCK (g_signal_mutex);
1165  return signal_id;
1166}
1167
1168static void
1169signal_destroy_R (SignalNode *signal_node)
1170{
1171  SignalNode node = *signal_node;
1172
1173  signal_node->destroyed = TRUE;
1174
1175  /* reentrancy caution, zero out real contents first */
1176  signal_node->n_params = 0;
1177  signal_node->param_types = NULL;
1178  signal_node->return_type = 0;
1179  signal_node->class_closure = NULL;
1180  signal_node->accumulator = NULL;
1181  signal_node->c_marshaller = NULL;
1182  signal_node->emission_hooks = NULL;
1183
1184#ifdef	G_ENABLE_DEBUG
1185  /* check current emissions */
1186  {
1187    Emission *emission;
1188
1189    for (emission = (node.flags & G_SIGNAL_NO_RECURSE) ? g_restart_emissions : g_recursive_emissions;
1190         emission; emission = emission->next)
1191      if (emission->signal_id == node.signal_id)
1192        g_critical (G_STRLOC ": signal \"%s\" being destroyed is currently in emission (instance `%p')",
1193                    node.name, emission->instance);
1194  }
1195#endif
1196
1197  /* free contents that need to
1198   */
1199  G_UNLOCK (g_signal_mutex);
1200  g_free (node.param_types);
1201  g_closure_unref (node.class_closure);
1202  g_free (node.accumulator);
1203  if (node.emission_hooks)
1204    {
1205      g_hook_list_clear (node.emission_hooks);
1206      g_free (node.emission_hooks);
1207    }
1208  G_LOCK (g_signal_mutex);
1209}
1210
1211guint
1212g_signal_connect_closure_by_id (gpointer  instance,
1213				guint     signal_id,
1214				GQuark    detail,
1215				GClosure *closure,
1216				gboolean  after)
1217{
1218  SignalNode *node;
1219  guint handler_id = 0;
1220
1221  g_return_val_if_fail (G_TYPE_CHECK_INSTANCE (instance), 0);
1222  g_return_val_if_fail (signal_id > 0, 0);
1223  g_return_val_if_fail (closure != NULL, 0);
1224
1225  G_LOCK (g_signal_mutex);
1226  node = LOOKUP_SIGNAL_NODE (signal_id);
1227  if (node)
1228    {
1229      if (detail && !(node->flags & G_SIGNAL_DETAILED))
1230	g_warning ("%s: signal id `%u' does not support detail (%u)", G_STRLOC, signal_id, detail);
1231      else if (!g_type_is_a (G_TYPE_FROM_INSTANCE (instance), node->itype))
1232	g_warning ("%s: signal id `%u' is invalid for instance `%p'", G_STRLOC, signal_id, instance);
1233      else
1234	{
1235	  Handler *handler = handler_new (after);
1236
1237	  handler_id = handler->id;
1238	  handler->detail = detail;
1239	  handler->closure = g_closure_ref (closure);
1240	  g_closure_sink (closure);
1241	  handler_insert (signal_id, instance, handler);
1242	  if (node->c_marshaller && G_CLOSURE_NEEDS_MARSHAL (closure))
1243	    g_closure_set_marshal (closure, node->c_marshaller);
1244	}
1245    }
1246  else
1247    g_warning ("%s: signal id `%u' is invalid for instance `%p'", G_STRLOC, signal_id, instance);
1248  G_UNLOCK (g_signal_mutex);
1249
1250  return handler_id;
1251}
1252
1253guint
1254g_signal_connect_closure (gpointer     instance,
1255			  const gchar *detailed_signal,
1256			  GClosure    *closure,
1257			  gboolean     after)
1258{
1259  guint signal_id, handler_id = 0;
1260  GQuark detail = 0;
1261  GType itype;
1262
1263  g_return_val_if_fail (G_TYPE_CHECK_INSTANCE (instance), 0);
1264  g_return_val_if_fail (detailed_signal != NULL, 0);
1265  g_return_val_if_fail (closure != NULL, 0);
1266
1267  G_LOCK (g_signal_mutex);
1268  itype = G_TYPE_FROM_INSTANCE (instance);
1269  signal_id = signal_parse_name (detailed_signal, itype, &detail, TRUE);
1270  if (signal_id)
1271    {
1272      SignalNode *node = LOOKUP_SIGNAL_NODE (signal_id);
1273
1274      if (detail && !(node->flags & G_SIGNAL_DETAILED))
1275	g_warning ("%s: signal `%s' does not support details", G_STRLOC, detailed_signal);
1276      else if (!g_type_is_a (itype, node->itype))
1277	g_warning ("%s: signal `%s' is invalid for instance `%p'", G_STRLOC, detailed_signal, instance);
1278      else
1279	{
1280	  Handler *handler = handler_new (after);
1281
1282	  handler_id = handler->id;
1283	  handler->detail = detail;
1284	  handler->closure = g_closure_ref (closure);
1285	  g_closure_sink (closure);
1286	  handler_insert (signal_id, instance, handler);
1287	  if (node->c_marshaller && G_CLOSURE_NEEDS_MARSHAL (handler->closure))
1288	    g_closure_set_marshal (handler->closure, node->c_marshaller);
1289	}
1290    }
1291  else
1292    g_warning ("%s: signal `%s' is invalid for instance `%p'", G_STRLOC, detailed_signal, instance);
1293  G_UNLOCK (g_signal_mutex);
1294
1295  return handler_id;
1296}
1297
1298guint
1299g_signal_connect_data (gpointer       instance,
1300		       const gchar   *detailed_signal,
1301		       GCallback      c_handler,
1302		       gpointer       data,
1303		       GClosureNotify destroy_data,
1304		       gboolean       swapped,
1305		       gboolean       after)
1306{
1307  guint signal_id, handler_id = 0;
1308  GQuark detail = 0;
1309  GType itype;
1310
1311  g_return_val_if_fail (G_TYPE_CHECK_INSTANCE (instance), 0);
1312  g_return_val_if_fail (detailed_signal != NULL, 0);
1313  g_return_val_if_fail (c_handler != NULL, 0);
1314
1315  G_LOCK (g_signal_mutex);
1316  itype = G_TYPE_FROM_INSTANCE (instance);
1317  signal_id = signal_parse_name (detailed_signal, itype, &detail, TRUE);
1318  if (signal_id)
1319    {
1320      SignalNode *node = LOOKUP_SIGNAL_NODE (signal_id);
1321
1322      if (detail && !(node->flags & G_SIGNAL_DETAILED))
1323	g_warning ("%s: signal `%s' does not support details", G_STRLOC, detailed_signal);
1324      else if (!g_type_is_a (itype, node->itype))
1325	g_warning ("%s: signal `%s' is invalid for instance `%p'", G_STRLOC, detailed_signal, instance);
1326      else
1327	{
1328	  Handler *handler = handler_new (after);
1329
1330	  handler_id = handler->id;
1331	  handler->detail = detail;
1332	  handler->closure = g_closure_ref ((swapped ? g_cclosure_new_swap : g_cclosure_new) (c_handler, data, destroy_data));
1333	  g_closure_sink (handler->closure);
1334	  handler_insert (signal_id, instance, handler);
1335	  if (node->c_marshaller && G_CLOSURE_NEEDS_MARSHAL (handler->closure))
1336	    g_closure_set_marshal (handler->closure, node->c_marshaller);
1337	}
1338    }
1339  else
1340    g_warning ("%s: signal `%s' is invalid for instance `%p'", G_STRLOC, detailed_signal, instance);
1341  G_UNLOCK (g_signal_mutex);
1342
1343  return handler_id;
1344}
1345
1346void
1347g_signal_handler_block (gpointer instance,
1348                        guint    handler_id)
1349{
1350  Handler *handler;
1351
1352  g_return_if_fail (G_TYPE_CHECK_INSTANCE (instance));
1353  g_return_if_fail (handler_id > 0);
1354
1355  G_LOCK (g_signal_mutex);
1356  handler = handler_lookup (instance, handler_id, NULL);
1357  if (handler)
1358    {
1359#ifndef G_DISABLE_CHECKS
1360      if (handler->block_count >= HANDLER_MAX_BLOCK_COUNT - 1)
1361        g_error (G_STRLOC ": handler block_count overflow, %s", REPORT_BUG);
1362#endif
1363
1364      handler->block_count += 1;
1365    }
1366  else
1367    g_warning ("%s: instance `%p' has no handler with id `%u'", G_STRLOC, instance, handler_id);
1368  G_UNLOCK (g_signal_mutex);
1369}
1370
1371void
1372g_signal_handler_unblock (gpointer instance,
1373                          guint    handler_id)
1374{
1375  Handler *handler;
1376
1377  g_return_if_fail (G_TYPE_CHECK_INSTANCE (instance));
1378  g_return_if_fail (handler_id > 0);
1379
1380  G_LOCK (g_signal_mutex);
1381  handler = handler_lookup (instance, handler_id, NULL);
1382  if (handler)
1383    {
1384      if (handler->block_count)
1385        handler->block_count -= 1;
1386      else
1387        g_warning (G_STRLOC ": handler `%u' of instance `%p' is not blocked", handler_id, instance);
1388    }
1389  else
1390    g_warning ("%s: instance `%p' has no handler with id `%u'", G_STRLOC, instance, handler_id);
1391  G_UNLOCK (g_signal_mutex);
1392}
1393
1394void
1395g_signal_handler_disconnect (gpointer instance,
1396                             guint    handler_id)
1397{
1398  Handler *handler;
1399  guint signal_id;
1400
1401  g_return_if_fail (G_TYPE_CHECK_INSTANCE (instance));
1402  g_return_if_fail (handler_id > 0);
1403
1404  G_LOCK (g_signal_mutex);
1405  handler = handler_lookup (instance, handler_id, &signal_id);
1406  if (handler)
1407    {
1408      handler->id = 0;
1409      handler->block_count = 1;
1410      handler_unref_R (signal_id, instance, handler);
1411    }
1412  else
1413    g_warning ("%s: instance `%p' has no handler with id `%u'", G_STRLOC, instance, handler_id);
1414  G_UNLOCK (g_signal_mutex);
1415}
1416
1417void
1418g_signal_handlers_destroy (gpointer instance)
1419{
1420  GBSearchArray *hlbsa;
1421
1422  g_return_if_fail (G_TYPE_CHECK_INSTANCE (instance));
1423
1424  G_LOCK (g_signal_mutex);
1425  hlbsa = g_hash_table_lookup (g_handler_list_bsa_ht, instance);
1426  if (hlbsa)
1427    {
1428      guint i;
1429
1430      /* reentrancy caution, delete instance trace first */
1431      g_hash_table_remove (g_handler_list_bsa_ht, instance);
1432
1433      for (i = 0; i < hlbsa->n_nodes; i++)
1434        {
1435          HandlerList *hlist = g_bsearch_array_get_nth (hlbsa, i);
1436          Handler *handler = hlist->handlers;
1437
1438          while (handler)
1439            {
1440              Handler *tmp = handler;
1441
1442              handler = tmp->next;
1443              tmp->block_count = 1;
1444              /* cruel unlink, this works because _all_ handlers vanish */
1445              tmp->next = NULL;
1446              tmp->prev = tmp;
1447              if (tmp->id)
1448		{
1449		  tmp->id = 0;
1450		  handler_unref_R (0, NULL, tmp);
1451		}
1452            }
1453        }
1454      g_free (hlbsa->nodes);
1455      g_generic_node_free (&g_bsa_ts, hlbsa);
1456    }
1457  G_UNLOCK (g_signal_mutex);
1458}
1459
1460guint
1461g_signal_handler_find (gpointer         instance,
1462                       GSignalMatchType mask,
1463                       guint            signal_id,
1464		       GQuark		detail,
1465                       GClosure        *closure,
1466                       gpointer         func,
1467                       gpointer         data)
1468{
1469  guint handler_id = 0;
1470
1471  g_return_val_if_fail (G_TYPE_CHECK_INSTANCE (instance), 0);
1472  g_return_val_if_fail ((mask & ~G_SIGNAL_MATCH_MASK) == 0, 0);
1473
1474  if (mask & G_SIGNAL_MATCH_MASK)
1475    {
1476      HandlerMatch *mlist;
1477
1478      G_LOCK (g_signal_mutex);
1479      mlist = handlers_find (instance, mask, signal_id, detail, closure, func, data, TRUE);
1480      if (mlist)
1481	{
1482	  handler_id = mlist->handler->id;
1483	  handler_match_free1_R (mlist, instance);
1484	}
1485      G_UNLOCK (g_signal_mutex);
1486    }
1487
1488  return handler_id;
1489}
1490
1491static guint
1492signal_handlers_foreach_matched_R (gpointer         instance,
1493				   GSignalMatchType mask,
1494				   guint            signal_id,
1495				   GQuark           detail,
1496				   GClosure        *closure,
1497				   gpointer         func,
1498				   gpointer         data,
1499				   void		  (*callback) (gpointer instance,
1500							       guint    handler_id))
1501{
1502  HandlerMatch *mlist;
1503  guint n_handlers = 0;
1504
1505  mlist = handlers_find (instance, mask, signal_id, detail, closure, func, data, FALSE);
1506  while (mlist)
1507    {
1508      n_handlers++;
1509      G_UNLOCK (g_signal_mutex);
1510      callback (instance, mlist->handler->id);
1511      G_LOCK (g_signal_mutex);
1512      mlist = handler_match_free1_R (mlist, instance);
1513    }
1514
1515  return n_handlers;
1516}
1517
1518guint
1519g_signal_handlers_block_matched (gpointer         instance,
1520				 GSignalMatchType mask,
1521				 guint            signal_id,
1522				 GQuark           detail,
1523				 GClosure        *closure,
1524				 gpointer         func,
1525				 gpointer         data)
1526{
1527  guint n_handlers = 0;
1528
1529  g_return_val_if_fail (G_TYPE_CHECK_INSTANCE (instance), FALSE);
1530  g_return_val_if_fail ((mask & ~G_SIGNAL_MATCH_MASK) == 0, FALSE);
1531
1532  if (mask & (G_SIGNAL_MATCH_CLOSURE | G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA))
1533    {
1534      G_LOCK (g_signal_mutex);
1535      n_handlers = signal_handlers_foreach_matched_R (instance, mask, signal_id, detail,
1536						      closure, func, data,
1537						      g_signal_handler_block);
1538      G_UNLOCK (g_signal_mutex);
1539    }
1540
1541  return n_handlers;
1542}
1543
1544guint
1545g_signal_handlers_unblock_matched (gpointer         instance,
1546				   GSignalMatchType mask,
1547				   guint            signal_id,
1548				   GQuark           detail,
1549				   GClosure        *closure,
1550				   gpointer         func,
1551				   gpointer         data)
1552{
1553  guint n_handlers = 0;
1554
1555  g_return_val_if_fail (G_TYPE_CHECK_INSTANCE (instance), FALSE);
1556  g_return_val_if_fail ((mask & ~G_SIGNAL_MATCH_MASK) == 0, FALSE);
1557
1558  if (mask & (G_SIGNAL_MATCH_CLOSURE | G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA))
1559    {
1560      G_LOCK (g_signal_mutex);
1561      n_handlers = signal_handlers_foreach_matched_R (instance, mask, signal_id, detail,
1562						      closure, func, data,
1563						      g_signal_handler_unblock);
1564      G_UNLOCK (g_signal_mutex);
1565    }
1566
1567  return n_handlers;
1568}
1569
1570guint
1571g_signal_handlers_disconnect_matched (gpointer         instance,
1572				      GSignalMatchType mask,
1573				      guint            signal_id,
1574				      GQuark           detail,
1575				      GClosure        *closure,
1576				      gpointer         func,
1577				      gpointer         data)
1578{
1579  guint n_handlers = 0;
1580
1581  g_return_val_if_fail (G_TYPE_CHECK_INSTANCE (instance), FALSE);
1582  g_return_val_if_fail ((mask & ~G_SIGNAL_MATCH_MASK) == 0, FALSE);
1583
1584  if (mask & (G_SIGNAL_MATCH_CLOSURE | G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA))
1585    {
1586      G_LOCK (g_signal_mutex);
1587      n_handlers = signal_handlers_foreach_matched_R (instance, mask, signal_id, detail,
1588						      closure, func, data,
1589						      g_signal_handler_disconnect);
1590      G_UNLOCK (g_signal_mutex);
1591    }
1592
1593  return n_handlers;
1594}
1595
1596gboolean
1597g_signal_has_handler_pending (gpointer instance,
1598			      guint    signal_id,
1599			      GQuark   detail,
1600			      gboolean may_be_blocked)
1601{
1602  HandlerMatch *mlist;
1603  gboolean has_pending;
1604
1605  g_return_val_if_fail (G_TYPE_CHECK_INSTANCE (instance), FALSE);
1606  g_return_val_if_fail (signal_id > 0, FALSE);
1607
1608  G_LOCK (g_signal_mutex);
1609  if (detail)
1610    {
1611      SignalNode *node = LOOKUP_SIGNAL_NODE (signal_id);
1612
1613      if (!(node->flags & G_SIGNAL_DETAILED))
1614	{
1615	  g_warning ("%s: signal id `%u' does not support detail (%u)", G_STRLOC, signal_id, detail);
1616	  G_UNLOCK (g_signal_mutex);
1617	  return FALSE;
1618	}
1619    }
1620  mlist = handlers_find (instance,
1621			 (G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_DETAIL | (may_be_blocked ? 0 : G_SIGNAL_MATCH_UNBLOCKED)),
1622			 signal_id, detail, NULL, NULL, NULL, TRUE);
1623  if (mlist)
1624    {
1625      has_pending = TRUE;
1626      handler_match_free1_R (mlist, instance);
1627    }
1628  else
1629    has_pending = FALSE;
1630  G_UNLOCK (g_signal_mutex);
1631
1632  return has_pending;
1633}
1634
1635void
1636g_signal_emitv (const GValue *instance_and_params,
1637		guint         signal_id,
1638		GQuark	      detail,
1639		GValue       *return_value)
1640{
1641  const GValue *param_values;
1642  gpointer instance;
1643  SignalNode *node;
1644  guint i;
1645
1646  g_return_if_fail (instance_and_params != NULL);
1647  instance = g_value_peek_pointer (instance_and_params);
1648  g_return_if_fail (G_TYPE_CHECK_INSTANCE (instance));
1649  g_return_if_fail (signal_id > 0);
1650
1651  param_values = instance_and_params + 1;
1652
1653  G_LOCK (g_signal_mutex);
1654  node = LOOKUP_SIGNAL_NODE (signal_id);
1655  if (!node || !g_type_is_a (G_TYPE_FROM_INSTANCE (instance), node->itype))
1656    {
1657      g_warning ("%s: signal id `%u' is invalid for instance `%p'", G_STRLOC, signal_id, instance);
1658      G_UNLOCK (g_signal_mutex);
1659      return;
1660    }
1661#ifdef G_ENABLE_DEBUG
1662  if (detail && !(node->flags & G_SIGNAL_DETAILED))
1663    {
1664      g_warning ("%s: signal id `%u' does not support detail (%u)", G_STRLOC, signal_id, detail);
1665      G_UNLOCK (g_signal_mutex);
1666      return;
1667    }
1668  for (i = 0; i < node->n_params; i++)
1669    if (!G_TYPE_CHECK_VALUE_TYPE (param_values + i, node->param_types[i] & ~G_SIGNAL_TYPE_STATIC_SCOPE))
1670      {
1671	g_critical ("%s: value for `%s' parameter %u for signal \"%s\" is of type `%s'",
1672		    G_STRLOC,
1673		    g_type_name (node->param_types[i] & ~G_SIGNAL_TYPE_STATIC_SCOPE),
1674		    i,
1675		    node->name,
1676		    G_VALUE_TYPE_NAME (param_values + i));
1677	G_UNLOCK (g_signal_mutex);
1678	return;
1679      }
1680  if (node->return_type != G_TYPE_NONE)
1681    {
1682      if (!return_value)
1683	{
1684	  g_critical ("%s: return value `%s' for signal \"%s\" is (NULL)",
1685		      G_STRLOC,
1686		      g_type_name (node->return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE),
1687		      node->name);
1688	  G_UNLOCK (g_signal_mutex);
1689	  return;
1690	}
1691      else if (!node->accumulator && !G_TYPE_CHECK_VALUE_TYPE (return_value, node->return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE))
1692	{
1693	  g_critical ("%s: return value `%s' for signal \"%s\" is of type `%s'",
1694		      G_STRLOC,
1695		      g_type_name (node->return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE),
1696		      node->name,
1697		      G_VALUE_TYPE_NAME (return_value));
1698	  G_UNLOCK (g_signal_mutex);
1699	  return;
1700	}
1701    }
1702  else
1703    return_value = NULL;
1704#endif	/* G_ENABLE_DEBUG */
1705
1706  signal_emit_R (node, detail, instance, return_value, instance_and_params);
1707  G_UNLOCK (g_signal_mutex);
1708}
1709
1710void
1711g_signal_emit_valist (gpointer instance,
1712		      guint    signal_id,
1713		      GQuark   detail,
1714		      va_list  var_args)
1715{
1716  GValue *instance_and_params, stack_values[MAX_STACK_VALUES], *free_me = NULL;
1717  GValue *param_values;
1718  SignalNode *node;
1719  guint i;
1720
1721  g_return_if_fail (G_TYPE_CHECK_INSTANCE (instance));
1722  g_return_if_fail (signal_id > 0);
1723
1724  G_LOCK (g_signal_mutex);
1725  node = LOOKUP_SIGNAL_NODE (signal_id);
1726  if (!node || !g_type_is_a (G_TYPE_FROM_INSTANCE (instance), node->itype))
1727    {
1728      g_warning ("%s: signal id `%u' is invalid for instance `%p'", G_STRLOC, signal_id, instance);
1729      G_UNLOCK (g_signal_mutex);
1730      return;
1731    }
1732#ifndef G_DISABLE_CHECKS
1733  if (detail && !(node->flags & G_SIGNAL_DETAILED))
1734    {
1735      g_warning ("%s: signal id `%u' does not support detail (%u)", G_STRLOC, signal_id, detail);
1736      G_UNLOCK (g_signal_mutex);
1737      return;
1738    }
1739#endif  /* !G_DISABLE_CHECKS */
1740
1741  if (node->n_params < MAX_STACK_VALUES)
1742    instance_and_params = stack_values;
1743  else
1744    {
1745      free_me = g_new (GValue, node->n_params + 1);
1746      instance_and_params = free_me;
1747    }
1748  param_values = instance_and_params + 1;
1749  for (i = 0; i < node->n_params; i++)
1750    {
1751      gchar *error;
1752
1753      param_values[i].g_type = 0;
1754      g_value_init (param_values + i, node->param_types[i] & ~G_SIGNAL_TYPE_STATIC_SCOPE);
1755      G_VALUE_COLLECT (param_values + i,
1756		       var_args,
1757		       node->param_types[i] & G_SIGNAL_TYPE_STATIC_SCOPE ? G_VALUE_NOCOPY_CONTENTS : 0,
1758		       &error);
1759      if (error)
1760	{
1761	  g_warning ("%s: %s", G_STRLOC, error);
1762	  g_free (error);
1763
1764	  /* we purposely leak the value here, it might not be
1765	   * in a sane state if an error condition occoured
1766	   */
1767	  while (i--)
1768	    g_value_unset (param_values + i);
1769
1770	  G_UNLOCK (g_signal_mutex);
1771	  g_free (free_me);
1772	  return;
1773	}
1774    }
1775  instance_and_params->g_type = 0;
1776  g_value_init (instance_and_params, G_TYPE_FROM_INSTANCE (instance));
1777  g_value_set_instance (instance_and_params, instance);
1778  if (node->return_type == G_TYPE_NONE)
1779    signal_emit_R (node, detail, instance, NULL, instance_and_params);
1780  else
1781    {
1782      GValue return_value = { 0, };
1783      gchar *error = NULL;
1784
1785      g_value_init (&return_value, node->return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE);
1786      if (signal_emit_R (node, detail, instance, &return_value, instance_and_params))
1787	G_VALUE_LCOPY (&return_value,
1788		       var_args,
1789		       node->return_type & G_SIGNAL_TYPE_STATIC_SCOPE ? G_VALUE_NOCOPY_CONTENTS : 0,
1790		       &error);
1791      if (!error)
1792	g_value_unset (&return_value);
1793      else
1794	{
1795	  g_warning ("%s: %s", G_STRLOC, error);
1796	  g_free (error);
1797
1798	  /* we purposely leak the value here, it might not be
1799	   * in a sane state if an error condition occoured
1800	   */
1801	}
1802    }
1803  for (i = 0; i < node->n_params; i++)
1804    g_value_unset (param_values + i);
1805  g_value_unset (instance_and_params);
1806  if (free_me)
1807    g_free (free_me);
1808  G_UNLOCK (g_signal_mutex);
1809}
1810
1811void
1812g_signal_emit (gpointer instance,
1813	       guint    signal_id,
1814	       GQuark   detail,
1815	       ...)
1816{
1817  va_list var_args;
1818
1819  va_start (var_args, detail);
1820  g_signal_emit_valist (instance, signal_id, detail, var_args);
1821  va_end (var_args);
1822}
1823
1824void
1825g_signal_emit_by_name (gpointer     instance,
1826		       const gchar *detailed_signal,
1827		       ...)
1828{
1829  GQuark detail = 0;
1830  guint signal_id;
1831
1832  g_return_if_fail (G_TYPE_CHECK_INSTANCE (instance));
1833  g_return_if_fail (detailed_signal != NULL);
1834
1835  G_LOCK (g_signal_mutex);
1836  signal_id = signal_parse_name (detailed_signal, G_TYPE_FROM_INSTANCE (instance), &detail, TRUE);
1837  G_UNLOCK (g_signal_mutex);
1838
1839  if (signal_id)
1840    {
1841      va_list var_args;
1842
1843      va_start (var_args, detailed_signal);
1844      g_signal_emit_valist (instance, signal_id, detail, var_args);
1845      va_end (var_args);
1846    }
1847  else
1848    g_warning ("%s: signal name `%s' is invalid for instance `%p'", G_STRLOC, detailed_signal, instance);
1849}
1850
1851static inline gboolean
1852accumulate (GSignalInvocationHint *ihint,
1853	    GValue                *return_accu,
1854	    GValue	          *handler_return,
1855	    SignalAccumulator     *accumulator)
1856{
1857  gboolean continue_emission;
1858
1859  if (!accumulator)
1860    return TRUE;
1861
1862  continue_emission = accumulator->func (ihint, return_accu, handler_return, accumulator->data);
1863  g_value_reset (handler_return);
1864
1865  return continue_emission;
1866}
1867
1868static gboolean
1869signal_emit_R (SignalNode   *node,
1870	       GQuark	     detail,
1871	       gpointer      instance,
1872	       GValue	    *emission_return,
1873	       const GValue *instance_and_params)
1874{
1875  EmissionState emission_state = 0;
1876  SignalAccumulator *accumulator;
1877  GSignalInvocationHint ihint;
1878  GClosure *class_closure;
1879  HandlerList *hlist;
1880  Handler *handler_list = NULL;
1881  GValue *return_accu, accu = { 0, };
1882  guint signal_id = node->signal_id;
1883  gboolean return_value_altered = FALSE;
1884
1885#ifdef	G_ENABLE_DEBUG
1886  IF_DEBUG (SIGNALS, g_trace_instance_signals == instance || g_trap_instance_signals == instance)
1887    {
1888      g_message ("%s::%s(%u) emitted (instance=%p signal-node=%p)\n",
1889		 g_type_name (G_TYPE_FROM_INSTANCE (instance)),
1890		 node->name, detail,
1891		 instance, node);
1892      if (g_trap_instance_signals == instance)
1893	G_BREAKPOINT ();
1894    }
1895#endif	/* G_ENABLE_DEBUG */
1896
1897  if (node->flags & G_SIGNAL_NO_RECURSE)
1898    {
1899      Emission *emission = emission_find (g_restart_emissions, signal_id, detail, instance);
1900
1901      if (emission)
1902	{
1903	  *emission->state_p = EMISSION_RESTART;
1904	  return return_value_altered;
1905	}
1906    }
1907  ihint.signal_id = node->signal_id;
1908  ihint.detail = detail;
1909  accumulator = node->accumulator;
1910  if (accumulator)
1911    {
1912      g_value_init (&accu, node->return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE);
1913      return_accu = &accu;
1914    }
1915  else
1916    return_accu = emission_return;
1917  emission_push ((node->flags & G_SIGNAL_NO_RECURSE) ? &g_restart_emissions : &g_recursive_emissions,
1918		 signal_id, detail, instance, &emission_state);
1919  class_closure = node->class_closure;
1920
1921 EMIT_RESTART:
1922
1923  if (handler_list)
1924    handler_unref_R (signal_id, instance, handler_list);
1925  hlist = handler_list_lookup (signal_id, instance);
1926  handler_list = hlist ? hlist->handlers : NULL;
1927  if (handler_list)
1928    handler_ref (handler_list);
1929
1930  ihint.run_type = G_SIGNAL_RUN_FIRST;
1931
1932  if ((node->flags & G_SIGNAL_RUN_FIRST) && class_closure)
1933    {
1934      emission_state = EMISSION_RUN;
1935
1936      G_UNLOCK (g_signal_mutex);
1937      g_closure_invoke (class_closure,
1938			return_accu,
1939			node->n_params + 1,
1940			instance_and_params,
1941			&ihint);
1942      if (!accumulate (&ihint, emission_return, &accu, accumulator) &&
1943	  emission_state == EMISSION_RUN)
1944	emission_state = EMISSION_STOP;
1945      G_LOCK (g_signal_mutex);
1946      return_value_altered = TRUE;
1947
1948      if (emission_state == EMISSION_STOP)
1949	goto EMIT_CLEANUP;
1950      else if (emission_state == EMISSION_RESTART)
1951	goto EMIT_RESTART;
1952    }
1953
1954  if (node->emission_hooks)
1955    {
1956      gboolean need_destroy, was_in_call, may_recurse = TRUE;
1957      GHook *hook;
1958
1959      emission_state = EMISSION_HOOK;
1960      hook = g_hook_first_valid (node->emission_hooks, may_recurse);
1961      while (hook)
1962	{
1963	  SignalHook *signal_hook = SIGNAL_HOOK (hook);
1964
1965	  if (!signal_hook->detail || signal_hook->detail == detail)
1966	    {
1967	      GSignalEmissionHook hook_func = hook->func;
1968
1969	      was_in_call = G_HOOK_IN_CALL (hook);
1970	      hook->flags |= G_HOOK_FLAG_IN_CALL;
1971              G_UNLOCK (g_signal_mutex);
1972	      need_destroy = !hook_func (&ihint, node->n_params + 1, instance_and_params, hook->data);
1973	      G_LOCK (g_signal_mutex);
1974	      if (!was_in_call)
1975		hook->flags &= ~G_HOOK_FLAG_IN_CALL;
1976	      if (need_destroy)
1977		g_hook_destroy_link (node->emission_hooks, hook);
1978	    }
1979	  hook = g_hook_next_valid (node->emission_hooks, hook, may_recurse);
1980	}
1981
1982      if (emission_state == EMISSION_RESTART)
1983	goto EMIT_RESTART;
1984    }
1985
1986  if (handler_list)
1987    {
1988      Handler *handler = handler_list;
1989
1990      emission_state = EMISSION_RUN;
1991      handler_ref (handler);
1992      do
1993	{
1994	  Handler *tmp;
1995
1996	  if (handler->after)
1997	    {
1998	      handler_unref_R (signal_id, instance, handler_list);
1999	      handler_list = handler;
2000	      break;
2001	    }
2002	  else if (!handler->block_count && (!handler->detail || handler->detail == detail))
2003	    {
2004	      G_UNLOCK (g_signal_mutex);
2005	      g_closure_invoke (handler->closure,
2006				return_accu,
2007				node->n_params + 1,
2008				instance_and_params,
2009				&ihint);
2010	      if (!accumulate (&ihint, emission_return, &accu, accumulator) &&
2011		  emission_state == EMISSION_RUN)
2012		emission_state = EMISSION_STOP;
2013	      G_LOCK (g_signal_mutex);
2014	      return_value_altered = TRUE;
2015
2016	      tmp = emission_state == EMISSION_RUN ? handler->next : NULL;
2017	    }
2018	  else
2019	    tmp = handler->next;
2020
2021	  if (tmp)
2022	    handler_ref (tmp);
2023	  handler_unref_R (signal_id, instance, handler_list);
2024	  handler_list = handler;
2025	  handler = tmp;
2026	}
2027      while (handler);
2028
2029      if (emission_state == EMISSION_STOP)
2030	goto EMIT_CLEANUP;
2031      else if (emission_state == EMISSION_RESTART)
2032	goto EMIT_RESTART;
2033    }
2034
2035  ihint.run_type = G_SIGNAL_RUN_LAST;
2036
2037  if ((node->flags & G_SIGNAL_RUN_LAST) && class_closure)
2038    {
2039      emission_state = EMISSION_RUN;
2040
2041      G_UNLOCK (g_signal_mutex);
2042      g_closure_invoke (class_closure,
2043			return_accu,
2044			node->n_params + 1,
2045			instance_and_params,
2046			&ihint);
2047      if (!accumulate (&ihint, emission_return, &accu, accumulator) &&
2048	  emission_state == EMISSION_RUN)
2049	emission_state = EMISSION_STOP;
2050      G_LOCK (g_signal_mutex);
2051      return_value_altered = TRUE;
2052
2053      if (emission_state == EMISSION_STOP)
2054	goto EMIT_CLEANUP;
2055      else if (emission_state == EMISSION_RESTART)
2056	goto EMIT_RESTART;
2057    }
2058
2059  if (handler_list)
2060    {
2061      Handler *handler = handler_list;
2062
2063      emission_state = EMISSION_RUN;
2064      handler_ref (handler);
2065      do
2066	{
2067	  Handler *tmp;
2068
2069	  if (handler->after && !handler->block_count && (!handler->detail || handler->detail == detail))
2070	    {
2071	      G_UNLOCK (g_signal_mutex);
2072	      g_closure_invoke (handler->closure,
2073				return_accu,
2074				node->n_params + 1,
2075				instance_and_params,
2076				&ihint);
2077	      if (!accumulate (&ihint, emission_return, &accu, accumulator) &&
2078		  emission_state == EMISSION_RUN)
2079		emission_state = EMISSION_STOP;
2080	      G_LOCK (g_signal_mutex);
2081	      return_value_altered = TRUE;
2082
2083	      tmp = emission_state == EMISSION_RUN ? handler->next : NULL;
2084	    }
2085	  else
2086	    tmp = handler->next;
2087
2088	  if (tmp)
2089	    handler_ref (tmp);
2090	  handler_unref_R (signal_id, instance, handler);
2091	  handler = tmp;
2092	}
2093      while (handler);
2094
2095      if (emission_state == EMISSION_STOP)
2096	goto EMIT_CLEANUP;
2097      else if (emission_state == EMISSION_RESTART)
2098	goto EMIT_RESTART;
2099    }
2100
2101 EMIT_CLEANUP:
2102
2103  ihint.run_type = G_SIGNAL_RUN_CLEANUP;
2104
2105  if ((node->flags & G_SIGNAL_RUN_CLEANUP) && class_closure)
2106    {
2107      gboolean need_unset = FALSE;
2108
2109      emission_state = EMISSION_STOP;
2110
2111      G_UNLOCK (g_signal_mutex);
2112      if (node->return_type != G_TYPE_NONE && !accumulator)
2113	{
2114	  g_value_init (&accu, node->return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE);
2115	  need_unset = TRUE;
2116	}
2117      g_closure_invoke (class_closure,
2118			node->return_type != G_TYPE_NONE ? &accu : NULL,
2119			node->n_params + 1,
2120			instance_and_params,
2121			&ihint);
2122      if (need_unset)
2123	g_value_unset (&accu);
2124      G_LOCK (g_signal_mutex);
2125
2126      if (emission_state == EMISSION_RESTART)
2127	goto EMIT_RESTART;
2128    }
2129
2130  if (handler_list)
2131    handler_unref_R (signal_id, instance, handler_list);
2132
2133  emission_pop ((node->flags & G_SIGNAL_NO_RECURSE) ? &g_restart_emissions : &g_recursive_emissions, &emission_state);
2134  if (accumulator)
2135    g_value_unset (&accu);
2136
2137  return return_value_altered;
2138}
2139
2140
2141/* --- compile standard marshallers --- */
2142#include	"gobject.h"
2143#include	"genums.h"
2144#include        "gmarshal.c"
2145