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