Fix problem where signals with "_" in them appeared twice in the result
[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
26 #include        "gbsearcharray.h"
27
28
29 /* pre allocation configurations
30  */
31 #define BSA_PRE_ALLOC           (20)
32 #define HANDLER_PRE_ALLOC       (48)
33 #define EMISSION_PRE_ALLOC      (16)
34
35 #define TIGHT_MEMORY    (1)
36
37 #define REPORT_BUG      "please report occourance circumstances to gtk-devel-list@gnome.org"
38
39
40 /* --- generic allocation --- */
41 /* we can special case allocations generically by replacing
42  * these functions with more speed/memory aware variants
43  */
44 static inline gpointer
45 g_generic_node_alloc (GTrashStack **trash_stack_p,
46                       guint         sizeof_node,
47                       guint         nodes_pre_alloc)
48 {
49   gpointer node = g_trash_stack_pop (trash_stack_p);
50   
51   if (!node)
52     {
53       guint8 *block;
54       
55       nodes_pre_alloc = MAX (nodes_pre_alloc, 1);
56       block = g_malloc (sizeof_node * nodes_pre_alloc);
57       while (--nodes_pre_alloc)
58         {
59           g_trash_stack_push (trash_stack_p, block);
60           block += sizeof_node;
61         }
62       node = block;
63     }
64   
65   return node;
66 }
67 static inline void
68 g_generic_node_free (GTrashStack **trash_stack_p,
69                      gpointer      node)
70 {
71   g_trash_stack_push (trash_stack_p, node);
72 }
73
74
75 /* --- typedefs --- */
76 typedef struct _SignalNode  SignalNode;
77 typedef struct _SignalKey   SignalKey;
78 typedef struct _Emission    Emission;
79 typedef struct _Handler     Handler;
80 typedef struct _HandlerList HandlerList;
81 typedef enum
82 {
83   EMISSION_STOP,
84   EMISSION_RUN,
85   EMISSION_HOOK,
86   EMISSION_RESTART
87 } EmissionState;
88
89
90 /* --- prototypes --- */
91 static inline guint             signal_id_lookup      (GQuark           quark,
92                                                        GType            itype);
93 static        void              signal_destroy_R      (SignalNode      *signal_node);
94 static inline HandlerList*      handler_list_ensure   (guint            signal_id,
95                                                        gpointer         instance);
96 static inline HandlerList*      handler_list_lookup   (guint            signal_id,
97                                                        gpointer         instance);
98 static inline Handler*          handler_new           (gboolean         after);
99 static        void              handler_insert        (guint            signal_id,
100                                                        gpointer         instance,
101                                                        Handler         *handler);
102 static        Handler*          handler_lookup        (gpointer         instance,
103                                                        guint            handler_id,
104                                                        guint           *signal_id_p);
105 static        Handler*          handler_find          (gpointer         instance,
106                                                        GSignalMatchType mask,
107                                                        guint            signal_id,
108                                                        GQuark           detail,
109                                                        GClosure        *closure,
110                                                        gpointer         func,
111                                                        gpointer         data);
112 static inline void              handler_ref           (Handler         *handler);
113 static inline void              handler_unref_R       (guint            signal_id,
114                                                        gpointer         instance,
115                                                        Handler         *handler);
116 static inline void              emission_push         (Emission       **emission_list_p,
117                                                        guint            signal_id,
118                                                        GQuark           detail,
119                                                        gpointer         instance,
120                                                        EmissionState   *state_p);
121 static inline void              emission_pop          (Emission       **emission_list_p,
122                                                        EmissionState   *state_p);
123 static inline Emission*         emission_find         (Emission        *emission_list,
124                                                        guint            signal_id,
125                                                        GQuark           detail,
126                                                        gpointer         instance);
127 static        void              signal_emit_R         (SignalNode      *node,
128                                                        GQuark           detail,
129                                                        gpointer         instance,
130                                                        GValue          *return_value,
131                                                        const GValue    *instance_and_params);
132
133
134 /* --- structures --- */
135 struct _SignalNode
136 {
137   /* permanent portion */
138   guint              signal_id;
139   GType              itype;
140   gchar             *name;
141   guint              destroyed : 1;
142   
143   /* reinitializable portion */
144   guint              flags : 8;
145   guint              n_params : 8;
146   GType             *param_types;
147   GType              return_type;
148   GClosure          *class_closure;
149   GSignalAccumulator accumulator;
150   GSignalCMarshaller c_marshaller;
151   GHookList         *emission_hooks;
152 };
153
154 struct _SignalKey
155 {
156   GType  itype;
157   GQuark quark;
158   guint  signal_id;
159 };
160
161 struct _Emission
162 {
163   Emission      *next;
164   guint          signal_id;
165   GQuark         detail;
166   gpointer       instance;
167   EmissionState *state_p;
168 };
169
170 struct _HandlerList
171 {
172   guint    signal_id;
173   Handler *handlers;
174 };
175
176 struct _Handler
177 {
178   guint         id;
179   Handler      *next;
180   Handler      *prev;
181   GQuark        detail;
182   guint         ref_count : 16;
183 #define HANDLER_MAX_REF_COUNT   (1 << 16)
184   guint         block_count : 12;
185 #define HANDLER_MAX_BLOCK_COUNT (1 << 12)
186   guint         after : 1;
187   GClosure     *closure;
188 };
189
190
191 /* --- variables --- */
192 static GBSearchArray  g_signal_key_bsa = { NULL, 0, 0, 0, NULL };
193 static GHashTable    *g_handler_list_bsa_ht = NULL;
194 static Emission      *g_recursive_emissions = NULL;
195 static Emission      *g_restart_emissions = NULL;
196 static GTrashStack   *g_bsa_ts = NULL;
197 static GTrashStack   *g_handler_ts = NULL;
198 static GTrashStack   *g_emission_ts = NULL;
199 G_LOCK_DEFINE_STATIC (g_signal_mutex);
200
201
202 /* --- signal nodes --- */
203 static guint          g_n_signal_nodes = 0;
204 static SignalNode   **g_signal_nodes = NULL;
205
206 static inline SignalNode*
207 LOOKUP_SIGNAL_NODE (register guint signal_id)
208 {
209   if (signal_id < g_n_signal_nodes)
210     return g_signal_nodes[signal_id];
211   else
212     return NULL;
213 }
214
215
216 /* --- functions --- */
217 static inline guint
218 signal_id_lookup (GQuark quark,
219                   GType  itype)
220 {
221   do
222     {
223       SignalKey key, *signal_key;
224       
225       key.itype = itype;
226       key.quark = quark;
227       
228       signal_key = g_bsearch_array_lookup (&g_signal_key_bsa, &key);
229       
230       if (signal_key)
231         return signal_key->signal_id;
232       
233       itype = g_type_parent (itype);
234     }
235   while (itype);
236   
237   return 0;
238 }
239
240 static gint
241 handler_lists_cmp (gconstpointer node1,
242                    gconstpointer node2)
243 {
244   const HandlerList *hlist1 = node1, *hlist2 = node2;
245   
246   return G_BSEARCH_ARRAY_CMP (hlist1->signal_id, hlist2->signal_id);
247 }
248
249 static inline HandlerList*
250 handler_list_ensure (guint    signal_id,
251                      gpointer instance)
252 {
253   GBSearchArray *hlbsa = g_hash_table_lookup (g_handler_list_bsa_ht, instance);
254   HandlerList key;
255   
256   if (!hlbsa)
257     {
258       hlbsa = g_generic_node_alloc (&g_bsa_ts,
259                                     sizeof (GBSearchArray),
260                                     BSA_PRE_ALLOC);
261       hlbsa->cmp_func = handler_lists_cmp;
262       hlbsa->sizeof_node = sizeof (HandlerList);
263       hlbsa->flags = G_BSEARCH_DEFER_SHRINK;
264       hlbsa->n_nodes = 0;
265       hlbsa->nodes = NULL;
266       g_hash_table_insert (g_handler_list_bsa_ht, instance, hlbsa);
267     }
268   key.signal_id = signal_id;
269   key.handlers = NULL;
270   
271   return g_bsearch_array_insert (hlbsa, &key, FALSE);
272 }
273
274 static inline HandlerList*
275 handler_list_lookup (guint    signal_id,
276                      gpointer instance)
277 {
278   GBSearchArray *hlbsa = g_hash_table_lookup (g_handler_list_bsa_ht, instance);
279   HandlerList key;
280   
281   key.signal_id = signal_id;
282   
283   return hlbsa ? g_bsearch_array_lookup (hlbsa, &key) : NULL;
284 }
285
286 static Handler*
287 handler_lookup (gpointer instance,
288                 guint    handler_id,
289                 guint   *signal_id_p)
290 {
291   GBSearchArray *hlbsa = g_hash_table_lookup (g_handler_list_bsa_ht, instance);
292   
293   if (hlbsa)
294     {
295       guint i;
296       
297       for (i = 0; i < hlbsa->n_nodes; i++)
298         {
299           HandlerList *hlist = g_bsearch_array_get_nth (hlbsa, i);
300           Handler *handler;
301           
302           for (handler = hlist->handlers; handler; handler = handler->next)
303             if (handler->id == handler_id)
304               {
305                 if (signal_id_p)
306                   *signal_id_p = hlist->signal_id;
307                 
308                 return handler;
309               }
310         }
311     }
312   
313   return NULL;
314 }
315
316 static Handler*
317 handler_find (gpointer         instance,
318               GSignalMatchType mask,
319               guint            signal_id,
320               GQuark           detail,
321               GClosure        *closure,
322               gpointer         func,
323               gpointer         data)
324 {
325   if (mask & G_SIGNAL_MATCH_ID)
326     {
327       HandlerList *hlist = handler_list_lookup (signal_id, instance);
328       Handler *handler;
329       SignalNode *node;
330       
331       if (mask & G_SIGNAL_MATCH_FUNC)
332         {
333           node = LOOKUP_SIGNAL_NODE (signal_id);
334           if (!node || !node->c_marshaller)
335             return NULL;
336         }
337           
338       mask = ~mask;
339       for (handler = hlist ? hlist->handlers : NULL; handler; handler = handler->next)
340         if (((mask & G_SIGNAL_MATCH_DETAIL) || handler->detail == detail) &&
341             ((mask & G_SIGNAL_MATCH_CLOSURE) || handler->closure == closure) &&
342             ((mask & G_SIGNAL_MATCH_DATA) || handler->closure->data == data) &&
343             ((mask & G_SIGNAL_MATCH_UNBLOCKED) || handler->block_count == 0) &&
344             ((mask & G_SIGNAL_MATCH_FUNC) || (handler->closure->marshal == node->c_marshaller &&
345                                               handler->closure->meta_marshal == 0 &&
346                                               ((GCClosure*) handler->closure)->callback == func)))
347           return handler;
348     }
349   else
350     {
351       GBSearchArray *hlbsa = g_hash_table_lookup (g_handler_list_bsa_ht, instance);
352       
353       mask = ~mask;
354       if (hlbsa)
355         {
356           guint i;
357           
358           for (i = 0; i < hlbsa->n_nodes; i++)
359             {
360               HandlerList *hlist = g_bsearch_array_get_nth (hlbsa, i);
361               SignalNode *node;
362               Handler *handler;
363               
364               if (!(mask & G_SIGNAL_MATCH_FUNC))
365                 {
366                   node = LOOKUP_SIGNAL_NODE (hlist->signal_id);
367                   if (!node->c_marshaller)
368                     continue;
369                 }
370
371               for (handler = hlist->handlers; handler; handler = handler->next)
372                 if (((mask & G_SIGNAL_MATCH_DETAIL) || handler->detail == detail) &&
373                     ((mask & G_SIGNAL_MATCH_CLOSURE) || handler->closure == closure) &&
374                     ((mask & G_SIGNAL_MATCH_DATA) || handler->closure->data == data) &&
375                     ((mask & G_SIGNAL_MATCH_UNBLOCKED) || handler->block_count == 0) &&
376                     ((mask & G_SIGNAL_MATCH_FUNC) || (handler->closure->marshal == node->c_marshaller &&
377                                                       handler->closure->meta_marshal == 0 &&
378                                                       ((GCClosure*) handler->closure)->callback == func)))
379                   return handler;
380             }
381         }
382     }
383   
384   return NULL;
385 }
386
387 static inline Handler*
388 handler_new (gboolean after)
389 {
390   static guint handler_id = 1;
391   Handler *handler = g_generic_node_alloc (&g_handler_ts,
392                                            sizeof (Handler),
393                                            HANDLER_PRE_ALLOC);
394 #ifndef G_DISABLE_CHECKS
395   if (handler_id == 0)
396     g_error (G_STRLOC ": handler id overflow, %s", REPORT_BUG);
397 #endif
398   
399   handler->id = handler_id++;
400   handler->prev = NULL;
401   handler->next = NULL;
402   handler->detail = 0;
403   handler->ref_count = 1;
404   handler->block_count = 0;
405   handler->after = after != FALSE;
406   handler->closure = NULL;
407   
408   return handler;
409 }
410
411 static inline void
412 handler_ref (Handler *handler)
413 {
414   g_return_if_fail (handler->ref_count > 0);
415   
416 #ifndef G_DISABLE_CHECKS
417   if (handler->ref_count >= HANDLER_MAX_REF_COUNT - 1)
418     g_error (G_STRLOC ": handler ref_count overflow, %s", REPORT_BUG);
419 #endif
420   
421   handler->ref_count += 1;
422 }
423
424 static inline void
425 handler_unref_R (guint    signal_id,
426                  gpointer instance,
427                  Handler *handler)
428 {
429   g_return_if_fail (handler->ref_count > 0);
430   
431   handler->ref_count -= 1;
432   if (!handler->ref_count)
433     {
434       if (handler->next)
435         handler->next->prev = handler->prev;
436       if (handler->prev)        /* watch out for g_signal_handlers_destroy()! */
437         handler->prev->next = handler->next;
438       else
439         {
440           HandlerList *hlist = handler_list_lookup (signal_id, instance);
441           
442           hlist->handlers = handler->next;
443         }
444       G_UNLOCK (g_signal_mutex);
445       g_closure_unref (handler->closure);
446       G_LOCK (g_signal_mutex);
447       g_generic_node_free (&g_handler_ts, handler);
448     }
449 }
450
451 static void
452 handler_insert (guint    signal_id,
453                 gpointer instance,
454                 Handler  *handler)
455 {
456   HandlerList *hlist;
457   
458   g_assert (handler->prev == NULL && handler->next == NULL); // FIXME: paranoid
459   
460   hlist = handler_list_ensure (signal_id, instance);
461   if (!hlist->handlers)
462     hlist->handlers = handler;
463   else if (hlist->handlers->after && !handler->after)
464     {
465       handler->next = hlist->handlers;
466       hlist->handlers->prev = handler;
467       hlist->handlers = handler;
468     }
469   else
470     {
471       Handler *tmp = hlist->handlers;
472       
473       if (handler->after)
474         while (tmp->next)
475           tmp = tmp->next;
476       else
477         while (tmp->next && !tmp->next->after)
478           tmp = tmp->next;
479       if (tmp->next)
480         tmp->next->prev = handler;
481       handler->next = tmp->next;
482       handler->prev = tmp;
483       tmp->next = handler;
484     }
485 }
486
487 static inline void
488 emission_push (Emission     **emission_list_p,
489                guint          signal_id,
490                GQuark         detail,
491                gpointer       instance,
492                EmissionState *state_p)
493 {
494   Emission *emission = g_generic_node_alloc (&g_emission_ts,
495                                              sizeof (Emission),
496                                              EMISSION_PRE_ALLOC);
497   emission->next = *emission_list_p;
498   emission->signal_id = signal_id;
499   emission->detail = detail;
500   emission->instance = instance;
501   emission->state_p = state_p;
502   *emission_list_p = emission;
503 }
504
505 static inline void
506 emission_pop (Emission     **emission_list_p,
507               EmissionState *state_p)
508 {
509   Emission **loc = emission_list_p, *emission = *loc;
510
511   while (emission->state_p != state_p)
512     {
513       loc = &emission->next;
514       emission = *loc;
515     }
516   *loc = emission->next;
517   g_generic_node_free (&g_emission_ts, emission);
518 }
519
520 static inline Emission*
521 emission_find (Emission *emission_list,
522                guint     signal_id,
523                GQuark    detail,
524                gpointer  instance)
525 {
526   Emission *emission;
527   
528   for (emission = emission_list; emission; emission = emission->next)
529     if (emission->instance == instance &&
530         emission->signal_id == signal_id &&
531         emission->detail == detail)
532       return emission;
533   return NULL;
534 }
535
536 static gint
537 signal_key_cmp (gconstpointer node1,
538                 gconstpointer node2)
539 {
540   const SignalKey *key1 = node1, *key2 = node2;
541   
542   if (key1->itype == key2->itype)
543     return G_BSEARCH_ARRAY_CMP (key1->quark, key2->quark);
544   else
545     return G_BSEARCH_ARRAY_CMP (key1->itype, key2->itype);
546 }
547
548 void
549 g_signal_init (void) /* sync with gtype.c */
550 {
551   G_LOCK (g_signal_mutex);
552   if (!g_n_signal_nodes)
553     {
554       /* setup signal key array */
555       g_signal_key_bsa.cmp_func = signal_key_cmp;
556       g_signal_key_bsa.sizeof_node = sizeof (SignalKey);
557       g_signal_key_bsa.flags = 0; /* alloc-only */
558       
559       /* setup handler list binary searchable array hash table (in german, that'd be one word ;) */
560       g_handler_list_bsa_ht = g_hash_table_new (g_direct_hash, NULL);
561       
562       /* invalid (0) signal_id */
563       g_n_signal_nodes = 1;
564       g_signal_nodes = g_renew (SignalNode*, g_signal_nodes, g_n_signal_nodes);
565       g_signal_nodes[0] = NULL;
566     }
567   G_UNLOCK (g_signal_mutex);
568 }
569
570 void
571 g_signals_destroy (GType itype)
572 {
573   guint i;
574   gboolean found_one = FALSE;
575   
576   G_LOCK (g_signal_mutex);
577   for (i = 0; i < g_n_signal_nodes; i++)
578     {
579       SignalNode *node = g_signal_nodes[i];
580       
581       if (node->itype == itype)
582         {
583           if (node->destroyed)
584             g_warning (G_STRLOC ": signal \"%s\" of type `%s' already destroyed",
585                        node->name,
586                        g_type_name (node->itype));
587           else
588             {
589               found_one = TRUE;
590               signal_destroy_R (node);
591             }
592         }
593     }
594   if (!found_one)
595     g_warning (G_STRLOC ": type `%s' has no signals that could be destroyed",
596                g_type_name (itype));
597   G_UNLOCK (g_signal_mutex);
598 }
599
600 void
601 g_signal_stop_emission (gpointer instance,
602                         guint    signal_id,
603                         GQuark   detail)
604 {
605   SignalNode *node;
606   
607   g_return_if_fail (G_TYPE_CHECK_INSTANCE (instance));
608   g_return_if_fail (signal_id > 0);
609   
610   G_LOCK (g_signal_mutex);
611   node = LOOKUP_SIGNAL_NODE (signal_id);
612   if (node && detail && !(node->flags & G_SIGNAL_DETAILED))
613     {
614       g_warning ("%s: signal id `%u' does not support detail (%u)", G_STRLOC, signal_id, detail);
615       G_UNLOCK (g_signal_mutex);
616       return;
617     }
618   if (node && g_type_conforms_to (G_TYPE_FROM_INSTANCE (instance), node->itype))
619     {
620       Emission *emission_list = node->flags & G_SIGNAL_NO_RECURSE ? g_restart_emissions : g_recursive_emissions;
621       Emission *emission = emission_find (emission_list, signal_id, detail, instance);
622       
623       if (emission)
624         {
625           if (*emission->state_p == EMISSION_HOOK)
626             g_warning (G_STRLOC ": emission of signal \"%s\" for instance `%p' cannot be stopped from emission hook",
627                        node->name, instance);
628           else if (*emission->state_p == EMISSION_RUN)
629             *emission->state_p = EMISSION_STOP;
630         }
631       else
632         g_warning (G_STRLOC ": no emission of signal \"%s\" to stop for instance `%p'",
633                    node->name, instance);
634     }
635   else
636     g_warning ("%s: signal id `%u' is invalid for instance `%p'", G_STRLOC, signal_id, instance);
637   G_UNLOCK (g_signal_mutex);
638 }
639
640 guint
641 g_signal_lookup (const gchar *name,
642                  GType        itype)
643 {
644   guint signal_id;
645   
646   g_return_val_if_fail (name != NULL, 0);
647   g_return_val_if_fail (G_TYPE_IS_INSTANTIATABLE (itype) || G_TYPE_IS_INTERFACE (itype), 0);
648   
649   G_LOCK (g_signal_mutex);
650   signal_id = signal_id_lookup (g_quark_try_string (name), itype);
651   G_UNLOCK (g_signal_mutex);
652   
653   return signal_id;
654 }
655
656 gchar*
657 g_signal_name (guint signal_id)
658 {
659   SignalNode *node;
660   gchar *name;
661
662   G_LOCK (g_signal_mutex);
663   node = LOOKUP_SIGNAL_NODE (signal_id);
664   name = node ? node->name : NULL;
665   G_UNLOCK (g_signal_mutex);
666   
667   return name;
668 }
669
670 void
671 g_signal_query (guint         signal_id,
672                 GSignalQuery *query)
673 {
674   SignalNode *node;
675
676   g_return_if_fail (query != NULL);
677
678   G_LOCK (g_signal_mutex);
679   node = LOOKUP_SIGNAL_NODE (signal_id);
680   if (!node || node->destroyed)
681     query->signal_id = 0;
682   else
683     {
684       query->signal_id = node->signal_id;
685       query->signal_name = node->name;
686       query->itype = node->itype;
687       query->signal_flags = node->flags;
688       query->return_type = node->return_type;
689       query->n_params = node->n_params;
690       query->param_types = node->param_types;
691     }
692   G_UNLOCK (g_signal_mutex);
693 }
694
695 /**
696  * gtk_signals_list:
697  * @itype: an  
698  * @n_ids: location to store number of ids in @itype
699  * 
700  * List all signals for a given type.
701  *
702  * Return value: Array 
703  **/
704 guint *
705 g_type_signals (GType    itype,
706                 guint   *n_ids)
707 {
708   guint i;
709   SignalKey *keys;
710   guint n_nodes;
711   GArray *result;
712
713   g_return_val_if_fail (n_ids != NULL, NULL);
714   g_return_val_if_fail (G_TYPE_IS_INSTANTIATABLE (itype) || G_TYPE_IS_INTERFACE (itype), NULL);
715
716   keys = g_signal_key_bsa.nodes;
717   n_nodes  = g_signal_key_bsa.n_nodes;
718   result = g_array_new (FALSE, FALSE, sizeof (guint));
719   
720   for (i = 0; i < n_nodes; i++)
721     {
722       if (keys[i].itype == itype)
723         {
724           gchar *name = g_quark_to_string (keys[i].quark);
725           /* Signal names with "_" in them are aliases to the same
726            * name with "-" instead of "_".
727            */
728           if (!strchr (name, '_'))
729             g_array_append_val (result, keys[i].signal_id);
730         }
731     }
732
733   *n_ids = result->len;
734
735   return (guint *) g_array_free (result, FALSE);
736 }
737
738 guint
739 g_signal_newv (const gchar       *signal_name,
740                GType              itype,
741                GSignalFlags       signal_flags,
742                GClosure          *class_closure,
743                GSignalAccumulator accumulator,
744                GSignalCMarshaller c_marshaller,
745                GType              return_type,
746                guint              n_params,
747                GType             *param_types)
748 {
749   gchar *name;
750   guint signal_id, i;
751   SignalNode *node;
752   
753   g_return_val_if_fail (signal_name != NULL, 0);
754   g_return_val_if_fail (G_TYPE_IS_INSTANTIATABLE (itype) || G_TYPE_IS_INTERFACE (itype), 0);
755   if (n_params)
756     g_return_val_if_fail (param_types != NULL, 0);
757   if (return_type != G_TYPE_NONE)
758     g_return_val_if_fail (accumulator == NULL, 0);
759   
760   name = g_strdup (signal_name);
761   g_strdelimit (name, G_STR_DELIMITERS ":^", '_');  // FIXME do character checks like for types
762   
763   G_LOCK (g_signal_mutex);
764   
765   signal_id = signal_id_lookup (g_quark_try_string (name), itype);
766   node = LOOKUP_SIGNAL_NODE (signal_id);
767   if (node && !node->destroyed)
768     {
769       g_warning (G_STRLOC ": signal \"%s\" already exists in the `%s' %s",
770                  name,
771                  g_type_name (node->itype),
772                  G_TYPE_IS_INTERFACE (node->itype) ? "interface" : "class ancestry");
773       g_free (name);
774       G_UNLOCK (g_signal_mutex);
775       return 0;
776     }
777   if (node && node->itype != itype)
778     {
779       g_warning (G_STRLOC ": signal \"%s\" for type `%s' was previously created for type `%s'",
780                  name,
781                  g_type_name (itype),
782                  g_type_name (node->itype));
783       g_free (name);
784       G_UNLOCK (g_signal_mutex);
785       return 0;
786     }
787   for (i = 0; i < n_params; i++)
788     if (!G_TYPE_IS_VALUE (param_types[i]) ||
789         param_types[i] == G_TYPE_ENUM || param_types[i] == G_TYPE_FLAGS) /* FIXME: kludge */
790       {
791         g_warning (G_STRLOC ": parameter %d of type `%s' for signal \"%s::%s\" is not a value type",
792                    i + 1, g_type_name (param_types[i]), g_type_name (itype), name);
793         g_free (name);
794         G_UNLOCK (g_signal_mutex);
795         return 0;
796       }
797   if (return_type != G_TYPE_NONE && !G_TYPE_IS_VALUE (return_type))
798     {
799       g_warning (G_STRLOC ": return value of type `%s' for signal \"%s::%s\" is not a value type",
800                  g_type_name (param_types[i]), g_type_name (itype), name);
801       g_free (name);
802       G_UNLOCK (g_signal_mutex);
803       return 0;
804     }
805   
806   /* setup permanent portion of signal node */
807   if (!node)
808     {
809       SignalKey key;
810       
811       signal_id = g_n_signal_nodes++;
812       node = g_new (SignalNode, 1);
813       node->signal_id = signal_id;
814       g_signal_nodes = g_renew (SignalNode*, g_signal_nodes, g_n_signal_nodes);
815       g_signal_nodes[signal_id] = node;
816       node->itype = itype;
817       node->name = name;
818       key.itype = itype;
819       key.quark = g_quark_from_string (node->name);
820       key.signal_id = signal_id;
821       g_bsearch_array_insert (&g_signal_key_bsa, &key, FALSE);
822       g_strdelimit (node->name, "_", '-');
823       key.quark = g_quark_from_static_string (node->name);
824       g_bsearch_array_insert (&g_signal_key_bsa, &key, FALSE);
825     }
826   node->destroyed = FALSE;
827   
828   /* setup reinitializable portion */
829   node->flags = signal_flags & G_SIGNAL_FLAGS_MASK;
830   node->n_params = n_params;
831   node->param_types = g_memdup (param_types, sizeof (GType) * n_params);
832   node->return_type = return_type;
833   node->class_closure = class_closure ? g_closure_ref (class_closure) : NULL;
834   node->accumulator = accumulator;
835   node->c_marshaller = c_marshaller;
836   node->emission_hooks = NULL;
837   if (node->c_marshaller && class_closure && G_CLOSURE_NEEDS_MARSHAL (class_closure))
838     g_closure_set_marshal (class_closure, node->c_marshaller);
839   
840   G_UNLOCK (g_signal_mutex);
841   return signal_id;
842 }
843
844 static void
845 signal_destroy_R (SignalNode *signal_node)
846 {
847   SignalNode node = *signal_node;
848   
849   signal_node->destroyed = TRUE;
850   
851   /* reentrancy caution, zero out real contents first */
852   signal_node->n_params = 0;
853   signal_node->param_types = NULL;
854   signal_node->return_type = 0;
855   signal_node->class_closure = NULL;
856   signal_node->accumulator = NULL;
857   signal_node->c_marshaller = NULL;
858   signal_node->emission_hooks = NULL;
859   
860 #ifndef G_DISABLE_CHECKS
861   /* check current emissions */
862   {
863     Emission *emission;
864     
865     for (emission = (node.flags & G_SIGNAL_NO_RECURSE) ? g_restart_emissions : g_recursive_emissions;
866          emission; emission = emission->next)
867       if (emission->signal_id == node.signal_id)
868         g_critical (G_STRLOC ": signal \"%s\" being destroyed is currently in emission (instance `%p')",
869                     node.name, emission->instance);
870   }
871 #endif
872   
873   /* free contents that need to
874    */
875   G_UNLOCK (g_signal_mutex);
876   g_free (node.param_types);
877   g_closure_unref (node.class_closure);
878   if (node.emission_hooks)
879     {
880       g_hook_list_clear (node.emission_hooks);
881       g_free (node.emission_hooks);
882     }
883   G_LOCK (g_signal_mutex);
884 }
885
886 guint
887 g_signal_connect_closure (gpointer  instance,
888                           guint     signal_id,
889                           GQuark    detail,
890                           GClosure *closure,
891                           gboolean  after)
892 {
893   SignalNode *node;
894   guint handler_id = 0;
895   
896   g_return_val_if_fail (G_TYPE_CHECK_INSTANCE (instance), 0);
897   g_return_val_if_fail (signal_id > 0, 0);
898   g_return_val_if_fail (closure != NULL, 0);
899   
900   G_LOCK (g_signal_mutex);
901   node = LOOKUP_SIGNAL_NODE (signal_id);
902   if (node && detail && !(node->flags & G_SIGNAL_DETAILED))
903     {
904       g_warning ("%s: signal id `%u' does not support detail (%u)", G_STRLOC, signal_id, detail);
905       G_UNLOCK (g_signal_mutex);
906       return 0;
907     }
908   if (node && g_type_conforms_to (G_TYPE_FROM_INSTANCE (instance), node->itype))
909     {
910       Handler *handler = handler_new (after);
911       
912       handler_id = handler->id;
913       handler->detail = detail;
914       handler->closure = g_closure_ref (closure);
915       handler_insert (signal_id, instance, handler);
916       if (node->c_marshaller && G_CLOSURE_NEEDS_MARSHAL (closure))
917         g_closure_set_marshal (closure, node->c_marshaller);
918     }
919   else
920     g_warning ("%s: signal id `%u' is invalid for instance `%p'", G_STRLOC, signal_id, instance);
921   G_UNLOCK (g_signal_mutex);
922   
923   return handler_id;
924 }
925
926 void
927 g_signal_handler_disconnect (gpointer instance,
928                              guint    handler_id)
929 {
930   Handler *handler;
931   guint signal_id;
932   
933   g_return_if_fail (G_TYPE_CHECK_INSTANCE (instance));
934   g_return_if_fail (handler_id > 0);
935   
936   G_LOCK (g_signal_mutex);
937   handler = handler_lookup (instance, handler_id, &signal_id);
938   if (handler)
939     {
940       handler->id = 0;
941       handler->block_count = 1;
942       handler_unref_R (signal_id, instance, handler);
943     }
944   else
945     g_warning ("%s: instance `%p' has no handler with id `%u'", G_STRLOC, instance, handler_id);
946   G_UNLOCK (g_signal_mutex);
947 }
948
949 void
950 g_signal_handlers_destroy (gpointer instance)
951 {
952   GBSearchArray *hlbsa;
953   
954   g_return_if_fail (G_TYPE_CHECK_INSTANCE (instance));
955   
956   G_LOCK (g_signal_mutex);
957   hlbsa = g_hash_table_lookup (g_handler_list_bsa_ht, instance);
958   if (hlbsa)
959     {
960       guint i;
961       
962       /* reentrancy caution, delete instance trace first */
963       g_hash_table_remove (g_handler_list_bsa_ht, instance);
964
965       for (i = 0; i < hlbsa->n_nodes; i++)
966         {
967           HandlerList *hlist = g_bsearch_array_get_nth (hlbsa, i);
968           Handler *handler = hlist->handlers;
969           
970           while (handler)
971             {
972               Handler *tmp = handler;
973               
974               handler = tmp->next;
975               tmp->block_count = 1;
976               /* cruel unlink, this works because _all_ handlers vanish */
977               tmp->next = NULL;
978               tmp->prev = tmp;
979               if (tmp->id)
980                 {
981                   tmp->id = 0;
982                   handler_unref_R (0, NULL, tmp);
983                 }
984             }
985         }
986       g_free (hlbsa->nodes);
987       g_generic_node_free (&g_bsa_ts, hlbsa);
988     }
989   G_UNLOCK (g_signal_mutex);
990 }
991
992 void
993 g_signal_handler_block (gpointer instance,
994                         guint    handler_id)
995 {
996   Handler *handler;
997   
998   g_return_if_fail (G_TYPE_CHECK_INSTANCE (instance));
999   g_return_if_fail (handler_id > 0);
1000   
1001   G_LOCK (g_signal_mutex);
1002   handler = handler_lookup (instance, handler_id, NULL);
1003   if (handler)
1004     {
1005 #ifndef G_DISABLE_CHECKS
1006       if (handler->block_count >= HANDLER_MAX_BLOCK_COUNT - 1)
1007         g_error (G_STRLOC ": handler block_count overflow, %s", REPORT_BUG);
1008 #endif
1009       
1010       handler->block_count += 1;
1011     }
1012   else
1013     g_warning ("%s: instance `%p' has no handler with id `%u'", G_STRLOC, instance, handler_id);
1014   G_UNLOCK (g_signal_mutex);
1015 }
1016
1017 void
1018 g_signal_handler_unblock (gpointer instance,
1019                           guint    handler_id)
1020 {
1021   Handler *handler;
1022   
1023   g_return_if_fail (G_TYPE_CHECK_INSTANCE (instance));
1024   g_return_if_fail (handler_id > 0);
1025   
1026   G_LOCK (g_signal_mutex);
1027   handler = handler_lookup (instance, handler_id, NULL);
1028   if (handler)
1029     {
1030       if (handler->block_count)
1031         handler->block_count -= 1;
1032       else
1033         g_warning (G_STRLOC ": handler `%u' of instance `%p' is not blocked", handler_id, instance);
1034     }
1035   else
1036     g_warning ("%s: instance `%p' has no handler with id `%u'", G_STRLOC, instance, handler_id);
1037   G_UNLOCK (g_signal_mutex);
1038 }
1039
1040 guint
1041 g_signal_handler_find (gpointer         instance,
1042                        GSignalMatchType mask,
1043                        guint            signal_id,
1044                        GQuark           detail,
1045                        GClosure        *closure,
1046                        gpointer         func,
1047                        gpointer         data)
1048 {
1049   Handler *handler = NULL;
1050   guint handler_id;
1051   
1052   g_return_val_if_fail (G_TYPE_CHECK_INSTANCE (instance), 0);
1053   g_return_val_if_fail ((mask & ~G_SIGNAL_MATCH_MASK) == 0, 0);
1054   
1055   G_LOCK (g_signal_mutex);
1056   handler = handler_find (instance, mask, signal_id, detail, closure, func, data);
1057   handler_id = handler ? handler->id : 0;
1058   G_UNLOCK (g_signal_mutex);
1059   
1060   return handler_id;
1061 }
1062
1063 gboolean
1064 g_signal_handler_pending (gpointer instance,
1065                           guint    signal_id,
1066                           GQuark   detail,
1067                           gboolean may_be_blocked)
1068 {
1069   Handler *handler = NULL;
1070   
1071   g_return_val_if_fail (G_TYPE_CHECK_INSTANCE (instance), FALSE);
1072   g_return_val_if_fail (signal_id > 0, FALSE);
1073   
1074   G_LOCK (g_signal_mutex);
1075   if (detail)
1076     {
1077       SignalNode *node = LOOKUP_SIGNAL_NODE (signal_id);
1078       
1079       if (!(node->flags & G_SIGNAL_DETAILED))
1080         {
1081           g_warning ("%s: signal id `%u' does not support detail (%u)", G_STRLOC, signal_id, detail);
1082           G_UNLOCK (g_signal_mutex);
1083           return FALSE;
1084         }
1085     }
1086   handler = handler_find (instance,
1087                           (G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_DETAIL |
1088                            (may_be_blocked ? 0 : G_SIGNAL_MATCH_UNBLOCKED)),
1089                           signal_id, detail, NULL, NULL, NULL);
1090   G_UNLOCK (g_signal_mutex);
1091   
1092   return handler != NULL;
1093 }
1094
1095 void
1096 g_signal_emitv (const GValue *instance_and_params,
1097                 guint         signal_id,
1098                 GQuark        detail,
1099                 GValue       *return_value)
1100 {
1101   SignalNode *node;
1102   gpointer instance;
1103   const GValue *param_values;
1104   guint i;
1105   
1106   g_return_if_fail (instance_and_params != NULL);
1107   instance = g_value_get_as_pointer (instance_and_params);
1108   g_return_if_fail (G_TYPE_CHECK_INSTANCE (instance));
1109   g_return_if_fail (signal_id > 0);
1110
1111   param_values = instance_and_params + 1;
1112   
1113   G_LOCK (g_signal_mutex);
1114   node = LOOKUP_SIGNAL_NODE (signal_id);
1115 #ifndef G_DISABLE_CHECKS
1116   if (!node || !g_type_conforms_to (G_TYPE_FROM_INSTANCE (instance), node->itype))
1117     g_warning ("%s: signal id `%u' is invalid for instance `%p'", G_STRLOC, signal_id, instance);
1118   if (detail && !(node->flags & G_SIGNAL_DETAILED))
1119     {
1120       g_warning ("%s: signal id `%u' does not support detail (%u)", G_STRLOC, signal_id, detail);
1121       G_UNLOCK (g_signal_mutex);
1122       return;
1123     }
1124   for (i = 0; i < node->n_params; i++)
1125     if (!G_VALUE_HOLDS (param_values + i, node->param_types[i]))
1126       {
1127         g_critical (G_STRLOC ": value for `%s' parameter %u for signal \"%s\" is of type `%s'",
1128                     g_type_name (node->param_types[i]),
1129                     i,
1130                     node->name,
1131                     G_VALUE_TYPE_NAME (param_values + i));
1132         G_UNLOCK (g_signal_mutex);
1133         return;
1134       }
1135   if (node->return_type != G_TYPE_NONE)
1136     {
1137       if (!return_value)
1138         {
1139           g_critical (G_STRLOC ": return value `%s' for signal \"%s\" is (NULL)",
1140                       g_type_name (node->return_type),
1141                       node->name);
1142           G_UNLOCK (g_signal_mutex);
1143           return;
1144         }
1145       else if (!node->accumulator && !G_VALUE_HOLDS (return_value, node->return_type))
1146         {
1147           g_critical (G_STRLOC ": return value `%s' for signal \"%s\" is of type `%s'",
1148                       g_type_name (node->return_type),
1149                       node->name,
1150                       G_VALUE_TYPE_NAME (return_value));
1151           G_UNLOCK (g_signal_mutex);
1152           return;
1153         }
1154     }
1155   else
1156     return_value = NULL;
1157 #endif  /* !G_DISABLE_CHECKS */
1158   
1159   signal_emit_R (node, detail, instance, return_value, instance_and_params);
1160   
1161   G_UNLOCK (g_signal_mutex);
1162 }
1163
1164 static void
1165 signal_emit_R (SignalNode   *node,
1166                GQuark        detail,
1167                gpointer      instance,
1168                GValue       *return_value,
1169                const GValue *instance_and_params)
1170 {
1171   EmissionState emission_state = 0;
1172   GSignalAccumulator accumulator;
1173   GSignalInvocationHint ihint;
1174   GClosure *class_closure;
1175   HandlerList *hlist;
1176   Handler *handler_list = NULL;
1177   GValue accu;
1178   gboolean accu_used = FALSE;
1179   guint signal_id = node->signal_id;
1180   
1181   if (node->flags & G_SIGNAL_NO_RECURSE)
1182     {
1183       Emission *emission = emission_find (g_restart_emissions, signal_id, detail, instance);
1184       
1185       if (emission)
1186         {
1187           *emission->state_p = EMISSION_RESTART;
1188           return;
1189         }
1190     }
1191   ihint.signal_id = node->signal_id;
1192   ihint.detail = detail;
1193   accumulator = node->accumulator;
1194   if (accumulator)
1195     {
1196       G_UNLOCK (g_signal_mutex);
1197       g_value_init (&accu, node->return_type);
1198       G_LOCK (g_signal_mutex);
1199     }
1200   emission_push ((node->flags & G_SIGNAL_NO_RECURSE) ? &g_restart_emissions : &g_recursive_emissions,
1201                  signal_id, detail, instance, &emission_state);
1202   class_closure = node->class_closure;
1203   
1204  EMIT_RESTART:
1205   
1206   if (handler_list)
1207     handler_unref_R (signal_id, instance, handler_list);
1208   hlist = handler_list_lookup (signal_id, instance);
1209   handler_list = hlist ? hlist->handlers : NULL;
1210   if (handler_list)
1211     handler_ref (handler_list);
1212   
1213   ihint.run_type = G_SIGNAL_RUN_FIRST;
1214   
1215   if ((node->flags & G_SIGNAL_RUN_FIRST) && class_closure)
1216     {
1217       emission_state = EMISSION_RUN;
1218       
1219       G_UNLOCK (g_signal_mutex);
1220       if (accumulator)
1221         {
1222           if (accu_used)
1223             g_value_reset (&accu);
1224           g_closure_invoke (class_closure,
1225                             &accu,
1226                             node->n_params + 1,
1227                             instance_and_params,
1228                             &ihint);
1229           if (!accumulator (&ihint, return_value, &accu) &&
1230               emission_state == EMISSION_RUN)
1231             emission_state = EMISSION_STOP;
1232           accu_used = TRUE;
1233         }
1234       else
1235         g_closure_invoke (class_closure,
1236                           return_value,
1237                           node->n_params + 1,
1238                           instance_and_params,
1239                           &ihint);
1240       G_LOCK (g_signal_mutex);
1241       
1242       if (emission_state == EMISSION_STOP)
1243         goto EMIT_CLEANUP;
1244       else if (emission_state == EMISSION_RESTART)
1245         goto EMIT_RESTART;
1246     }
1247   
1248   if (node->emission_hooks)
1249     {
1250       emission_state = EMISSION_HOOK;
1251       
1252       G_UNLOCK (g_signal_mutex);
1253       g_print ("emission_hooks()\n");
1254       G_LOCK (g_signal_mutex);
1255       
1256       if (emission_state == EMISSION_RESTART)
1257         goto EMIT_RESTART;
1258     }
1259   
1260   if (handler_list)
1261     {
1262       Handler *handler = handler_list;
1263       
1264       emission_state = EMISSION_RUN;
1265       handler_ref (handler);
1266       do
1267         {
1268           Handler *tmp;
1269           
1270           if (handler->after)
1271             {
1272               handler_unref_R (signal_id, instance, handler_list);
1273               handler_list = handler;
1274               break;
1275             }
1276           else if (!handler->block_count && (!handler->detail || handler->detail == detail))
1277             {
1278               G_UNLOCK (g_signal_mutex);
1279               if (accumulator)
1280                 {
1281                   if (accu_used)
1282                     g_value_reset (&accu);
1283                   g_closure_invoke (handler->closure,
1284                                     &accu,
1285                                     node->n_params + 1,
1286                                     instance_and_params,
1287                                     &ihint);
1288                   if (!accumulator (&ihint, return_value, &accu) &&
1289                       emission_state == EMISSION_RUN)
1290                     emission_state = EMISSION_STOP;
1291                   accu_used = TRUE;
1292                 }
1293               else
1294                 g_closure_invoke (handler->closure,
1295                                   return_value,
1296                                   node->n_params + 1,
1297                                   instance_and_params,
1298                                   &ihint);
1299               G_LOCK (g_signal_mutex);
1300               
1301               tmp = emission_state == EMISSION_RUN ? handler->next : NULL;
1302             }
1303           else
1304             tmp = handler->next;
1305           
1306           if (tmp)
1307             handler_ref (tmp);
1308           handler_unref_R (signal_id, instance, handler_list);
1309           handler_list = handler;
1310           handler = tmp;
1311         }
1312       while (handler);
1313       
1314       if (emission_state == EMISSION_STOP)
1315         goto EMIT_CLEANUP;
1316       else if (emission_state == EMISSION_RESTART)
1317         goto EMIT_RESTART;
1318     }
1319   
1320   ihint.run_type = G_SIGNAL_RUN_LAST;
1321   
1322   if ((node->flags & G_SIGNAL_RUN_LAST) && class_closure)
1323     {
1324       emission_state = EMISSION_RUN;
1325       
1326       G_UNLOCK (g_signal_mutex);
1327       if (accumulator)
1328         {
1329           if (accu_used)
1330             g_value_reset (&accu);
1331           g_closure_invoke (class_closure,
1332                             &accu,
1333                             node->n_params + 1,
1334                             instance_and_params,
1335                             &ihint);
1336           if (!accumulator (&ihint, return_value, &accu) &&
1337               emission_state == EMISSION_RUN)
1338             emission_state = EMISSION_STOP;
1339           accu_used = TRUE;
1340         }
1341       else
1342         g_closure_invoke (class_closure,
1343                           return_value,
1344                           node->n_params + 1,
1345                           instance_and_params,
1346                           &ihint);
1347       G_LOCK (g_signal_mutex);
1348       
1349       if (emission_state == EMISSION_STOP)
1350         goto EMIT_CLEANUP;
1351       else if (emission_state == EMISSION_RESTART)
1352         goto EMIT_RESTART;
1353     }
1354   
1355   if (handler_list)
1356     {
1357       Handler *handler = handler_list;
1358       
1359       emission_state = EMISSION_RUN;
1360       handler_ref (handler);
1361       do
1362         {
1363           Handler *tmp;
1364           
1365           if (handler->after && !handler->block_count && (!handler->detail || handler->detail == detail))
1366             {
1367               G_UNLOCK (g_signal_mutex);
1368               if (accumulator)
1369                 {
1370                   if (accu_used)
1371                     g_value_reset (&accu);
1372                   g_closure_invoke (handler->closure,
1373                                     &accu,
1374                                     node->n_params + 1,
1375                                     instance_and_params,
1376                                     &ihint);
1377                   if (!accumulator (&ihint, return_value, &accu) &&
1378                       emission_state == EMISSION_RUN)
1379                     emission_state = EMISSION_STOP;
1380                   accu_used = TRUE;
1381                 }
1382               else
1383                 g_closure_invoke (handler->closure,
1384                                   return_value,
1385                                   node->n_params + 1,
1386                                   instance_and_params,
1387                                   &ihint);
1388               G_LOCK (g_signal_mutex);
1389               
1390               tmp = emission_state == EMISSION_RUN ? handler->next : NULL;
1391             }
1392           else
1393             tmp = handler->next;
1394           
1395           if (tmp)
1396             handler_ref (tmp);
1397           handler_unref_R (signal_id, instance, handler);
1398           handler = tmp;
1399         }
1400       while (handler);
1401       
1402       if (emission_state == EMISSION_STOP)
1403         goto EMIT_CLEANUP;
1404       else if (emission_state == EMISSION_RESTART)
1405         goto EMIT_RESTART;
1406     }
1407   
1408  EMIT_CLEANUP:
1409   
1410   ihint.run_type = G_SIGNAL_RUN_CLEANUP;
1411   
1412   if ((node->flags & G_SIGNAL_RUN_CLEANUP) && class_closure)
1413     {
1414       gboolean need_unset = FALSE;
1415       
1416       emission_state = EMISSION_STOP;
1417       
1418       G_UNLOCK (g_signal_mutex);
1419       if (node->return_type != G_TYPE_NONE)
1420         {
1421           if (!accumulator)
1422             {
1423               g_value_init (&accu, node->return_type);
1424               need_unset = TRUE;
1425             }
1426           else if (accu_used)
1427             g_value_reset (&accu);
1428         }
1429       g_closure_invoke (class_closure,
1430                         node->return_type != G_TYPE_NONE ? &accu : NULL,
1431                         node->n_params + 1,
1432                         instance_and_params,
1433                         &ihint);
1434       if (need_unset)
1435         g_value_unset (&accu);
1436       G_LOCK (g_signal_mutex);
1437       
1438       if (emission_state == EMISSION_RESTART)
1439         goto EMIT_RESTART;
1440     }
1441   
1442   if (handler_list)
1443     handler_unref_R (signal_id, instance, handler_list);
1444   
1445   emission_pop ((node->flags & G_SIGNAL_NO_RECURSE) ? &g_restart_emissions : &g_recursive_emissions, &emission_state);
1446   if (accumulator)
1447     {
1448       G_UNLOCK (g_signal_mutex);
1449       g_value_unset (&accu);
1450       G_LOCK (g_signal_mutex);
1451     }
1452 }