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