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