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