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