Branch data Line data Source code
1 : : /* GObject - GLib Type, Object, Parameter and Signal Library
2 : : * Copyright (C) 2000-2001 Red Hat, Inc.
3 : : *
4 : : * SPDX-License-Identifier: LGPL-2.1-or-later
5 : : *
6 : : * This library is free software; you can redistribute it and/or
7 : : * modify it under the terms of the GNU Lesser General Public
8 : : * License as published by the Free Software Foundation; either
9 : : * version 2.1 of the License, or (at your option) any later version.
10 : : *
11 : : * This library is distributed in the hope that it will be useful,
12 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 : : * Lesser General Public License for more details.
15 : : *
16 : : * You should have received a copy of the GNU Lesser General
17 : : * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
18 : : *
19 : : * this code is based on the original GtkSignal implementation
20 : : * for the Gtk+ library by Peter Mattis <petm@xcf.berkeley.edu>
21 : : */
22 : :
23 : : /*
24 : : * MT safe
25 : : */
26 : :
27 : : #include "config.h"
28 : :
29 : : #include <signal.h>
30 : : #include <stdint.h>
31 : : #include <string.h>
32 : :
33 : : #include "gsignal.h"
34 : : #include "gtype-private.h"
35 : : #include "gbsearcharray.h"
36 : : #include "gvaluecollector.h"
37 : : #include "gvaluetypes.h"
38 : : #include "gobject.h"
39 : : #include "genums.h"
40 : : #include "gobject_trace.h"
41 : :
42 : :
43 : : #define REPORT_BUG "please report occurrence circumstances to https://gitlab.gnome.org/GNOME/glib/issues/new"
44 : :
45 : : /* --- typedefs --- */
46 : : typedef struct _SignalNode SignalNode;
47 : : typedef struct _SignalKey SignalKey;
48 : : typedef struct _Emission Emission;
49 : : typedef struct _Handler Handler;
50 : : typedef struct _HandlerList HandlerList;
51 : : typedef struct _HandlerMatch HandlerMatch;
52 : : typedef enum
53 : : {
54 : : EMISSION_STOP,
55 : : EMISSION_RUN,
56 : : EMISSION_HOOK,
57 : : EMISSION_RESTART
58 : : } EmissionState;
59 : :
60 : :
61 : : /* --- prototypes --- */
62 : : static inline guint signal_id_lookup (const gchar *name,
63 : : GType itype);
64 : : static void signal_destroy_R (SignalNode *signal_node);
65 : : static inline HandlerList* handler_list_ensure (guint signal_id,
66 : : gpointer instance);
67 : : static inline HandlerList* handler_list_lookup (guint signal_id,
68 : : gpointer instance);
69 : : static inline Handler* handler_new (guint signal_id,
70 : : gpointer instance,
71 : : gboolean after);
72 : : static void handler_insert (guint signal_id,
73 : : gpointer instance,
74 : : Handler *handler);
75 : : static Handler * handler_lookup_by_closure (gpointer instance,
76 : : GClosure *closure,
77 : : guint *signal_id_p);
78 : : static inline HandlerMatch* handler_match_prepend (HandlerMatch *list,
79 : : Handler *handler,
80 : : guint signal_id);
81 : : static inline HandlerMatch* handler_match_free1_R (HandlerMatch *node,
82 : : gpointer instance);
83 : : static HandlerMatch* handlers_find (gpointer instance,
84 : : GSignalMatchType mask,
85 : : guint signal_id,
86 : : GQuark detail,
87 : : GClosure *closure,
88 : : gpointer func,
89 : : gpointer data,
90 : : gboolean one_and_only);
91 : : static inline void handler_ref (Handler *handler);
92 : : static inline void handler_unref_R (guint signal_id,
93 : : gpointer instance,
94 : : Handler *handler);
95 : : static gint handler_lists_cmp (gconstpointer node1,
96 : : gconstpointer node2);
97 : : static inline void emission_push (Emission *emission);
98 : : static inline void emission_pop (Emission *emission);
99 : : static inline Emission* emission_find (guint signal_id,
100 : : GQuark detail,
101 : : gpointer instance);
102 : : static gint class_closures_cmp (gconstpointer node1,
103 : : gconstpointer node2);
104 : : static gint signal_key_cmp (gconstpointer node1,
105 : : gconstpointer node2);
106 : : static gboolean signal_emit_unlocked_R (SignalNode *node,
107 : : GQuark detail,
108 : : gpointer instance,
109 : : GValue *return_value,
110 : : const GValue *instance_and_params);
111 : : static void add_invalid_closure_notify (Handler *handler,
112 : : gpointer instance);
113 : : static void remove_invalid_closure_notify (Handler *handler,
114 : : gpointer instance);
115 : : static void invalid_closure_notify (gpointer data,
116 : : GClosure *closure);
117 : : static const gchar * type_debug_name (GType type);
118 : : static void node_check_deprecated (const SignalNode *node);
119 : : static void node_update_single_va_closure (SignalNode *node);
120 : :
121 : :
122 : : /* --- structures --- */
123 : : typedef struct
124 : : {
125 : : GSignalAccumulator func;
126 : : gpointer data;
127 : : } SignalAccumulator;
128 : : typedef struct
129 : : {
130 : : GHook hook;
131 : : GQuark detail;
132 : : } SignalHook;
133 : : #define SIGNAL_HOOK(hook) ((SignalHook*) (hook))
134 : :
135 : : struct _SignalNode
136 : : {
137 : : /* permanent portion */
138 : : guint signal_id;
139 : : GType itype;
140 : : const gchar *name;
141 : : guint destroyed : 1;
142 : :
143 : : /* reinitializable portion */
144 : : guint flags : 9;
145 : : guint n_params : 8;
146 : : guint single_va_closure_is_valid : 1;
147 : : guint single_va_closure_is_after : 1;
148 : : GType *param_types; /* mangled with G_SIGNAL_TYPE_STATIC_SCOPE flag */
149 : : GType return_type; /* mangled with G_SIGNAL_TYPE_STATIC_SCOPE flag */
150 : : GBSearchArray *class_closure_bsa;
151 : : SignalAccumulator *accumulator;
152 : : GSignalCMarshaller c_marshaller;
153 : : GSignalCVaMarshaller va_marshaller;
154 : : GHookList *emission_hooks;
155 : :
156 : : GClosure *single_va_closure;
157 : : };
158 : :
159 : : #define SINGLE_VA_CLOSURE_EMPTY_MAGIC GINT_TO_POINTER(1) /* indicates single_va_closure is valid but empty */
160 : :
161 : : struct _SignalKey
162 : : {
163 : : GType itype;
164 : : GQuark quark;
165 : : guint signal_id;
166 : : };
167 : :
168 : : struct _Emission
169 : : {
170 : : Emission *next;
171 : : gpointer instance;
172 : : GSignalInvocationHint ihint;
173 : : EmissionState state;
174 : : GType chain_type;
175 : : };
176 : :
177 : : struct _HandlerList
178 : : {
179 : : guint signal_id;
180 : : Handler *handlers;
181 : : Handler *tail_before; /* normal signal handlers are appended here */
182 : : Handler *tail_after; /* CONNECT_AFTER handlers are appended here */
183 : : };
184 : :
185 : : struct _Handler
186 : : {
187 : : gulong sequential_number;
188 : : Handler *next;
189 : : Handler *prev;
190 : : GQuark detail;
191 : : guint signal_id;
192 : : guint ref_count;
193 : : guint block_count : 16;
194 : : #define HANDLER_MAX_BLOCK_COUNT (1 << 16)
195 : : guint after : 1;
196 : : guint has_invalid_closure_notify : 1;
197 : : GClosure *closure;
198 : : gpointer instance;
199 : : };
200 : : struct _HandlerMatch
201 : : {
202 : : Handler *handler;
203 : : HandlerMatch *next;
204 : : guint signal_id;
205 : : };
206 : :
207 : : typedef struct
208 : : {
209 : : GType instance_type; /* 0 for default closure */
210 : : GClosure *closure;
211 : : } ClassClosure;
212 : :
213 : :
214 : : /* --- variables --- */
215 : : static GBSearchArray *g_signal_key_bsa = NULL;
216 : : static const GBSearchConfig g_signal_key_bconfig = {
217 : : sizeof (SignalKey),
218 : : signal_key_cmp,
219 : : G_BSEARCH_ARRAY_ALIGN_POWER2,
220 : : };
221 : : static GBSearchConfig g_signal_hlbsa_bconfig = {
222 : : sizeof (HandlerList),
223 : : handler_lists_cmp,
224 : : 0,
225 : : };
226 : : static GBSearchConfig g_class_closure_bconfig = {
227 : : sizeof (ClassClosure),
228 : : class_closures_cmp,
229 : : 0,
230 : : };
231 : : static GHashTable *g_handler_list_bsa_ht = NULL;
232 : : static Emission *g_emissions = NULL;
233 : : static gulong g_handler_sequential_number = 1;
234 : : static GHashTable *g_handlers = NULL;
235 : :
236 : : G_LOCK_DEFINE_STATIC (g_signal_mutex);
237 : : #define SIGNAL_LOCK() G_LOCK (g_signal_mutex)
238 : : #define SIGNAL_UNLOCK() G_UNLOCK (g_signal_mutex)
239 : :
240 : :
241 : : /* --- signal nodes --- */
242 : : static guint g_n_signal_nodes = 0;
243 : : static SignalNode **g_signal_nodes = NULL;
244 : :
245 : : static inline SignalNode*
246 : 45523071 : LOOKUP_SIGNAL_NODE (guint signal_id)
247 : : {
248 : 45523071 : if (signal_id < g_n_signal_nodes)
249 : 45523071 : return g_signal_nodes[signal_id];
250 : : else
251 : 0 : return NULL;
252 : 24247381 : }
253 : :
254 : :
255 : : /* --- functions --- */
256 : : /* @key must have already been validated with is_valid()
257 : : * Modifies @key in place. */
258 : : static void
259 : 8 : canonicalize_key (gchar *key)
260 : : {
261 : : gchar *p;
262 : :
263 : 93 : for (p = key; *p != 0; p++)
264 : : {
265 : 85 : gchar c = *p;
266 : :
267 : 85 : if (c == '_')
268 : 8 : *p = '-';
269 : 40 : }
270 : 8 : }
271 : :
272 : : /* @key must have already been validated with is_valid() */
273 : : static gboolean
274 : 5280 : is_canonical (const gchar *key)
275 : : {
276 : 5280 : return (strchr (key, '_') == NULL);
277 : : }
278 : :
279 : : /**
280 : : * g_signal_is_valid_name:
281 : : * @name: the canonical name of the signal
282 : : *
283 : : * Validate a signal name. This can be useful for dynamically-generated signals
284 : : * which need to be validated at run-time before actually trying to create them.
285 : : *
286 : : * See [func@GObject.signal_new] for details of the rules for valid names.
287 : : * The rules for signal names are the same as those for property names.
288 : : *
289 : : * Returns: %TRUE if @name is a valid signal name, %FALSE otherwise.
290 : : * Since: 2.66
291 : : */
292 : : gboolean
293 : 2654 : g_signal_is_valid_name (const gchar *name)
294 : : {
295 : : /* FIXME: We allow this, against our own documentation (the leading `-` is
296 : : * invalid), because GTK has historically used this. */
297 : 2654 : if (g_str_equal (name, "-gtk-private-changed"))
298 : 0 : return TRUE;
299 : :
300 : 2654 : return g_param_spec_is_valid_name (name);
301 : 607 : }
302 : :
303 : : static inline guint
304 : 626578 : signal_id_lookup (const gchar *name,
305 : : GType itype)
306 : : {
307 : : GQuark quark;
308 : 626578 : GType *ifaces, type = itype;
309 : : SignalKey key;
310 : : guint n_ifaces;
311 : :
312 : 626578 : quark = g_quark_try_string (name);
313 : 626578 : key.quark = quark;
314 : :
315 : : /* try looking up signals for this type and its ancestors */
316 : 104861 : do
317 : : {
318 : : SignalKey *signal_key;
319 : :
320 : 1035755 : key.itype = type;
321 : 1035755 : signal_key = g_bsearch_array_lookup (g_signal_key_bsa, &g_signal_key_bconfig, &key);
322 : :
323 : 1035755 : if (signal_key)
324 : 223144 : return signal_key->signal_id;
325 : :
326 : 812611 : type = g_type_parent (type);
327 : 1180 : }
328 : 812611 : while (type);
329 : :
330 : : /* no luck, try interfaces it exports */
331 : 403434 : ifaces = g_type_interfaces (itype, &n_ifaces);
332 : 805826 : while (n_ifaces--)
333 : : {
334 : : SignalKey *signal_key;
335 : :
336 : 803178 : key.itype = ifaces[n_ifaces];
337 : 803178 : signal_key = g_bsearch_array_lookup (g_signal_key_bsa, &g_signal_key_bconfig, &key);
338 : :
339 : 803178 : if (signal_key)
340 : : {
341 : 400786 : g_free (ifaces);
342 : 400786 : return signal_key->signal_id;
343 : : }
344 : : }
345 : 2648 : g_free (ifaces);
346 : :
347 : : /* If the @name is non-canonical, try again. This is the slow path — people
348 : : * should use canonical names in their queries if they want performance. */
349 : 2648 : if (!is_canonical (name))
350 : : {
351 : : guint signal_id;
352 : 5 : gchar *name_copy = g_strdup (name);
353 : 5 : canonicalize_key (name_copy);
354 : :
355 : 5 : signal_id = signal_id_lookup (name_copy, itype);
356 : :
357 : 5 : g_free (name_copy);
358 : :
359 : 5 : return signal_id;
360 : : }
361 : :
362 : 2643 : return 0;
363 : 104861 : }
364 : :
365 : : static gint
366 : 183 : class_closures_cmp (gconstpointer node1,
367 : : gconstpointer node2)
368 : : {
369 : 183 : const ClassClosure *c1 = node1, *c2 = node2;
370 : :
371 : 183 : return G_BSEARCH_ARRAY_CMP (c1->instance_type, c2->instance_type);
372 : : }
373 : :
374 : : static gint
375 : 62580234 : handler_lists_cmp (gconstpointer node1,
376 : : gconstpointer node2)
377 : : {
378 : 62580234 : const HandlerList *hlist1 = node1, *hlist2 = node2;
379 : :
380 : 62580234 : return G_BSEARCH_ARRAY_CMP (hlist1->signal_id, hlist2->signal_id);
381 : : }
382 : :
383 : : static inline HandlerList*
384 : 629320 : handler_list_ensure (guint signal_id,
385 : : gpointer instance)
386 : : {
387 : 629320 : GBSearchArray *hlbsa = g_hash_table_lookup (g_handler_list_bsa_ht, instance);
388 : : HandlerList key;
389 : :
390 : 629320 : key.signal_id = signal_id;
391 : 629320 : key.handlers = NULL;
392 : 629320 : key.tail_before = NULL;
393 : 629320 : key.tail_after = NULL;
394 : 629320 : if (!hlbsa)
395 : : {
396 : 207777 : hlbsa = g_bsearch_array_create (&g_signal_hlbsa_bconfig);
397 : 100583 : }
398 : 629320 : hlbsa = g_bsearch_array_insert (hlbsa, &g_signal_hlbsa_bconfig, &key);
399 : 629320 : g_hash_table_insert (g_handler_list_bsa_ht, instance, hlbsa);
400 : 629320 : return g_bsearch_array_lookup (hlbsa, &g_signal_hlbsa_bconfig, &key);
401 : : }
402 : :
403 : : static inline HandlerList*
404 : 45307731 : handler_list_lookup (guint signal_id,
405 : : gpointer instance)
406 : : {
407 : 45307731 : GBSearchArray *hlbsa = g_hash_table_lookup (g_handler_list_bsa_ht, instance);
408 : : HandlerList key;
409 : :
410 : 45307731 : key.signal_id = signal_id;
411 : :
412 : 45307731 : return hlbsa ? g_bsearch_array_lookup (hlbsa, &g_signal_hlbsa_bconfig, &key) : NULL;
413 : : }
414 : :
415 : : static guint
416 : 1258969 : handler_hash (gconstpointer key)
417 : : {
418 : 1258969 : return (guint)((Handler*)key)->sequential_number;
419 : : }
420 : :
421 : : static gboolean
422 : 629755 : handler_equal (gconstpointer a, gconstpointer b)
423 : : {
424 : 629755 : Handler *ha = (Handler *)a;
425 : 629755 : Handler *hb = (Handler *)b;
426 : 1259373 : return (ha->sequential_number == hb->sequential_number) &&
427 : 629618 : (ha->instance == hb->instance);
428 : : }
429 : :
430 : : static Handler *
431 : 762 : handler_lookup_by_id (gpointer instance,
432 : : gulong handler_id)
433 : : {
434 : : Handler key;
435 : :
436 : 762 : g_assert (handler_id != 0);
437 : :
438 : 762 : key.sequential_number = handler_id;
439 : 762 : key.instance = instance;
440 : :
441 : 762 : return g_hash_table_lookup (g_handlers, &key);
442 : : }
443 : :
444 : : static Handler *
445 : 627625 : handler_steal_by_id (gpointer instance,
446 : : gulong handler_id)
447 : : {
448 : : Handler key;
449 : 627625 : Handler *handler = NULL;
450 : :
451 : 627625 : g_assert (handler_id != 0);
452 : :
453 : 627625 : key.sequential_number = handler_id;
454 : 627625 : key.instance = instance;
455 : :
456 : 627625 : if (!g_hash_table_steal_extended (g_handlers, &key,
457 : : (gpointer *) &handler, NULL))
458 : 10 : return NULL;
459 : :
460 : 627615 : return handler;
461 : 101808 : }
462 : :
463 : : static Handler*
464 : 114 : handler_lookup_by_closure (gpointer instance,
465 : : GClosure *closure,
466 : : guint *signal_id_p)
467 : : {
468 : : GBSearchArray *hlbsa;
469 : :
470 : 114 : g_assert (closure != NULL);
471 : :
472 : 114 : hlbsa = g_hash_table_lookup (g_handler_list_bsa_ht, instance);
473 : :
474 : 114 : if (hlbsa)
475 : : {
476 : : guint i;
477 : :
478 : 114 : for (i = 0; i < hlbsa->n_nodes; i++)
479 : : {
480 : 114 : HandlerList *hlist = g_bsearch_array_get_nth (hlbsa, &g_signal_hlbsa_bconfig, i);
481 : : Handler *handler;
482 : :
483 : 131 : for (handler = hlist->handlers; handler; handler = handler->next)
484 : 131 : if (handler->closure == closure)
485 : : {
486 : 114 : if (signal_id_p)
487 : 114 : *signal_id_p = hlist->signal_id;
488 : :
489 : 114 : return handler;
490 : : }
491 : 0 : }
492 : 0 : }
493 : :
494 : 0 : return NULL;
495 : 57 : }
496 : :
497 : : static inline HandlerMatch*
498 : 403573 : handler_match_prepend (HandlerMatch *list,
499 : : Handler *handler,
500 : : guint signal_id)
501 : : {
502 : : HandlerMatch *node;
503 : :
504 : 403573 : node = g_slice_new (HandlerMatch);
505 : 403573 : node->handler = handler;
506 : 403573 : node->next = list;
507 : 403573 : node->signal_id = signal_id;
508 : 403573 : handler_ref (handler);
509 : :
510 : 403573 : return node;
511 : : }
512 : : static inline HandlerMatch*
513 : 403573 : handler_match_free1_R (HandlerMatch *node,
514 : : gpointer instance)
515 : : {
516 : 403573 : HandlerMatch *next = node->next;
517 : :
518 : 403573 : handler_unref_R (node->signal_id, instance, node->handler);
519 : 403573 : g_slice_free (HandlerMatch, node);
520 : :
521 : 403573 : return next;
522 : : }
523 : :
524 : : static HandlerMatch*
525 : 408995 : handlers_find (gpointer instance,
526 : : GSignalMatchType mask,
527 : : guint signal_id,
528 : : GQuark detail,
529 : : GClosure *closure,
530 : : gpointer func,
531 : : gpointer data,
532 : : gboolean one_and_only)
533 : : {
534 : 408995 : HandlerMatch *mlist = NULL;
535 : :
536 : 408995 : if (mask & G_SIGNAL_MATCH_ID)
537 : : {
538 : 170 : HandlerList *hlist = handler_list_lookup (signal_id, instance);
539 : : Handler *handler;
540 : 170 : SignalNode *node = NULL;
541 : :
542 : 170 : if (mask & G_SIGNAL_MATCH_FUNC)
543 : : {
544 : 5 : node = LOOKUP_SIGNAL_NODE (signal_id);
545 : 5 : if (!node || !node->c_marshaller)
546 : 0 : return NULL;
547 : 1 : }
548 : :
549 : 170 : mask = ~mask;
550 : 178 : for (handler = hlist ? hlist->handlers : NULL; handler; handler = handler->next)
551 : 95 : if (handler->sequential_number &&
552 : 91 : ((mask & G_SIGNAL_MATCH_DETAIL) || handler->detail == detail) &&
553 : 93 : ((mask & G_SIGNAL_MATCH_CLOSURE) || handler->closure == closure) &&
554 : 93 : ((mask & G_SIGNAL_MATCH_DATA) || handler->closure->data == data) &&
555 : 93 : ((mask & G_SIGNAL_MATCH_UNBLOCKED) || handler->block_count == 0) &&
556 : 92 : ((mask & G_SIGNAL_MATCH_FUNC) || (handler->closure->marshal == node->c_marshaller &&
557 : 3 : G_REAL_CLOSURE (handler->closure)->meta_marshal == NULL &&
558 : 14 : ((GCClosure*) handler->closure)->callback == func)))
559 : : {
560 : 91 : mlist = handler_match_prepend (mlist, handler, signal_id);
561 : 91 : if (one_and_only)
562 : 83 : return mlist;
563 : 4 : }
564 : 7 : }
565 : : else
566 : : {
567 : 408825 : GBSearchArray *hlbsa = g_hash_table_lookup (g_handler_list_bsa_ht, instance);
568 : :
569 : 408825 : mask = ~mask;
570 : 408825 : if (hlbsa)
571 : : {
572 : : guint i;
573 : :
574 : 2013107 : for (i = 0; i < hlbsa->n_nodes; i++)
575 : : {
576 : 1609546 : HandlerList *hlist = g_bsearch_array_get_nth (hlbsa, &g_signal_hlbsa_bconfig, i);
577 : 1609546 : SignalNode *node = NULL;
578 : : Handler *handler;
579 : :
580 : 1609546 : if (!(mask & G_SIGNAL_MATCH_FUNC))
581 : : {
582 : 1604310 : node = LOOKUP_SIGNAL_NODE (hlist->signal_id);
583 : 1604310 : if (!node->c_marshaller)
584 : 0 : continue;
585 : 1308 : }
586 : :
587 : 3662229 : for (handler = hlist->handlers; handler; handler = handler->next)
588 : 2057911 : if (handler->sequential_number &&
589 : 2052683 : ((mask & G_SIGNAL_MATCH_DETAIL) || handler->detail == detail) &&
590 : 2055297 : ((mask & G_SIGNAL_MATCH_CLOSURE) || handler->closure == closure) &&
591 : 2055297 : ((mask & G_SIGNAL_MATCH_DATA) || handler->closure->data == data) &&
592 : 1006404 : ((mask & G_SIGNAL_MATCH_UNBLOCKED) || handler->block_count == 0) &&
593 : 1005094 : ((mask & G_SIGNAL_MATCH_FUNC) || (handler->closure->marshal == node->c_marshaller &&
594 : 1003779 : G_REAL_CLOSURE (handler->closure)->meta_marshal == NULL &&
595 : 1538234 : ((GCClosure*) handler->closure)->callback == func)))
596 : : {
597 : 403482 : mlist = handler_match_prepend (mlist, handler, hlist->signal_id);
598 : 403482 : if (one_and_only)
599 : 0 : return mlist;
600 : 1307 : }
601 : 1308 : }
602 : 1307 : }
603 : : }
604 : :
605 : 403680 : return mlist;
606 : 1333 : }
607 : :
608 : : static inline Handler*
609 : 629320 : handler_new (guint signal_id, gpointer instance, gboolean after)
610 : : {
611 : 629320 : Handler *handler = g_slice_new (Handler);
612 : : #ifndef G_DISABLE_CHECKS
613 : 629320 : if (g_handler_sequential_number < 1)
614 : 0 : g_error (G_STRLOC ": handler id overflow, %s", REPORT_BUG);
615 : : #endif
616 : :
617 : 629320 : handler->sequential_number = g_handler_sequential_number++;
618 : 629320 : handler->prev = NULL;
619 : 629320 : handler->next = NULL;
620 : 629320 : handler->detail = 0;
621 : 629320 : handler->signal_id = signal_id;
622 : 629320 : handler->instance = instance;
623 : 629320 : handler->ref_count = 1;
624 : 629320 : handler->block_count = 0;
625 : 629320 : handler->after = after != FALSE;
626 : 629320 : handler->closure = NULL;
627 : 629320 : handler->has_invalid_closure_notify = 0;
628 : :
629 : 629320 : g_hash_table_add (g_handlers, handler);
630 : :
631 : 629320 : return handler;
632 : : }
633 : :
634 : : static inline void
635 : 49996800 : handler_ref (Handler *handler)
636 : : {
637 : 49996800 : g_return_if_fail (handler->ref_count > 0);
638 : :
639 : 49996800 : handler->ref_count++;
640 : 29566874 : }
641 : :
642 : : static inline void
643 : 50625661 : handler_unref_R (guint signal_id,
644 : : gpointer instance,
645 : : Handler *handler)
646 : : {
647 : 50625661 : g_return_if_fail (handler->ref_count > 0);
648 : :
649 : 50625661 : handler->ref_count--;
650 : :
651 : 50625661 : if (G_UNLIKELY (handler->ref_count == 0))
652 : : {
653 : 628871 : HandlerList *hlist = NULL;
654 : :
655 : 628871 : if (handler->next)
656 : 2094 : handler->next->prev = handler->prev;
657 : 628871 : if (handler->prev) /* watch out for g_signal_handlers_destroy()! */
658 : 13836 : handler->prev->next = handler->next;
659 : : else
660 : : {
661 : 615035 : hlist = handler_list_lookup (signal_id, instance);
662 : 615035 : g_assert (hlist != NULL);
663 : 615035 : hlist->handlers = handler->next;
664 : : }
665 : :
666 : 628871 : if (instance)
667 : : {
668 : : /* check if we are removing the handler pointed to by tail_before */
669 : 627723 : if (!handler->after && (!handler->next || handler->next->after))
670 : : {
671 : 625627 : if (!hlist)
672 : 11156 : hlist = handler_list_lookup (signal_id, instance);
673 : 625627 : if (hlist)
674 : : {
675 : 625627 : g_assert (hlist->tail_before == handler); /* paranoid */
676 : 625627 : hlist->tail_before = handler->prev;
677 : 101052 : }
678 : 101052 : }
679 : :
680 : : /* check if we are removing the handler pointed to by tail_after */
681 : 627723 : if (!handler->next)
682 : : {
683 : 625629 : if (!hlist)
684 : 4 : hlist = handler_list_lookup (signal_id, instance);
685 : 625629 : if (hlist)
686 : : {
687 : 625629 : g_assert (hlist->tail_after == handler); /* paranoid */
688 : 625629 : hlist->tail_after = handler->prev;
689 : 101053 : }
690 : 101053 : }
691 : 101860 : }
692 : :
693 : 628871 : SIGNAL_UNLOCK ();
694 : 628871 : g_closure_unref (handler->closure);
695 : 628871 : SIGNAL_LOCK ();
696 : 628871 : g_slice_free (Handler, handler);
697 : 102182 : }
698 : 29669054 : }
699 : :
700 : : static void
701 : 629320 : handler_insert (guint signal_id,
702 : : gpointer instance,
703 : : Handler *handler)
704 : : {
705 : : HandlerList *hlist;
706 : :
707 : 629320 : g_assert (handler->prev == NULL && handler->next == NULL); /* paranoid */
708 : :
709 : 629320 : hlist = handler_list_ensure (signal_id, instance);
710 : 629320 : if (!hlist->handlers)
711 : : {
712 : 615968 : hlist->handlers = handler;
713 : 615968 : if (!handler->after)
714 : 615966 : hlist->tail_before = handler;
715 : 100861 : }
716 : 13352 : else if (handler->after)
717 : : {
718 : 32 : handler->prev = hlist->tail_after;
719 : 32 : hlist->tail_after->next = handler;
720 : 15 : }
721 : : else
722 : : {
723 : 13320 : if (hlist->tail_before)
724 : : {
725 : 13316 : handler->next = hlist->tail_before->next;
726 : 13316 : if (handler->next)
727 : 54 : handler->next->prev = handler;
728 : 13316 : handler->prev = hlist->tail_before;
729 : 13316 : hlist->tail_before->next = handler;
730 : 1332 : }
731 : : else /* insert !after handler into a list of only after handlers */
732 : : {
733 : 4 : handler->next = hlist->handlers;
734 : 4 : if (handler->next)
735 : 4 : handler->next->prev = handler;
736 : 4 : hlist->handlers = handler;
737 : : }
738 : 13320 : hlist->tail_before = handler;
739 : : }
740 : :
741 : 629320 : if (!handler->next)
742 : 629262 : hlist->tail_after = handler;
743 : 629320 : }
744 : :
745 : : static void
746 : 685 : node_update_single_va_closure (SignalNode *node)
747 : : {
748 : 685 : GClosure *closure = NULL;
749 : 685 : gboolean is_after = FALSE;
750 : :
751 : : /* Fast path single-handler without boxing the arguments in GValues */
752 : 685 : if (G_TYPE_IS_OBJECT (node->itype) &&
753 : 585 : (node->flags & (G_SIGNAL_MUST_COLLECT)) == 0 &&
754 : 546 : (node->emission_hooks == NULL || node->emission_hooks->hooks == NULL))
755 : : {
756 : : GSignalFlags run_type;
757 : : ClassClosure * cc;
758 : 530 : GBSearchArray *bsa = node->class_closure_bsa;
759 : :
760 : 530 : if (bsa == NULL || bsa->n_nodes == 0)
761 : 51 : closure = SINGLE_VA_CLOSURE_EMPTY_MAGIC;
762 : 479 : else if (bsa->n_nodes == 1)
763 : : {
764 : : /* Look for default class closure (can't support non-default as it
765 : : chains up using GValues */
766 : 471 : cc = g_bsearch_array_get_nth (bsa, &g_class_closure_bconfig, 0);
767 : 471 : if (cc->instance_type == 0)
768 : : {
769 : 471 : run_type = node->flags & (G_SIGNAL_RUN_FIRST|G_SIGNAL_RUN_LAST|G_SIGNAL_RUN_CLEANUP);
770 : : /* Only support *one* of run-first or run-last, not multiple or cleanup */
771 : 471 : if (run_type == G_SIGNAL_RUN_FIRST ||
772 : 72 : run_type == G_SIGNAL_RUN_LAST)
773 : : {
774 : 461 : closure = cc->closure;
775 : 461 : is_after = (run_type == G_SIGNAL_RUN_LAST);
776 : 95 : }
777 : 100 : }
778 : 100 : }
779 : 128 : }
780 : :
781 : 685 : node->single_va_closure_is_valid = TRUE;
782 : 685 : node->single_va_closure = closure;
783 : 685 : node->single_va_closure_is_after = (guint) is_after;
784 : 685 : }
785 : :
786 : : static inline void
787 : 25868159 : emission_push (Emission *emission)
788 : : {
789 : 25868159 : emission->next = g_emissions;
790 : 25868159 : g_emissions = emission;
791 : 25868159 : }
792 : :
793 : : static inline void
794 : 25868149 : emission_pop (Emission *emission)
795 : : {
796 : 25868149 : Emission *node, *last = NULL;
797 : :
798 : 26654693 : for (node = g_emissions; node; last = node, node = last->next)
799 : 26654693 : if (node == emission)
800 : : {
801 : 25868149 : if (last)
802 : 647942 : last->next = node->next;
803 : : else
804 : 25220207 : g_emissions = node->next;
805 : 25868149 : return;
806 : : }
807 : : g_assert_not_reached ();
808 : 16297676 : }
809 : :
810 : : static inline Emission*
811 : 7598330 : emission_find (guint signal_id,
812 : : GQuark detail,
813 : : gpointer instance)
814 : : {
815 : : Emission *emission;
816 : :
817 : 8670107 : for (emission = g_emissions; emission; emission = emission->next)
818 : 1563386 : if (emission->instance == instance &&
819 : 491685 : emission->ihint.signal_id == signal_id &&
820 : 1021110 : emission->ihint.detail == detail)
821 : 491609 : return emission;
822 : 7106721 : return NULL;
823 : 4695826 : }
824 : :
825 : : static inline Emission*
826 : 48 : emission_find_innermost (gpointer instance)
827 : : {
828 : : Emission *emission;
829 : :
830 : 48 : for (emission = g_emissions; emission; emission = emission->next)
831 : 48 : if (emission->instance == instance)
832 : 48 : return emission;
833 : :
834 : 0 : return NULL;
835 : 24 : }
836 : :
837 : : static gint
838 : 7900038 : signal_key_cmp (gconstpointer node1,
839 : : gconstpointer node2)
840 : : {
841 : 7900038 : const SignalKey *key1 = node1, *key2 = node2;
842 : :
843 : 7900038 : if (key1->itype == key2->itype)
844 : 1432586 : return G_BSEARCH_ARRAY_CMP (key1->quark, key2->quark);
845 : : else
846 : 6467452 : return G_BSEARCH_ARRAY_CMP (key1->itype, key2->itype);
847 : 109426 : }
848 : :
849 : : void
850 : 853 : _g_signal_init (void)
851 : : {
852 : 853 : SIGNAL_LOCK ();
853 : 853 : if (!g_n_signal_nodes)
854 : : {
855 : : /* setup handler list binary searchable array hash table (in german, that'd be one word ;) */
856 : 853 : g_handler_list_bsa_ht = g_hash_table_new (g_direct_hash, NULL);
857 : 853 : g_signal_key_bsa = g_bsearch_array_create (&g_signal_key_bconfig);
858 : :
859 : : /* invalid (0) signal_id */
860 : 853 : g_n_signal_nodes = 1;
861 : 853 : g_signal_nodes = g_renew (SignalNode*, g_signal_nodes, g_n_signal_nodes);
862 : 853 : g_signal_nodes[0] = NULL;
863 : 853 : g_handlers = g_hash_table_new (handler_hash, handler_equal);
864 : 262 : }
865 : 853 : SIGNAL_UNLOCK ();
866 : 853 : }
867 : :
868 : : void
869 : 0 : _g_signals_destroy (GType itype)
870 : : {
871 : : guint i;
872 : :
873 : 0 : SIGNAL_LOCK ();
874 : 0 : for (i = 1; i < g_n_signal_nodes; i++)
875 : : {
876 : 0 : SignalNode *node = g_signal_nodes[i];
877 : :
878 : 0 : if (node->itype == itype)
879 : : {
880 : 0 : if (node->destroyed)
881 : 0 : g_critical (G_STRLOC ": signal \"%s\" of type '%s' already destroyed",
882 : 0 : node->name,
883 : 0 : type_debug_name (node->itype));
884 : : else
885 : 0 : signal_destroy_R (node);
886 : 0 : }
887 : 0 : }
888 : 0 : SIGNAL_UNLOCK ();
889 : 0 : }
890 : :
891 : : /**
892 : : * g_signal_stop_emission:
893 : : * @instance: (type GObject.Object): the object whose signal handlers you wish to stop.
894 : : * @signal_id: the signal identifier, as returned by g_signal_lookup().
895 : : * @detail: the detail which the signal was emitted with.
896 : : *
897 : : * Stops a signal's current emission.
898 : : *
899 : : * This will prevent the default method from running, if the signal was
900 : : * %G_SIGNAL_RUN_LAST and you connected normally (i.e. without the "after"
901 : : * flag).
902 : : *
903 : : * Prints a warning if used on a signal which isn't being emitted.
904 : : */
905 : : void
906 : 2 : g_signal_stop_emission (gpointer instance,
907 : : guint signal_id,
908 : : GQuark detail)
909 : : {
910 : : SignalNode *node;
911 : :
912 : 2 : g_return_if_fail (G_TYPE_CHECK_INSTANCE (instance));
913 : 2 : g_return_if_fail (signal_id > 0);
914 : :
915 : 2 : SIGNAL_LOCK ();
916 : 2 : node = LOOKUP_SIGNAL_NODE (signal_id);
917 : 2 : if (node && detail && !(node->flags & G_SIGNAL_DETAILED))
918 : : {
919 : 0 : g_critical ("%s: signal id '%u' does not support detail (%u)", G_STRLOC, signal_id, detail);
920 : 0 : SIGNAL_UNLOCK ();
921 : 0 : return;
922 : : }
923 : 2 : if (node && g_type_is_a (G_TYPE_FROM_INSTANCE (instance), node->itype))
924 : 1 : {
925 : 2 : Emission *emission = emission_find (signal_id, detail, instance);
926 : :
927 : 2 : if (emission)
928 : : {
929 : 2 : if (emission->state == EMISSION_HOOK)
930 : 0 : g_critical (G_STRLOC ": emission of signal \"%s\" for instance '%p' cannot be stopped from emission hook",
931 : 0 : node->name, instance);
932 : 2 : else if (emission->state == EMISSION_RUN)
933 : 2 : emission->state = EMISSION_STOP;
934 : 1 : }
935 : : else
936 : 0 : g_critical (G_STRLOC ": no emission of signal \"%s\" to stop for instance '%p'",
937 : 0 : node->name, instance);
938 : 1 : }
939 : : else
940 : 0 : g_critical ("%s: signal id '%u' is invalid for instance '%p'", G_STRLOC, signal_id, instance);
941 : 2 : SIGNAL_UNLOCK ();
942 : 1 : }
943 : :
944 : : static void
945 : 52 : signal_finalize_hook (GHookList *hook_list,
946 : : GHook *hook)
947 : : {
948 : 52 : GDestroyNotify destroy = hook->destroy;
949 : :
950 : 52 : if (destroy)
951 : : {
952 : 0 : hook->destroy = NULL;
953 : 0 : SIGNAL_UNLOCK ();
954 : 0 : destroy (hook->data);
955 : 0 : SIGNAL_LOCK ();
956 : 0 : }
957 : 52 : }
958 : :
959 : : /**
960 : : * g_signal_add_emission_hook:
961 : : * @signal_id: the signal identifier, as returned by g_signal_lookup().
962 : : * @detail: the detail on which to call the hook.
963 : : * @hook_func: (not nullable) (closure hook_data): a #GSignalEmissionHook function.
964 : : * @hook_data: (nullable): user data for @hook_func.
965 : : * @data_destroy: (nullable) (destroy hook_data): a #GDestroyNotify for @hook_data.
966 : : *
967 : : * Adds an emission hook for a signal, which will get called for any emission
968 : : * of that signal, independent of the instance. This is possible only
969 : : * for signals which don't have %G_SIGNAL_NO_HOOKS flag set.
970 : : *
971 : : * Returns: the hook id, for later use with g_signal_remove_emission_hook().
972 : : */
973 : : gulong
974 : 52 : g_signal_add_emission_hook (guint signal_id,
975 : : GQuark detail,
976 : : GSignalEmissionHook hook_func,
977 : : gpointer hook_data,
978 : : GDestroyNotify data_destroy)
979 : : {
980 : : static gulong seq_hook_id = 1;
981 : : SignalNode *node;
982 : : GHook *hook;
983 : : SignalHook *signal_hook;
984 : :
985 : 52 : g_return_val_if_fail (signal_id > 0, 0);
986 : 52 : g_return_val_if_fail (hook_func != NULL, 0);
987 : :
988 : 52 : SIGNAL_LOCK ();
989 : 52 : node = LOOKUP_SIGNAL_NODE (signal_id);
990 : 52 : if (!node || node->destroyed)
991 : : {
992 : 0 : g_critical ("%s: invalid signal id '%u'", G_STRLOC, signal_id);
993 : 0 : SIGNAL_UNLOCK ();
994 : 0 : return 0;
995 : : }
996 : 52 : if (node->flags & G_SIGNAL_NO_HOOKS)
997 : : {
998 : 0 : g_critical ("%s: signal id '%u' does not support emission hooks (G_SIGNAL_NO_HOOKS flag set)", G_STRLOC, signal_id);
999 : 0 : SIGNAL_UNLOCK ();
1000 : 0 : return 0;
1001 : : }
1002 : 52 : if (detail && !(node->flags & G_SIGNAL_DETAILED))
1003 : : {
1004 : 0 : g_critical ("%s: signal id '%u' does not support detail (%u)", G_STRLOC, signal_id, detail);
1005 : 0 : SIGNAL_UNLOCK ();
1006 : 0 : return 0;
1007 : : }
1008 : 52 : node->single_va_closure_is_valid = FALSE;
1009 : 52 : if (!node->emission_hooks)
1010 : : {
1011 : 6 : node->emission_hooks = g_new (GHookList, 1);
1012 : 6 : g_hook_list_init (node->emission_hooks, sizeof (SignalHook));
1013 : 6 : node->emission_hooks->finalize_hook = signal_finalize_hook;
1014 : 3 : }
1015 : :
1016 : 52 : node_check_deprecated (node);
1017 : :
1018 : 52 : hook = g_hook_alloc (node->emission_hooks);
1019 : 52 : hook->data = hook_data;
1020 : 52 : hook->func = (gpointer) hook_func;
1021 : 52 : hook->destroy = data_destroy;
1022 : 52 : signal_hook = SIGNAL_HOOK (hook);
1023 : 52 : signal_hook->detail = detail;
1024 : 52 : node->emission_hooks->seq_id = seq_hook_id;
1025 : 52 : g_hook_append (node->emission_hooks, hook);
1026 : 52 : seq_hook_id = node->emission_hooks->seq_id;
1027 : :
1028 : 52 : SIGNAL_UNLOCK ();
1029 : :
1030 : 52 : return hook->hook_id;
1031 : 26 : }
1032 : :
1033 : : /**
1034 : : * g_signal_remove_emission_hook:
1035 : : * @signal_id: the id of the signal
1036 : : * @hook_id: the id of the emission hook, as returned by
1037 : : * g_signal_add_emission_hook()
1038 : : *
1039 : : * Deletes an emission hook.
1040 : : */
1041 : : void
1042 : 54 : g_signal_remove_emission_hook (guint signal_id,
1043 : : gulong hook_id)
1044 : : {
1045 : : SignalNode *node;
1046 : :
1047 : 54 : g_return_if_fail (signal_id > 0);
1048 : 54 : g_return_if_fail (hook_id > 0);
1049 : :
1050 : 54 : SIGNAL_LOCK ();
1051 : 54 : node = LOOKUP_SIGNAL_NODE (signal_id);
1052 : 54 : if (!node || node->destroyed)
1053 : : {
1054 : 0 : g_critical ("%s: invalid signal id '%u'", G_STRLOC, signal_id);
1055 : 0 : goto out;
1056 : : }
1057 : 54 : else if (!node->emission_hooks || !g_hook_destroy (node->emission_hooks, hook_id))
1058 : 24 : g_critical ("%s: signal \"%s\" had no hook (%lu) to remove", G_STRLOC, node->name, hook_id);
1059 : :
1060 : 54 : node->single_va_closure_is_valid = FALSE;
1061 : :
1062 : 27 : out:
1063 : 54 : SIGNAL_UNLOCK ();
1064 : 27 : }
1065 : :
1066 : : static inline guint
1067 : 619356 : signal_parse_name (const gchar *name,
1068 : : GType itype,
1069 : : GQuark *detail_p,
1070 : : gboolean force_quark)
1071 : : {
1072 : 619356 : const gchar *colon = strchr (name, ':');
1073 : : guint signal_id;
1074 : :
1075 : 619356 : if (!colon)
1076 : : {
1077 : 618890 : signal_id = signal_id_lookup (name, itype);
1078 : 618890 : if (signal_id && detail_p)
1079 : 618884 : *detail_p = 0;
1080 : 101891 : }
1081 : 466 : else if (colon[1] == ':')
1082 : : {
1083 : : gchar buffer[32];
1084 : 458 : size_t l = (size_t) (colon - name);
1085 : :
1086 : 458 : if (colon[2] == '\0')
1087 : 4 : return 0;
1088 : :
1089 : 454 : if (l < 32)
1090 : : {
1091 : 454 : memcpy (buffer, name, l);
1092 : 454 : buffer[l] = 0;
1093 : 454 : signal_id = signal_id_lookup (buffer, itype);
1094 : 90 : }
1095 : : else
1096 : : {
1097 : 0 : gchar *signal = g_new (gchar, l + 1);
1098 : :
1099 : 0 : memcpy (signal, name, l);
1100 : 0 : signal[l] = 0;
1101 : 0 : signal_id = signal_id_lookup (signal, itype);
1102 : 0 : g_free (signal);
1103 : : }
1104 : :
1105 : 454 : if (signal_id && detail_p)
1106 : 452 : *detail_p = (force_quark ? g_quark_from_string : g_quark_try_string) (colon + 2);
1107 : 90 : }
1108 : : else
1109 : 8 : signal_id = 0;
1110 : 619352 : return signal_id;
1111 : 101987 : }
1112 : :
1113 : : /**
1114 : : * g_signal_parse_name:
1115 : : * @detailed_signal: a string of the form "signal-name::detail".
1116 : : * @itype: The interface/instance type that introduced "signal-name".
1117 : : * @signal_id_p: (out): Location to store the signal id.
1118 : : * @detail_p: (out): Location to store the detail quark.
1119 : : * @force_detail_quark: %TRUE forces creation of a #GQuark for the detail.
1120 : : *
1121 : : * Internal function to parse a signal name into its @signal_id
1122 : : * and @detail quark.
1123 : : *
1124 : : * Returns: Whether the signal name could successfully be parsed and @signal_id_p and @detail_p contain valid return values.
1125 : : */
1126 : : gboolean
1127 : 98 : g_signal_parse_name (const gchar *detailed_signal,
1128 : : GType itype,
1129 : : guint *signal_id_p,
1130 : : GQuark *detail_p,
1131 : : gboolean force_detail_quark)
1132 : : {
1133 : : SignalNode *node;
1134 : 98 : GQuark detail = 0;
1135 : : guint signal_id;
1136 : :
1137 : 98 : g_return_val_if_fail (detailed_signal != NULL, FALSE);
1138 : 98 : g_return_val_if_fail (G_TYPE_IS_INSTANTIATABLE (itype) || G_TYPE_IS_INTERFACE (itype), FALSE);
1139 : :
1140 : 98 : SIGNAL_LOCK ();
1141 : 98 : signal_id = signal_parse_name (detailed_signal, itype, &detail, force_detail_quark);
1142 : :
1143 : 98 : node = signal_id ? LOOKUP_SIGNAL_NODE (signal_id) : NULL;
1144 : :
1145 : 109 : if (!node || node->destroyed ||
1146 : 78 : (detail && !(node->flags & G_SIGNAL_DETAILED)))
1147 : : {
1148 : 22 : SIGNAL_UNLOCK ();
1149 : 22 : return FALSE;
1150 : : }
1151 : :
1152 : 76 : SIGNAL_UNLOCK ();
1153 : :
1154 : 76 : if (signal_id_p)
1155 : 76 : *signal_id_p = signal_id;
1156 : 76 : if (detail_p)
1157 : 76 : *detail_p = detail;
1158 : :
1159 : 76 : return TRUE;
1160 : 49 : }
1161 : :
1162 : : /**
1163 : : * g_signal_stop_emission_by_name:
1164 : : * @instance: (type GObject.Object): the object whose signal handlers you wish to stop.
1165 : : * @detailed_signal: a string of the form "signal-name::detail".
1166 : : *
1167 : : * Stops a signal's current emission.
1168 : : *
1169 : : * This is just like g_signal_stop_emission() except it will look up the
1170 : : * signal id for you.
1171 : : */
1172 : : void
1173 : 2 : g_signal_stop_emission_by_name (gpointer instance,
1174 : : const gchar *detailed_signal)
1175 : : {
1176 : : guint signal_id;
1177 : 2 : GQuark detail = 0;
1178 : : GType itype;
1179 : :
1180 : 2 : g_return_if_fail (G_TYPE_CHECK_INSTANCE (instance));
1181 : 2 : g_return_if_fail (detailed_signal != NULL);
1182 : :
1183 : 2 : SIGNAL_LOCK ();
1184 : 2 : itype = G_TYPE_FROM_INSTANCE (instance);
1185 : 2 : signal_id = signal_parse_name (detailed_signal, itype, &detail, TRUE);
1186 : 2 : if (signal_id)
1187 : : {
1188 : 2 : SignalNode *node = LOOKUP_SIGNAL_NODE (signal_id);
1189 : :
1190 : 2 : if (detail && !(node->flags & G_SIGNAL_DETAILED))
1191 : 0 : g_critical ("%s: signal '%s' does not support details", G_STRLOC, detailed_signal);
1192 : 2 : else if (!g_type_is_a (itype, node->itype))
1193 : 0 : g_critical ("%s: signal '%s' is invalid for instance '%p' of type '%s'",
1194 : 0 : G_STRLOC, detailed_signal, instance, g_type_name (itype));
1195 : : else
1196 : : {
1197 : 2 : Emission *emission = emission_find (signal_id, detail, instance);
1198 : :
1199 : 2 : if (emission)
1200 : : {
1201 : 2 : if (emission->state == EMISSION_HOOK)
1202 : 0 : g_critical (G_STRLOC ": emission of signal \"%s\" for instance '%p' cannot be stopped from emission hook",
1203 : 0 : node->name, instance);
1204 : 2 : else if (emission->state == EMISSION_RUN)
1205 : 2 : emission->state = EMISSION_STOP;
1206 : 1 : }
1207 : : else
1208 : 0 : g_critical (G_STRLOC ": no emission of signal \"%s\" to stop for instance '%p'",
1209 : 0 : node->name, instance);
1210 : : }
1211 : 1 : }
1212 : : else
1213 : 0 : g_critical ("%s: signal '%s' is invalid for instance '%p' of type '%s'",
1214 : 0 : G_STRLOC, detailed_signal, instance, g_type_name (itype));
1215 : 2 : SIGNAL_UNLOCK ();
1216 : 1 : }
1217 : :
1218 : : /**
1219 : : * g_signal_lookup:
1220 : : * @name: the signal's name.
1221 : : * @itype: the type that the signal operates on.
1222 : : *
1223 : : * Given the name of the signal and the type of object it connects to, gets
1224 : : * the signal's identifying integer. Emitting the signal by number is
1225 : : * somewhat faster than using the name each time.
1226 : : *
1227 : : * Also tries the ancestors of the given type.
1228 : : *
1229 : : * The type class passed as @itype must already have been instantiated (for
1230 : : * example, using g_type_class_ref()) for this function to work, as signals are
1231 : : * always installed during class initialization.
1232 : : *
1233 : : * See g_signal_new() for details on allowed signal names.
1234 : : *
1235 : : * Returns: the signal's identifying number, or 0 if no signal was found.
1236 : : */
1237 : : guint
1238 : 4596 : g_signal_lookup (const gchar *name,
1239 : : GType itype)
1240 : : {
1241 : : guint signal_id;
1242 : 4596 : g_return_val_if_fail (name != NULL, 0);
1243 : 4596 : g_return_val_if_fail (G_TYPE_IS_INSTANTIATABLE (itype) || G_TYPE_IS_INTERFACE (itype), 0);
1244 : :
1245 : 4596 : SIGNAL_LOCK ();
1246 : 4596 : signal_id = signal_id_lookup (name, itype);
1247 : 4596 : SIGNAL_UNLOCK ();
1248 : 4596 : if (!signal_id)
1249 : : {
1250 : : /* give elaborate warnings */
1251 : 2 : if (!g_type_name (itype))
1252 : 0 : g_critical (G_STRLOC ": unable to look up signal \"%s\" for invalid type id '%"G_GUINTPTR_FORMAT"'",
1253 : 0 : name, (guintptr) itype);
1254 : 2 : else if (!g_signal_is_valid_name (name))
1255 : 1 : g_critical (G_STRLOC ": unable to look up invalid signal name \"%s\" on type '%s'",
1256 : 1 : name, g_type_name (itype));
1257 : 1 : }
1258 : :
1259 : 4596 : return signal_id;
1260 : 2283 : }
1261 : :
1262 : : /**
1263 : : * g_signal_list_ids:
1264 : : * @itype: Instance or interface type.
1265 : : * @n_ids: Location to store the number of signal ids for @itype.
1266 : : *
1267 : : * Lists the signals by id that a certain instance or interface type
1268 : : * created. Further information about the signals can be acquired through
1269 : : * g_signal_query().
1270 : : *
1271 : : * Returns: (array length=n_ids) (transfer full): Newly allocated array of signal IDs.
1272 : : */
1273 : : guint*
1274 : 321 : g_signal_list_ids (GType itype,
1275 : : guint *n_ids)
1276 : : {
1277 : : SignalKey *keys;
1278 : : GArray *result;
1279 : : guint n_nodes;
1280 : : guint i;
1281 : :
1282 : 321 : g_return_val_if_fail (G_TYPE_IS_INSTANTIATABLE (itype) || G_TYPE_IS_INTERFACE (itype), NULL);
1283 : 321 : g_return_val_if_fail (n_ids != NULL, NULL);
1284 : :
1285 : 321 : SIGNAL_LOCK ();
1286 : 321 : keys = g_bsearch_array_get_nth (g_signal_key_bsa, &g_signal_key_bconfig, 0);
1287 : 321 : n_nodes = g_bsearch_array_get_n_nodes (g_signal_key_bsa);
1288 : 321 : result = g_array_new (FALSE, FALSE, sizeof (guint));
1289 : :
1290 : 12844 : for (i = 0; i < n_nodes; i++)
1291 : 12633 : if (keys[i].itype == itype)
1292 : : {
1293 : 222 : g_array_append_val (result, keys[i].signal_id);
1294 : 110 : }
1295 : 321 : *n_ids = result->len;
1296 : 321 : SIGNAL_UNLOCK ();
1297 : 321 : if (!n_nodes)
1298 : : {
1299 : : /* give elaborate warnings */
1300 : 0 : if (!g_type_name (itype))
1301 : 0 : g_critical (G_STRLOC ": unable to list signals for invalid type id '%"G_GUINTPTR_FORMAT"'",
1302 : 0 : (guintptr) itype);
1303 : 0 : else if (!G_TYPE_IS_INSTANTIATABLE (itype) && !G_TYPE_IS_INTERFACE (itype))
1304 : 0 : g_critical (G_STRLOC ": unable to list signals of non instantiatable type '%s'",
1305 : 0 : g_type_name (itype));
1306 : 0 : else if (!g_type_class_peek (itype) && !G_TYPE_IS_INTERFACE (itype))
1307 : 0 : g_critical (G_STRLOC ": unable to list signals of unloaded type '%s'",
1308 : 0 : g_type_name (itype));
1309 : 0 : }
1310 : :
1311 : 321 : return (guint*) g_array_free (result, FALSE);
1312 : 158 : }
1313 : :
1314 : : /**
1315 : : * g_signal_name:
1316 : : * @signal_id: the signal's identifying number.
1317 : : *
1318 : : * Given the signal's identifier, finds its name.
1319 : : *
1320 : : * Two different signals may have the same name, if they have differing types.
1321 : : *
1322 : : * Returns: (nullable): the signal name, or %NULL if the signal number was invalid.
1323 : : */
1324 : : const gchar *
1325 : 60 : g_signal_name (guint signal_id)
1326 : : {
1327 : : SignalNode *node;
1328 : : const gchar *name;
1329 : :
1330 : 60 : SIGNAL_LOCK ();
1331 : 60 : node = LOOKUP_SIGNAL_NODE (signal_id);
1332 : 60 : name = node ? node->name : NULL;
1333 : 60 : SIGNAL_UNLOCK ();
1334 : :
1335 : 60 : return (char*) name;
1336 : : }
1337 : :
1338 : : /**
1339 : : * g_signal_query:
1340 : : * @signal_id: The signal id of the signal to query information for.
1341 : : * @query: (out caller-allocates) (not optional): A user provided structure that is
1342 : : * filled in with constant values upon success.
1343 : : *
1344 : : * Queries the signal system for in-depth information about a
1345 : : * specific signal. This function will fill in a user-provided
1346 : : * structure to hold signal-specific information. If an invalid
1347 : : * signal id is passed in, the @signal_id member of the #GSignalQuery
1348 : : * is 0. All members filled into the #GSignalQuery structure should
1349 : : * be considered constant and have to be left untouched.
1350 : : */
1351 : : void
1352 : 168 : g_signal_query (guint signal_id,
1353 : : GSignalQuery *query)
1354 : : {
1355 : : SignalNode *node;
1356 : :
1357 : 168 : g_return_if_fail (query != NULL);
1358 : :
1359 : 168 : SIGNAL_LOCK ();
1360 : 168 : node = LOOKUP_SIGNAL_NODE (signal_id);
1361 : 168 : if (!node || node->destroyed)
1362 : 0 : query->signal_id = 0;
1363 : : else
1364 : : {
1365 : 168 : query->signal_id = node->signal_id;
1366 : 168 : query->signal_name = node->name;
1367 : 168 : query->itype = node->itype;
1368 : 168 : query->signal_flags = node->flags;
1369 : 168 : query->return_type = node->return_type;
1370 : 168 : query->n_params = node->n_params;
1371 : 168 : query->param_types = node->param_types;
1372 : : }
1373 : 168 : SIGNAL_UNLOCK ();
1374 : 83 : }
1375 : :
1376 : : /**
1377 : : * g_signal_new:
1378 : : * @signal_name: the name for the signal
1379 : : * @itype: the type this signal pertains to. It will also pertain to
1380 : : * types which are derived from this type.
1381 : : * @signal_flags: a combination of #GSignalFlags specifying detail of when
1382 : : * the default handler is to be invoked. You should at least specify
1383 : : * %G_SIGNAL_RUN_FIRST or %G_SIGNAL_RUN_LAST.
1384 : : * @class_offset: The offset of the function pointer in the class structure
1385 : : * for this type. Used to invoke a class method generically. Pass 0 to
1386 : : * not associate a class method slot with this signal.
1387 : : * @accumulator: (nullable) (scope forever) (closure accu_data): the accumulator for this signal; may be %NULL.
1388 : : * @accu_data: (nullable): user data for the @accumulator.
1389 : : * @c_marshaller: (nullable): the function to translate arrays of parameter
1390 : : * values to signal emissions into C language callback invocations or %NULL.
1391 : : * @return_type: the type of return value, or %G_TYPE_NONE for a signal
1392 : : * without a return value.
1393 : : * @n_params: the number of parameter types to follow.
1394 : : * @...: a list of types, one for each parameter.
1395 : : *
1396 : : * Creates a new signal. (This is usually done in the class initializer.)
1397 : : *
1398 : : * A signal name consists of segments consisting of ASCII letters and
1399 : : * digits, separated by either the `-` or `_` character. The first
1400 : : * character of a signal name must be a letter. Names which violate these
1401 : : * rules lead to undefined behaviour. These are the same rules as for property
1402 : : * naming (see g_param_spec_internal()).
1403 : : *
1404 : : * When registering a signal and looking up a signal, either separator can
1405 : : * be used, but they cannot be mixed. Using `-` is considerably more efficient.
1406 : : * Using `_` is discouraged.
1407 : : *
1408 : : * If 0 is used for @class_offset subclasses cannot override the class handler
1409 : : * in their class_init method by doing super_class->signal_handler = my_signal_handler.
1410 : : * Instead they will have to use g_signal_override_class_handler().
1411 : : *
1412 : : * If @c_marshaller is %NULL, g_cclosure_marshal_generic() will be used as
1413 : : * the marshaller for this signal. In some simple cases, g_signal_new()
1414 : : * will use a more optimized c_marshaller and va_marshaller for the signal
1415 : : * instead of g_cclosure_marshal_generic().
1416 : : *
1417 : : * If @c_marshaller is non-%NULL, you need to also specify a va_marshaller
1418 : : * using g_signal_set_va_marshaller() or the generic va_marshaller will
1419 : : * be used.
1420 : : *
1421 : : * Returns: the signal id
1422 : : */
1423 : : guint
1424 : 2631 : g_signal_new (const gchar *signal_name,
1425 : : GType itype,
1426 : : GSignalFlags signal_flags,
1427 : : guint class_offset,
1428 : : GSignalAccumulator accumulator,
1429 : : gpointer accu_data,
1430 : : GSignalCMarshaller c_marshaller,
1431 : : GType return_type,
1432 : : guint n_params,
1433 : : ...)
1434 : : {
1435 : : va_list args;
1436 : : guint signal_id;
1437 : :
1438 : 2631 : g_return_val_if_fail (signal_name != NULL, 0);
1439 : :
1440 : 2631 : va_start (args, n_params);
1441 : :
1442 : 5202 : signal_id = g_signal_new_valist (signal_name, itype, signal_flags,
1443 : 2571 : class_offset ? g_signal_type_cclosure_new (itype, class_offset) : NULL,
1444 : 595 : accumulator, accu_data, c_marshaller,
1445 : 595 : return_type, n_params, args);
1446 : :
1447 : 2631 : va_end (args);
1448 : :
1449 : 2631 : return signal_id;
1450 : 595 : }
1451 : :
1452 : : /**
1453 : : * g_signal_new_class_handler:
1454 : : * @signal_name: the name for the signal
1455 : : * @itype: the type this signal pertains to. It will also pertain to
1456 : : * types which are derived from this type.
1457 : : * @signal_flags: a combination of #GSignalFlags specifying detail of when
1458 : : * the default handler is to be invoked. You should at least specify
1459 : : * %G_SIGNAL_RUN_FIRST or %G_SIGNAL_RUN_LAST.
1460 : : * @class_handler: (nullable) (scope forever): a #GCallback which acts as class implementation of
1461 : : * this signal. Used to invoke a class method generically. Pass %NULL to
1462 : : * not associate a class method with this signal.
1463 : : * @accumulator: (nullable) (scope forever) (closure accu_data): the accumulator for this signal; may be %NULL.
1464 : : * @accu_data: (nullable): user data for the @accumulator.
1465 : : * @c_marshaller: (nullable): the function to translate arrays of parameter
1466 : : * values to signal emissions into C language callback invocations or %NULL.
1467 : : * @return_type: the type of return value, or %G_TYPE_NONE for a signal
1468 : : * without a return value.
1469 : : * @n_params: the number of parameter types to follow.
1470 : : * @...: a list of types, one for each parameter.
1471 : : *
1472 : : * Creates a new signal. (This is usually done in the class initializer.)
1473 : : *
1474 : : * This is a variant of g_signal_new() that takes a C callback instead
1475 : : * of a class offset for the signal's class handler. This function
1476 : : * doesn't need a function pointer exposed in the class structure of
1477 : : * an object definition, instead the function pointer is passed
1478 : : * directly and can be overridden by derived classes with
1479 : : * g_signal_override_class_closure() or
1480 : : * g_signal_override_class_handler() and chained to with
1481 : : * g_signal_chain_from_overridden() or
1482 : : * g_signal_chain_from_overridden_handler().
1483 : : *
1484 : : * See g_signal_new() for information about signal names.
1485 : : *
1486 : : * If c_marshaller is %NULL, g_cclosure_marshal_generic() will be used as
1487 : : * the marshaller for this signal.
1488 : : *
1489 : : * Returns: the signal id
1490 : : *
1491 : : * Since: 2.18
1492 : : */
1493 : : guint
1494 : 2 : g_signal_new_class_handler (const gchar *signal_name,
1495 : : GType itype,
1496 : : GSignalFlags signal_flags,
1497 : : GCallback class_handler,
1498 : : GSignalAccumulator accumulator,
1499 : : gpointer accu_data,
1500 : : GSignalCMarshaller c_marshaller,
1501 : : GType return_type,
1502 : : guint n_params,
1503 : : ...)
1504 : : {
1505 : : va_list args;
1506 : : guint signal_id;
1507 : :
1508 : 2 : g_return_val_if_fail (signal_name != NULL, 0);
1509 : :
1510 : 2 : va_start (args, n_params);
1511 : :
1512 : 4 : signal_id = g_signal_new_valist (signal_name, itype, signal_flags,
1513 : 2 : class_handler ? g_cclosure_new (class_handler, NULL, NULL) : NULL,
1514 : 1 : accumulator, accu_data, c_marshaller,
1515 : 1 : return_type, n_params, args);
1516 : :
1517 : 2 : va_end (args);
1518 : :
1519 : 2 : return signal_id;
1520 : 1 : }
1521 : :
1522 : : static inline ClassClosure*
1523 : 23912635 : signal_find_class_closure (SignalNode *node,
1524 : : GType itype)
1525 : : {
1526 : 23912635 : GBSearchArray *bsa = node->class_closure_bsa;
1527 : : ClassClosure *cc;
1528 : :
1529 : 23912635 : if (bsa)
1530 : : {
1531 : : ClassClosure key;
1532 : :
1533 : : /* cc->instance_type is 0 for default closure */
1534 : :
1535 : 23870440 : if (g_bsearch_array_get_n_nodes (bsa) == 1)
1536 : : {
1537 : 23870370 : cc = g_bsearch_array_get_nth (bsa, &g_class_closure_bconfig, 0);
1538 : 23870370 : if (cc && cc->instance_type == 0) /* check for default closure */
1539 : 23870370 : return cc;
1540 : 0 : }
1541 : :
1542 : 70 : key.instance_type = itype;
1543 : 70 : cc = g_bsearch_array_lookup (bsa, &g_class_closure_bconfig, &key);
1544 : 100 : while (!cc && key.instance_type)
1545 : : {
1546 : 30 : key.instance_type = g_type_parent (key.instance_type);
1547 : 30 : cc = g_bsearch_array_lookup (bsa, &g_class_closure_bconfig, &key);
1548 : : }
1549 : 35 : }
1550 : : else
1551 : 42195 : cc = NULL;
1552 : 42265 : return cc;
1553 : 15266875 : }
1554 : :
1555 : : static inline GClosure*
1556 : 23912502 : signal_lookup_closure (SignalNode *node,
1557 : : GTypeInstance *instance)
1558 : : {
1559 : : ClassClosure *cc;
1560 : :
1561 : 23912502 : cc = signal_find_class_closure (node, G_TYPE_FROM_INSTANCE (instance));
1562 : 23912502 : return cc ? cc->closure : NULL;
1563 : : }
1564 : :
1565 : : static void
1566 : 2529 : signal_add_class_closure (SignalNode *node,
1567 : : GType itype,
1568 : : GClosure *closure)
1569 : : {
1570 : : ClassClosure key;
1571 : :
1572 : 2529 : node->single_va_closure_is_valid = FALSE;
1573 : :
1574 : 2529 : if (!node->class_closure_bsa)
1575 : 2515 : node->class_closure_bsa = g_bsearch_array_create (&g_class_closure_bconfig);
1576 : 2529 : key.instance_type = itype;
1577 : 2529 : key.closure = g_closure_ref (closure);
1578 : 2529 : node->class_closure_bsa = g_bsearch_array_insert (node->class_closure_bsa,
1579 : : &g_class_closure_bconfig,
1580 : : &key);
1581 : 2529 : g_closure_sink (closure);
1582 : 2529 : if (node->c_marshaller && closure && G_CLOSURE_NEEDS_MARSHAL (closure))
1583 : : {
1584 : 2529 : g_closure_set_marshal (closure, node->c_marshaller);
1585 : 2529 : if (node->va_marshaller)
1586 : 1096 : _g_closure_set_va_marshal (closure, node->va_marshaller);
1587 : 544 : }
1588 : 2529 : }
1589 : :
1590 : : /**
1591 : : * g_signal_newv:
1592 : : * @signal_name: the name for the signal
1593 : : * @itype: the type this signal pertains to. It will also pertain to
1594 : : * types which are derived from this type
1595 : : * @signal_flags: a combination of #GSignalFlags specifying detail of when
1596 : : * the default handler is to be invoked. You should at least specify
1597 : : * %G_SIGNAL_RUN_FIRST or %G_SIGNAL_RUN_LAST
1598 : : * @class_closure: (nullable): The closure to invoke on signal emission;
1599 : : * may be %NULL
1600 : : * @accumulator: (nullable) (scope forever) (closure accu_data): the accumulator for this signal; may be %NULL
1601 : : * @accu_data: (nullable): user data for the @accumulator
1602 : : * @c_marshaller: (nullable): the function to translate arrays of
1603 : : * parameter values to signal emissions into C language callback
1604 : : * invocations or %NULL
1605 : : * @return_type: the type of return value, or %G_TYPE_NONE for a signal
1606 : : * without a return value
1607 : : * @n_params: the length of @param_types
1608 : : * @param_types: (array length=n_params) (nullable): an array of types, one for
1609 : : * each parameter (may be %NULL if @n_params is zero)
1610 : : *
1611 : : * Creates a new signal. (This is usually done in the class initializer.)
1612 : : *
1613 : : * See g_signal_new() for details on allowed signal names.
1614 : : *
1615 : : * If c_marshaller is %NULL, g_cclosure_marshal_generic() will be used as
1616 : : * the marshaller for this signal.
1617 : : *
1618 : : * Returns: the signal id
1619 : : */
1620 : : guint
1621 : 2635 : g_signal_newv (const gchar *signal_name,
1622 : : GType itype,
1623 : : GSignalFlags signal_flags,
1624 : : GClosure *class_closure,
1625 : : GSignalAccumulator accumulator,
1626 : : gpointer accu_data,
1627 : : GSignalCMarshaller c_marshaller,
1628 : : GType return_type,
1629 : : guint n_params,
1630 : : GType *param_types)
1631 : : {
1632 : : const gchar *name;
1633 : 2635 : gchar *signal_name_copy = NULL;
1634 : : guint signal_id, i;
1635 : : SignalNode *node;
1636 : : GSignalCMarshaller builtin_c_marshaller;
1637 : : GSignalCVaMarshaller builtin_va_marshaller;
1638 : : GSignalCVaMarshaller va_marshaller;
1639 : :
1640 : 2635 : g_return_val_if_fail (signal_name != NULL, 0);
1641 : 2635 : g_return_val_if_fail (g_signal_is_valid_name (signal_name), 0);
1642 : 2632 : g_return_val_if_fail (G_TYPE_IS_INSTANTIATABLE (itype) || G_TYPE_IS_INTERFACE (itype), 0);
1643 : 2632 : if (n_params)
1644 : 2270 : g_return_val_if_fail (param_types != NULL, 0);
1645 : 2632 : g_return_val_if_fail ((return_type & G_SIGNAL_TYPE_STATIC_SCOPE) == 0, 0);
1646 : 2632 : if (return_type == (G_TYPE_NONE & ~G_SIGNAL_TYPE_STATIC_SCOPE))
1647 : 1998 : g_return_val_if_fail (accumulator == NULL, 0);
1648 : 2632 : if (!accumulator)
1649 : 2032 : g_return_val_if_fail (accu_data == NULL, 0);
1650 : 2632 : g_return_val_if_fail ((signal_flags & G_SIGNAL_ACCUMULATOR_FIRST_RUN) == 0, 0);
1651 : :
1652 : 2632 : if (!is_canonical (signal_name))
1653 : : {
1654 : 3 : signal_name_copy = g_strdup (signal_name);
1655 : 3 : canonicalize_key (signal_name_copy);
1656 : 3 : name = signal_name_copy;
1657 : 2 : }
1658 : : else
1659 : : {
1660 : 2629 : name = signal_name;
1661 : : }
1662 : :
1663 : 2632 : SIGNAL_LOCK ();
1664 : :
1665 : 2632 : signal_id = signal_id_lookup (name, itype);
1666 : 2632 : node = LOOKUP_SIGNAL_NODE (signal_id);
1667 : 2632 : if (node && !node->destroyed)
1668 : : {
1669 : 0 : g_critical (G_STRLOC ": signal \"%s\" already exists in the '%s' %s",
1670 : 0 : name,
1671 : 0 : type_debug_name (node->itype),
1672 : 0 : G_TYPE_IS_INTERFACE (node->itype) ? "interface" : "class ancestry");
1673 : 0 : g_free (signal_name_copy);
1674 : 0 : SIGNAL_UNLOCK ();
1675 : 0 : return 0;
1676 : : }
1677 : 2632 : if (node && node->itype != itype)
1678 : : {
1679 : 0 : g_critical (G_STRLOC ": signal \"%s\" for type '%s' was previously created for type '%s'",
1680 : 0 : name,
1681 : 0 : type_debug_name (itype),
1682 : 0 : type_debug_name (node->itype));
1683 : 0 : g_free (signal_name_copy);
1684 : 0 : SIGNAL_UNLOCK ();
1685 : 0 : return 0;
1686 : : }
1687 : 6962 : for (i = 0; i < n_params; i++)
1688 : 4330 : if (!G_TYPE_IS_VALUE (param_types[i] & ~G_SIGNAL_TYPE_STATIC_SCOPE))
1689 : : {
1690 : 0 : g_critical (G_STRLOC ": parameter %d of type '%s' for signal \"%s::%s\" is not a value type",
1691 : 0 : i + 1, type_debug_name (param_types[i]), type_debug_name (itype), name);
1692 : 0 : g_free (signal_name_copy);
1693 : 0 : SIGNAL_UNLOCK ();
1694 : 0 : return 0;
1695 : : }
1696 : 2632 : if (return_type != G_TYPE_NONE && !G_TYPE_IS_VALUE (return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE))
1697 : : {
1698 : 0 : g_critical (G_STRLOC ": return value of type '%s' for signal \"%s::%s\" is not a value type",
1699 : 0 : type_debug_name (return_type), type_debug_name (itype), name);
1700 : 0 : g_free (signal_name_copy);
1701 : 0 : SIGNAL_UNLOCK ();
1702 : 0 : return 0;
1703 : : }
1704 : :
1705 : : /* setup permanent portion of signal node */
1706 : 2632 : if (!node)
1707 : : {
1708 : : SignalKey key;
1709 : :
1710 : 2632 : signal_id = g_n_signal_nodes++;
1711 : 2632 : node = g_new (SignalNode, 1);
1712 : 2632 : node->signal_id = signal_id;
1713 : 2632 : g_signal_nodes = g_renew (SignalNode*, g_signal_nodes, g_n_signal_nodes);
1714 : 2632 : g_signal_nodes[signal_id] = node;
1715 : 2632 : node->itype = itype;
1716 : 2632 : key.itype = itype;
1717 : 2632 : key.signal_id = signal_id;
1718 : 2632 : node->name = g_intern_string (name);
1719 : 2632 : key.quark = g_quark_from_string (name);
1720 : 2632 : g_signal_key_bsa = g_bsearch_array_insert (g_signal_key_bsa, &g_signal_key_bconfig, &key);
1721 : :
1722 : 2038 : TRACE (GOBJECT_SIGNAL_NEW (signal_id, name, (uintmax_t) itype));
1723 : 594 : }
1724 : 2632 : node->destroyed = FALSE;
1725 : :
1726 : : /* setup reinitializable portion */
1727 : 2632 : node->single_va_closure_is_valid = FALSE;
1728 : 2632 : node->flags = signal_flags & G_SIGNAL_FLAGS_MASK;
1729 : 2632 : node->n_params = n_params;
1730 : 2632 : node->param_types = g_memdup2 (param_types, sizeof (GType) * n_params);
1731 : 2632 : node->return_type = return_type;
1732 : 2632 : node->class_closure_bsa = NULL;
1733 : 2632 : if (accumulator)
1734 : : {
1735 : 600 : node->accumulator = g_new (SignalAccumulator, 1);
1736 : 600 : node->accumulator->func = accumulator;
1737 : 600 : node->accumulator->data = accu_data;
1738 : 90 : }
1739 : : else
1740 : 2032 : node->accumulator = NULL;
1741 : :
1742 : 2632 : builtin_c_marshaller = NULL;
1743 : 2632 : builtin_va_marshaller = NULL;
1744 : :
1745 : : /* Pick up built-in va marshallers for standard types, and
1746 : : instead of generic marshaller if no marshaller specified */
1747 : 2632 : if (n_params == 0 && return_type == G_TYPE_NONE)
1748 : : {
1749 : 306 : builtin_c_marshaller = g_cclosure_marshal_VOID__VOID;
1750 : 306 : builtin_va_marshaller = g_cclosure_marshal_VOID__VOIDv;
1751 : 70 : }
1752 : 2326 : else if (n_params == 1 && return_type == G_TYPE_NONE)
1753 : : {
1754 : : #define ADD_CHECK(__type__) \
1755 : : else if (g_type_is_a (param_types[0] & ~G_SIGNAL_TYPE_STATIC_SCOPE, G_TYPE_ ##__type__)) \
1756 : : { \
1757 : : builtin_c_marshaller = g_cclosure_marshal_VOID__ ## __type__; \
1758 : : builtin_va_marshaller = g_cclosure_marshal_VOID__ ## __type__ ##v; \
1759 : : }
1760 : :
1761 : : if (0) {}
1762 : 875 : ADD_CHECK (BOOLEAN)
1763 : 829 : ADD_CHECK (CHAR)
1764 : 829 : ADD_CHECK (UCHAR)
1765 : 829 : ADD_CHECK (INT)
1766 : 809 : ADD_CHECK (UINT)
1767 : 809 : ADD_CHECK (LONG)
1768 : 809 : ADD_CHECK (ULONG)
1769 : 809 : ADD_CHECK (ENUM)
1770 : 797 : ADD_CHECK (FLAGS)
1771 : 797 : ADD_CHECK (FLOAT)
1772 : 797 : ADD_CHECK (DOUBLE)
1773 : 795 : ADD_CHECK (STRING)
1774 : 738 : ADD_CHECK (PARAM)
1775 : 128 : ADD_CHECK (BOXED)
1776 : 128 : ADD_CHECK (POINTER)
1777 : 125 : ADD_CHECK (OBJECT)
1778 : 24 : ADD_CHECK (VARIANT)
1779 : 325 : }
1780 : :
1781 : 2632 : if (c_marshaller == NULL)
1782 : : {
1783 : 1181 : if (builtin_c_marshaller)
1784 : : {
1785 : 1126 : c_marshaller = builtin_c_marshaller;
1786 : 1126 : va_marshaller = builtin_va_marshaller;
1787 : 370 : }
1788 : : else
1789 : : {
1790 : 55 : c_marshaller = g_cclosure_marshal_generic;
1791 : 55 : va_marshaller = g_cclosure_marshal_generic_va;
1792 : : }
1793 : 403 : }
1794 : : else
1795 : 1451 : va_marshaller = NULL;
1796 : :
1797 : 2632 : node->c_marshaller = c_marshaller;
1798 : 2632 : node->va_marshaller = va_marshaller;
1799 : 2632 : node->emission_hooks = NULL;
1800 : 2632 : if (class_closure)
1801 : 2515 : signal_add_class_closure (node, 0, class_closure);
1802 : :
1803 : 2632 : SIGNAL_UNLOCK ();
1804 : :
1805 : 2632 : g_free (signal_name_copy);
1806 : :
1807 : 2632 : return signal_id;
1808 : 597 : }
1809 : :
1810 : : /**
1811 : : * g_signal_set_va_marshaller:
1812 : : * @signal_id: the signal id
1813 : : * @instance_type: the instance type on which to set the marshaller.
1814 : : * @va_marshaller: the marshaller to set.
1815 : : *
1816 : : * Change the #GSignalCVaMarshaller used for a given signal. This is a
1817 : : * specialised form of the marshaller that can often be used for the
1818 : : * common case of a single connected signal handler and avoids the
1819 : : * overhead of #GValue. Its use is optional.
1820 : : *
1821 : : * Since: 2.32
1822 : : */
1823 : : void
1824 : 1208 : g_signal_set_va_marshaller (guint signal_id,
1825 : : GType instance_type,
1826 : : GSignalCVaMarshaller va_marshaller)
1827 : : {
1828 : : SignalNode *node;
1829 : :
1830 : 1208 : g_return_if_fail (signal_id > 0);
1831 : 1208 : g_return_if_fail (va_marshaller != NULL);
1832 : :
1833 : 1208 : SIGNAL_LOCK ();
1834 : 1208 : node = LOOKUP_SIGNAL_NODE (signal_id);
1835 : 1208 : if (node)
1836 : : {
1837 : 1208 : node->va_marshaller = va_marshaller;
1838 : 1208 : if (node->class_closure_bsa)
1839 : : {
1840 : 1192 : ClassClosure *cc = g_bsearch_array_get_nth (node->class_closure_bsa, &g_class_closure_bconfig, 0);
1841 : 1192 : if (cc->closure->marshal == node->c_marshaller)
1842 : 1192 : _g_closure_set_va_marshal (cc->closure, va_marshaller);
1843 : 123 : }
1844 : :
1845 : 1208 : node->single_va_closure_is_valid = FALSE;
1846 : 131 : }
1847 : :
1848 : 1208 : SIGNAL_UNLOCK ();
1849 : 131 : }
1850 : :
1851 : :
1852 : : /**
1853 : : * g_signal_new_valist:
1854 : : * @signal_name: the name for the signal
1855 : : * @itype: the type this signal pertains to. It will also pertain to
1856 : : * types which are derived from this type.
1857 : : * @signal_flags: a combination of #GSignalFlags specifying detail of when
1858 : : * the default handler is to be invoked. You should at least specify
1859 : : * %G_SIGNAL_RUN_FIRST or %G_SIGNAL_RUN_LAST.
1860 : : * @class_closure: (nullable): The closure to invoke on signal emission; may be %NULL.
1861 : : * @accumulator: (nullable) (scope forever) (closure accu_data): the accumulator for this signal; may be %NULL.
1862 : : * @accu_data: (nullable): user data for the @accumulator.
1863 : : * @c_marshaller: (nullable): the function to translate arrays of parameter
1864 : : * values to signal emissions into C language callback invocations or %NULL.
1865 : : * @return_type: the type of return value, or %G_TYPE_NONE for a signal
1866 : : * without a return value.
1867 : : * @n_params: the number of parameter types in @args.
1868 : : * @args: va_list of #GType, one for each parameter.
1869 : : *
1870 : : * Creates a new signal. (This is usually done in the class initializer.)
1871 : : *
1872 : : * See g_signal_new() for details on allowed signal names.
1873 : : *
1874 : : * If c_marshaller is %NULL, g_cclosure_marshal_generic() will be used as
1875 : : * the marshaller for this signal.
1876 : : *
1877 : : * Returns: the signal id
1878 : : */
1879 : : guint
1880 : 2633 : g_signal_new_valist (const gchar *signal_name,
1881 : : GType itype,
1882 : : GSignalFlags signal_flags,
1883 : : GClosure *class_closure,
1884 : : GSignalAccumulator accumulator,
1885 : : gpointer accu_data,
1886 : : GSignalCMarshaller c_marshaller,
1887 : : GType return_type,
1888 : : guint n_params,
1889 : : va_list args)
1890 : : {
1891 : : /* Somewhat arbitrarily reserve 200 bytes. That should cover the majority
1892 : : * of cases where n_params is small and still be small enough for what we
1893 : : * want to put on the stack. */
1894 : : GType param_types_stack[200 / sizeof (GType)];
1895 : 2633 : GType *param_types_heap = NULL;
1896 : : GType *param_types;
1897 : : guint i;
1898 : : guint signal_id;
1899 : :
1900 : 2633 : param_types = param_types_stack;
1901 : 2633 : if (n_params > 0)
1902 : : {
1903 : 2270 : if (G_UNLIKELY (n_params > G_N_ELEMENTS (param_types_stack)))
1904 : : {
1905 : 0 : param_types_heap = g_new (GType, n_params);
1906 : 0 : param_types = param_types_heap;
1907 : 0 : }
1908 : :
1909 : 6600 : for (i = 0; i < n_params; i++)
1910 : 4330 : param_types[i] = va_arg (args, GType);
1911 : 495 : }
1912 : :
1913 : 3229 : signal_id = g_signal_newv (signal_name, itype, signal_flags,
1914 : 596 : class_closure, accumulator, accu_data, c_marshaller,
1915 : 596 : return_type, n_params, param_types);
1916 : 2633 : g_free (param_types_heap);
1917 : :
1918 : 2633 : return signal_id;
1919 : : }
1920 : :
1921 : : static void
1922 : 0 : signal_destroy_R (SignalNode *signal_node)
1923 : : {
1924 : 0 : SignalNode node = *signal_node;
1925 : :
1926 : 0 : signal_node->destroyed = TRUE;
1927 : :
1928 : : /* reentrancy caution, zero out real contents first */
1929 : 0 : signal_node->single_va_closure_is_valid = FALSE;
1930 : 0 : signal_node->n_params = 0;
1931 : 0 : signal_node->param_types = NULL;
1932 : 0 : signal_node->return_type = 0;
1933 : 0 : signal_node->class_closure_bsa = NULL;
1934 : 0 : signal_node->accumulator = NULL;
1935 : 0 : signal_node->c_marshaller = NULL;
1936 : 0 : signal_node->va_marshaller = NULL;
1937 : 0 : signal_node->emission_hooks = NULL;
1938 : :
1939 : : #ifdef G_ENABLE_DEBUG
1940 : : /* check current emissions */
1941 : : {
1942 : : Emission *emission;
1943 : :
1944 : 0 : for (emission = g_emissions; emission; emission = emission->next)
1945 : 0 : if (emission->ihint.signal_id == node.signal_id)
1946 : 0 : g_critical (G_STRLOC ": signal \"%s\" being destroyed is currently in emission (instance '%p')",
1947 : 0 : node.name, emission->instance);
1948 : : }
1949 : : #endif
1950 : :
1951 : : /* free contents that need to
1952 : : */
1953 : 0 : SIGNAL_UNLOCK ();
1954 : 0 : g_free (node.param_types);
1955 : 0 : if (node.class_closure_bsa)
1956 : : {
1957 : : guint i;
1958 : :
1959 : 0 : for (i = 0; i < node.class_closure_bsa->n_nodes; i++)
1960 : : {
1961 : 0 : ClassClosure *cc = g_bsearch_array_get_nth (node.class_closure_bsa, &g_class_closure_bconfig, i);
1962 : :
1963 : 0 : g_closure_unref (cc->closure);
1964 : 0 : }
1965 : 0 : g_bsearch_array_free (node.class_closure_bsa, &g_class_closure_bconfig);
1966 : 0 : }
1967 : 0 : g_free (node.accumulator);
1968 : 0 : if (node.emission_hooks)
1969 : : {
1970 : 0 : g_hook_list_clear (node.emission_hooks);
1971 : 0 : g_free (node.emission_hooks);
1972 : 0 : }
1973 : 0 : SIGNAL_LOCK ();
1974 : 0 : }
1975 : :
1976 : : /**
1977 : : * g_signal_override_class_closure:
1978 : : * @signal_id: the signal id
1979 : : * @instance_type: the instance type on which to override the class closure
1980 : : * for the signal.
1981 : : * @class_closure: the closure.
1982 : : *
1983 : : * Overrides the class closure (i.e. the default handler) for the given signal
1984 : : * for emissions on instances of @instance_type. @instance_type must be derived
1985 : : * from the type to which the signal belongs.
1986 : : *
1987 : : * See g_signal_chain_from_overridden() and
1988 : : * g_signal_chain_from_overridden_handler() for how to chain up to the
1989 : : * parent class closure from inside the overridden one.
1990 : : */
1991 : : void
1992 : 14 : g_signal_override_class_closure (guint signal_id,
1993 : : GType instance_type,
1994 : : GClosure *class_closure)
1995 : : {
1996 : : SignalNode *node;
1997 : :
1998 : 14 : g_return_if_fail (signal_id > 0);
1999 : 14 : g_return_if_fail (class_closure != NULL);
2000 : :
2001 : 14 : SIGNAL_LOCK ();
2002 : 14 : node = LOOKUP_SIGNAL_NODE (signal_id);
2003 : 14 : node_check_deprecated (node);
2004 : 14 : if (!g_type_is_a (instance_type, node->itype))
2005 : 0 : g_critical ("%s: type '%s' cannot be overridden for signal id '%u'", G_STRLOC, type_debug_name (instance_type), signal_id);
2006 : : else
2007 : : {
2008 : 14 : ClassClosure *cc = signal_find_class_closure (node, instance_type);
2009 : :
2010 : 14 : if (cc && cc->instance_type == instance_type)
2011 : 0 : g_critical ("%s: type '%s' is already overridden for signal id '%u'", G_STRLOC, type_debug_name (instance_type), signal_id);
2012 : : else
2013 : 14 : signal_add_class_closure (node, instance_type, class_closure);
2014 : : }
2015 : 14 : SIGNAL_UNLOCK ();
2016 : 7 : }
2017 : :
2018 : : /**
2019 : : * g_signal_override_class_handler:
2020 : : * @signal_name: the name for the signal
2021 : : * @instance_type: the instance type on which to override the class handler
2022 : : * for the signal.
2023 : : * @class_handler: (scope forever): the handler.
2024 : : *
2025 : : * Overrides the class closure (i.e. the default handler) for the
2026 : : * given signal for emissions on instances of @instance_type with
2027 : : * callback @class_handler. @instance_type must be derived from the
2028 : : * type to which the signal belongs.
2029 : : *
2030 : : * See g_signal_chain_from_overridden() and
2031 : : * g_signal_chain_from_overridden_handler() for how to chain up to the
2032 : : * parent class closure from inside the overridden one.
2033 : : *
2034 : : * Since: 2.18
2035 : : */
2036 : : void
2037 : 4 : g_signal_override_class_handler (const gchar *signal_name,
2038 : : GType instance_type,
2039 : : GCallback class_handler)
2040 : : {
2041 : : guint signal_id;
2042 : :
2043 : 4 : g_return_if_fail (signal_name != NULL);
2044 : 4 : g_return_if_fail (instance_type != G_TYPE_NONE);
2045 : 4 : g_return_if_fail (class_handler != NULL);
2046 : :
2047 : 4 : signal_id = g_signal_lookup (signal_name, instance_type);
2048 : :
2049 : 4 : if (signal_id)
2050 : 6 : g_signal_override_class_closure (signal_id, instance_type,
2051 : 2 : g_cclosure_new (class_handler, NULL, NULL));
2052 : : else
2053 : 0 : g_critical ("%s: signal name '%s' is invalid for type id '%"G_GUINTPTR_FORMAT"'",
2054 : 0 : G_STRLOC, signal_name, (guintptr) instance_type);
2055 : :
2056 : 2 : }
2057 : :
2058 : : /**
2059 : : * g_signal_chain_from_overridden:
2060 : : * @instance_and_params: (array): the argument list of the signal emission.
2061 : : * The first element in the array is a #GValue for the instance the signal
2062 : : * is being emitted on. The rest are any arguments to be passed to the signal.
2063 : : * @return_value: Location for the return value.
2064 : : *
2065 : : * Calls the original class closure of a signal. This function should only
2066 : : * be called from an overridden class closure; see
2067 : : * g_signal_override_class_closure() and
2068 : : * g_signal_override_class_handler().
2069 : : */
2070 : : void
2071 : 18 : g_signal_chain_from_overridden (const GValue *instance_and_params,
2072 : : GValue *return_value)
2073 : : {
2074 : 18 : GType chain_type = 0, restore_type = 0;
2075 : 18 : Emission *emission = NULL;
2076 : 18 : GClosure *closure = NULL;
2077 : 18 : guint n_params = 0;
2078 : : gpointer instance;
2079 : :
2080 : 18 : g_return_if_fail (instance_and_params != NULL);
2081 : 18 : instance = g_value_peek_pointer (instance_and_params);
2082 : 18 : g_return_if_fail (G_TYPE_CHECK_INSTANCE (instance));
2083 : :
2084 : 18 : SIGNAL_LOCK ();
2085 : 18 : emission = emission_find_innermost (instance);
2086 : 18 : if (emission)
2087 : : {
2088 : 18 : SignalNode *node = LOOKUP_SIGNAL_NODE (emission->ihint.signal_id);
2089 : :
2090 : 18 : g_assert (node != NULL); /* paranoid */
2091 : :
2092 : : /* we should probably do the same parameter checks as g_signal_emit() here.
2093 : : */
2094 : 18 : if (emission->chain_type != G_TYPE_NONE)
2095 : : {
2096 : 18 : ClassClosure *cc = signal_find_class_closure (node, emission->chain_type);
2097 : :
2098 : 18 : g_assert (cc != NULL); /* closure currently in call stack */
2099 : :
2100 : 18 : n_params = node->n_params;
2101 : 18 : restore_type = cc->instance_type;
2102 : 18 : cc = signal_find_class_closure (node, g_type_parent (cc->instance_type));
2103 : 18 : if (cc && cc->instance_type != restore_type)
2104 : : {
2105 : 18 : closure = cc->closure;
2106 : 18 : chain_type = cc->instance_type;
2107 : 9 : }
2108 : 9 : }
2109 : : else
2110 : 0 : g_critical ("%s: signal id '%u' cannot be chained from current emission stage for instance '%p'", G_STRLOC, node->signal_id, instance);
2111 : 9 : }
2112 : : else
2113 : 0 : g_critical ("%s: no signal is currently being emitted for instance '%p'", G_STRLOC, instance);
2114 : :
2115 : 18 : if (closure)
2116 : : {
2117 : 18 : emission->chain_type = chain_type;
2118 : 18 : SIGNAL_UNLOCK ();
2119 : 27 : g_closure_invoke (closure,
2120 : 9 : return_value,
2121 : 9 : n_params + 1,
2122 : 9 : instance_and_params,
2123 : 18 : &emission->ihint);
2124 : 18 : SIGNAL_LOCK ();
2125 : 18 : emission->chain_type = restore_type;
2126 : 9 : }
2127 : 18 : SIGNAL_UNLOCK ();
2128 : 9 : }
2129 : :
2130 : : /**
2131 : : * g_signal_chain_from_overridden_handler: (skip)
2132 : : * @instance: (type GObject.TypeInstance): the instance the signal is being
2133 : : * emitted on.
2134 : : * @...: parameters to be passed to the parent class closure, followed by a
2135 : : * location for the return value. If the return type of the signal
2136 : : * is %G_TYPE_NONE, the return value location can be omitted.
2137 : : *
2138 : : * Calls the original class closure of a signal. This function should
2139 : : * only be called from an overridden class closure; see
2140 : : * g_signal_override_class_closure() and
2141 : : * g_signal_override_class_handler().
2142 : : *
2143 : : * Since: 2.18
2144 : : */
2145 : : void
2146 : 6 : g_signal_chain_from_overridden_handler (gpointer instance,
2147 : : ...)
2148 : : {
2149 : 6 : GType chain_type = 0, restore_type = 0;
2150 : 6 : Emission *emission = NULL;
2151 : 6 : GClosure *closure = NULL;
2152 : 6 : SignalNode *node = NULL;
2153 : 6 : guint n_params = 0;
2154 : :
2155 : 6 : g_return_if_fail (G_TYPE_CHECK_INSTANCE (instance));
2156 : :
2157 : 6 : SIGNAL_LOCK ();
2158 : 6 : emission = emission_find_innermost (instance);
2159 : 6 : if (emission)
2160 : : {
2161 : 6 : node = LOOKUP_SIGNAL_NODE (emission->ihint.signal_id);
2162 : :
2163 : 6 : g_assert (node != NULL); /* paranoid */
2164 : :
2165 : : /* we should probably do the same parameter checks as g_signal_emit() here.
2166 : : */
2167 : 6 : if (emission->chain_type != G_TYPE_NONE)
2168 : : {
2169 : 6 : ClassClosure *cc = signal_find_class_closure (node, emission->chain_type);
2170 : :
2171 : 6 : g_assert (cc != NULL); /* closure currently in call stack */
2172 : :
2173 : 6 : n_params = node->n_params;
2174 : 6 : restore_type = cc->instance_type;
2175 : 6 : cc = signal_find_class_closure (node, g_type_parent (cc->instance_type));
2176 : 6 : if (cc && cc->instance_type != restore_type)
2177 : : {
2178 : 6 : closure = cc->closure;
2179 : 6 : chain_type = cc->instance_type;
2180 : 3 : }
2181 : 3 : }
2182 : : else
2183 : 0 : g_critical ("%s: signal id '%u' cannot be chained from current emission stage for instance '%p'", G_STRLOC, node->signal_id, instance);
2184 : 3 : }
2185 : : else
2186 : 0 : g_critical ("%s: no signal is currently being emitted for instance '%p'", G_STRLOC, instance);
2187 : :
2188 : 6 : if (closure)
2189 : : {
2190 : : GValue *instance_and_params;
2191 : : GType signal_return_type;
2192 : : GValue *param_values;
2193 : : va_list var_args;
2194 : : guint i;
2195 : :
2196 : 6 : va_start (var_args, instance);
2197 : :
2198 : 6 : signal_return_type = node->return_type;
2199 : 6 : instance_and_params = g_newa0 (GValue, n_params + 1);
2200 : 6 : param_values = instance_and_params + 1;
2201 : :
2202 : 18 : for (i = 0; i < node->n_params; i++)
2203 : : {
2204 : : gchar *error;
2205 : 12 : GType ptype = node->param_types[i] & ~G_SIGNAL_TYPE_STATIC_SCOPE;
2206 : 12 : gboolean static_scope = node->param_types[i] & G_SIGNAL_TYPE_STATIC_SCOPE;
2207 : :
2208 : 12 : SIGNAL_UNLOCK ();
2209 : 24 : G_VALUE_COLLECT_INIT (param_values + i, ptype,
2210 : : var_args,
2211 : 6 : static_scope ? G_VALUE_NOCOPY_CONTENTS : 0,
2212 : : &error);
2213 : 12 : if (error)
2214 : : {
2215 : 0 : g_critical ("%s: %s", G_STRLOC, error);
2216 : 0 : g_free (error);
2217 : :
2218 : : /* we purposely leak the value here, it might not be
2219 : : * in a correct state if an error condition occurred
2220 : : */
2221 : 0 : while (i--)
2222 : 0 : g_value_unset (param_values + i);
2223 : :
2224 : 0 : va_end (var_args);
2225 : 0 : return;
2226 : : }
2227 : 12 : SIGNAL_LOCK ();
2228 : 6 : }
2229 : :
2230 : 6 : SIGNAL_UNLOCK ();
2231 : 6 : g_value_init_from_instance (instance_and_params, instance);
2232 : 6 : SIGNAL_LOCK ();
2233 : :
2234 : 6 : emission->chain_type = chain_type;
2235 : 6 : SIGNAL_UNLOCK ();
2236 : :
2237 : 6 : if (signal_return_type == G_TYPE_NONE)
2238 : : {
2239 : 0 : g_closure_invoke (closure,
2240 : : NULL,
2241 : 0 : n_params + 1,
2242 : 0 : instance_and_params,
2243 : 0 : &emission->ihint);
2244 : 0 : }
2245 : : else
2246 : : {
2247 : 6 : GValue return_value = G_VALUE_INIT;
2248 : 6 : gchar *error = NULL;
2249 : 6 : GType rtype = signal_return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE;
2250 : 6 : gboolean static_scope = signal_return_type & G_SIGNAL_TYPE_STATIC_SCOPE;
2251 : :
2252 : 6 : g_value_init (&return_value, rtype);
2253 : :
2254 : 9 : g_closure_invoke (closure,
2255 : : &return_value,
2256 : 3 : n_params + 1,
2257 : 3 : instance_and_params,
2258 : 6 : &emission->ihint);
2259 : :
2260 : 12 : G_VALUE_LCOPY (&return_value,
2261 : : var_args,
2262 : 3 : static_scope ? G_VALUE_NOCOPY_CONTENTS : 0,
2263 : : &error);
2264 : 6 : if (!error)
2265 : : {
2266 : 6 : g_value_unset (&return_value);
2267 : 3 : }
2268 : : else
2269 : : {
2270 : 0 : g_critical ("%s: %s", G_STRLOC, error);
2271 : 0 : g_free (error);
2272 : :
2273 : : /* we purposely leak the value here, it might not be
2274 : : * in a correct state if an error condition occurred
2275 : : */
2276 : : }
2277 : : }
2278 : :
2279 : 18 : for (i = 0; i < n_params; i++)
2280 : 12 : g_value_unset (param_values + i);
2281 : 6 : g_value_unset (instance_and_params);
2282 : :
2283 : 6 : va_end (var_args);
2284 : :
2285 : 6 : SIGNAL_LOCK ();
2286 : 6 : emission->chain_type = restore_type;
2287 : 3 : }
2288 : 6 : SIGNAL_UNLOCK ();
2289 : 3 : }
2290 : :
2291 : : /**
2292 : : * g_signal_get_invocation_hint:
2293 : : * @instance: (type GObject.Object): the instance to query
2294 : : *
2295 : : * Returns the invocation hint of the innermost signal emission of instance.
2296 : : *
2297 : : * Returns: (transfer none) (nullable): the invocation hint of the innermost
2298 : : * signal emission, or %NULL if not found.
2299 : : */
2300 : : GSignalInvocationHint*
2301 : 24 : g_signal_get_invocation_hint (gpointer instance)
2302 : : {
2303 : 24 : Emission *emission = NULL;
2304 : :
2305 : 24 : g_return_val_if_fail (G_TYPE_CHECK_INSTANCE (instance), NULL);
2306 : :
2307 : 24 : SIGNAL_LOCK ();
2308 : 24 : emission = emission_find_innermost (instance);
2309 : 24 : SIGNAL_UNLOCK ();
2310 : :
2311 : 24 : return emission ? &emission->ihint : NULL;
2312 : 12 : }
2313 : :
2314 : : /**
2315 : : * g_signal_connect_closure_by_id:
2316 : : * @instance: (type GObject.Object): the instance to connect to.
2317 : : * @signal_id: the id of the signal.
2318 : : * @detail: the detail.
2319 : : * @closure: (not nullable): the closure to connect.
2320 : : * @after: whether the handler should be called before or after the
2321 : : * default handler of the signal.
2322 : : *
2323 : : * Connects a closure to a signal for a particular object.
2324 : : *
2325 : : * If @closure is a floating reference (see g_closure_sink()), this function
2326 : : * takes ownership of @closure.
2327 : : *
2328 : : * This function cannot fail. If the given signal name doesn’t exist,
2329 : : * a critical warning is emitted. No validation is performed on the
2330 : : * ‘detail’ string when specified in @detailed_signal, other than a
2331 : : * non-empty check.
2332 : : *
2333 : : * Refer to the [signals documentation](signals.html) for more
2334 : : * details.
2335 : : *
2336 : : * Returns: the handler ID (always greater than 0)
2337 : : */
2338 : : gulong
2339 : 10617 : g_signal_connect_closure_by_id (gpointer instance,
2340 : : guint signal_id,
2341 : : GQuark detail,
2342 : : GClosure *closure,
2343 : : gboolean after)
2344 : : {
2345 : : SignalNode *node;
2346 : 10617 : gulong handler_seq_no = 0;
2347 : :
2348 : 10617 : g_return_val_if_fail (G_TYPE_CHECK_INSTANCE (instance), 0);
2349 : 10617 : g_return_val_if_fail (signal_id > 0, 0);
2350 : 10617 : g_return_val_if_fail (closure != NULL, 0);
2351 : :
2352 : 10617 : SIGNAL_LOCK ();
2353 : 10617 : node = LOOKUP_SIGNAL_NODE (signal_id);
2354 : 10617 : if (node)
2355 : : {
2356 : 10617 : if (detail && !(node->flags & G_SIGNAL_DETAILED))
2357 : 0 : g_critical ("%s: signal id '%u' does not support detail (%u)", G_STRLOC, signal_id, detail);
2358 : 10617 : else if (!g_type_is_a (G_TYPE_FROM_INSTANCE (instance), node->itype))
2359 : 0 : g_critical ("%s: signal id '%u' is invalid for instance '%p'", G_STRLOC, signal_id, instance);
2360 : : else
2361 : : {
2362 : 10617 : Handler *handler = handler_new (signal_id, instance, after);
2363 : :
2364 : 10617 : if (G_TYPE_IS_OBJECT (node->itype))
2365 : 10617 : _g_object_set_has_signal_handler ((GObject *) instance, signal_id);
2366 : :
2367 : 10617 : handler_seq_no = handler->sequential_number;
2368 : 10617 : handler->detail = detail;
2369 : 10617 : handler->closure = g_closure_ref (closure);
2370 : 10617 : g_closure_sink (closure);
2371 : 10617 : add_invalid_closure_notify (handler, instance);
2372 : 10617 : handler_insert (signal_id, instance, handler);
2373 : 10617 : if (node->c_marshaller && G_CLOSURE_NEEDS_MARSHAL (closure))
2374 : : {
2375 : 10585 : g_closure_set_marshal (closure, node->c_marshaller);
2376 : 10585 : if (node->va_marshaller)
2377 : 10585 : _g_closure_set_va_marshal (closure, node->va_marshaller);
2378 : 345 : }
2379 : : }
2380 : 361 : }
2381 : : else
2382 : 0 : g_critical ("%s: signal id '%u' is invalid for instance '%p'", G_STRLOC, signal_id, instance);
2383 : 10617 : SIGNAL_UNLOCK ();
2384 : :
2385 : 10617 : return handler_seq_no;
2386 : 361 : }
2387 : :
2388 : : /**
2389 : : * g_signal_connect_closure:
2390 : : * @instance: (type GObject.Object): the instance to connect to.
2391 : : * @detailed_signal: a string of the form "signal-name::detail".
2392 : : * @closure: (not nullable): the closure to connect.
2393 : : * @after: whether the handler should be called before or after the
2394 : : * default handler of the signal.
2395 : : *
2396 : : * Connects a closure to a signal for a particular object.
2397 : : *
2398 : : * If @closure is a floating reference (see g_closure_sink()), this function
2399 : : * takes ownership of @closure.
2400 : : *
2401 : : * This function cannot fail. If the given signal name doesn’t exist,
2402 : : * a critical warning is emitted. No validation is performed on the
2403 : : * ‘detail’ string when specified in @detailed_signal, other than a
2404 : : * non-empty check.
2405 : : *
2406 : : * Refer to the [signals documentation](signals.html) for more
2407 : : * details.
2408 : : *
2409 : : * Returns: the handler ID (always greater than 0)
2410 : : */
2411 : : gulong
2412 : 142 : g_signal_connect_closure (gpointer instance,
2413 : : const gchar *detailed_signal,
2414 : : GClosure *closure,
2415 : : gboolean after)
2416 : : {
2417 : : guint signal_id;
2418 : 142 : gulong handler_seq_no = 0;
2419 : 142 : GQuark detail = 0;
2420 : : GType itype;
2421 : :
2422 : 142 : g_return_val_if_fail (G_TYPE_CHECK_INSTANCE (instance), 0);
2423 : 142 : g_return_val_if_fail (detailed_signal != NULL, 0);
2424 : 142 : g_return_val_if_fail (closure != NULL, 0);
2425 : :
2426 : 142 : SIGNAL_LOCK ();
2427 : 142 : itype = G_TYPE_FROM_INSTANCE (instance);
2428 : 142 : signal_id = signal_parse_name (detailed_signal, itype, &detail, TRUE);
2429 : 142 : if (signal_id)
2430 : : {
2431 : 142 : SignalNode *node = LOOKUP_SIGNAL_NODE (signal_id);
2432 : :
2433 : 142 : if (detail && !(node->flags & G_SIGNAL_DETAILED))
2434 : 0 : g_critical ("%s: signal '%s' does not support details", G_STRLOC, detailed_signal);
2435 : 142 : else if (!g_type_is_a (itype, node->itype))
2436 : 0 : g_critical ("%s: signal '%s' is invalid for instance '%p' of type '%s'",
2437 : 0 : G_STRLOC, detailed_signal, instance, g_type_name (itype));
2438 : : else
2439 : : {
2440 : 142 : Handler *handler = handler_new (signal_id, instance, after);
2441 : :
2442 : 142 : if (G_TYPE_IS_OBJECT (node->itype))
2443 : 118 : _g_object_set_has_signal_handler ((GObject *) instance, signal_id);
2444 : :
2445 : 142 : handler_seq_no = handler->sequential_number;
2446 : 142 : handler->detail = detail;
2447 : 142 : handler->closure = g_closure_ref (closure);
2448 : 142 : g_closure_sink (closure);
2449 : 142 : add_invalid_closure_notify (handler, instance);
2450 : 142 : handler_insert (signal_id, instance, handler);
2451 : 142 : if (node->c_marshaller && G_CLOSURE_NEEDS_MARSHAL (handler->closure))
2452 : : {
2453 : 140 : g_closure_set_marshal (handler->closure, node->c_marshaller);
2454 : 140 : if (node->va_marshaller)
2455 : 116 : _g_closure_set_va_marshal (handler->closure, node->va_marshaller);
2456 : 58 : }
2457 : : }
2458 : 59 : }
2459 : : else
2460 : 0 : g_critical ("%s: signal '%s' is invalid for instance '%p' of type '%s'",
2461 : 0 : G_STRLOC, detailed_signal, instance, g_type_name (itype));
2462 : 142 : SIGNAL_UNLOCK ();
2463 : :
2464 : 142 : return handler_seq_no;
2465 : 59 : }
2466 : :
2467 : : static void
2468 : 618627 : node_check_deprecated (const SignalNode *node)
2469 : : {
2470 : : static const gchar * g_enable_diagnostic = NULL;
2471 : :
2472 : 618627 : if (G_UNLIKELY (!g_enable_diagnostic))
2473 : : {
2474 : 265 : g_enable_diagnostic = g_getenv ("G_ENABLE_DIAGNOSTIC");
2475 : 265 : if (!g_enable_diagnostic)
2476 : 0 : g_enable_diagnostic = "0";
2477 : 36 : }
2478 : :
2479 : 618627 : if (g_enable_diagnostic[0] == '1')
2480 : : {
2481 : 618623 : if (node->flags & G_SIGNAL_DEPRECATED)
2482 : : {
2483 : 0 : g_warning ("The signal %s::%s is deprecated and shouldn't be used "
2484 : : "anymore. It will be removed in a future version.",
2485 : 0 : type_debug_name (node->itype), node->name);
2486 : 0 : }
2487 : 101823 : }
2488 : 618627 : }
2489 : :
2490 : : /**
2491 : : * g_signal_connect_data:
2492 : : * @instance: (type GObject.Object): the instance to connect to.
2493 : : * @detailed_signal: a string of the form "signal-name::detail".
2494 : : * @c_handler: (not nullable) (closure data): the #GCallback to connect.
2495 : : * @data: (nullable): data to pass to @c_handler calls.
2496 : : * @destroy_data: (nullable) (destroy data): a #GClosureNotify for @data.
2497 : : * @connect_flags: a combination of #GConnectFlags.
2498 : : *
2499 : : * Connects a #GCallback function to a signal for a particular object. Similar
2500 : : * to g_signal_connect(), but allows to provide a #GClosureNotify for the data
2501 : : * which will be called when the signal handler is disconnected and no longer
2502 : : * used. Specify @connect_flags if you need `..._after()` or
2503 : : * `..._swapped()` variants of this function.
2504 : : *
2505 : : * This function cannot fail. If the given signal name doesn’t exist,
2506 : : * a critical warning is emitted. No validation is performed on the
2507 : : * ‘detail’ string when specified in @detailed_signal, other than a
2508 : : * non-empty check.
2509 : : *
2510 : : * Refer to the [signals documentation](signals.html) for more
2511 : : * details.
2512 : : *
2513 : : * Returns: the handler ID (always greater than 0)
2514 : : */
2515 : : gulong
2516 : 618561 : g_signal_connect_data (gpointer instance,
2517 : : const gchar *detailed_signal,
2518 : : GCallback c_handler,
2519 : : gpointer data,
2520 : : GClosureNotify destroy_data,
2521 : : GConnectFlags connect_flags)
2522 : : {
2523 : : guint signal_id;
2524 : 618561 : gulong handler_seq_no = 0;
2525 : 618561 : GQuark detail = 0;
2526 : : GType itype;
2527 : : gboolean swapped, after;
2528 : :
2529 : 618561 : g_return_val_if_fail (G_TYPE_CHECK_INSTANCE (instance), 0);
2530 : 618561 : g_return_val_if_fail (detailed_signal != NULL, 0);
2531 : 618561 : g_return_val_if_fail (c_handler != NULL, 0);
2532 : :
2533 : 618561 : swapped = (connect_flags & G_CONNECT_SWAPPED) != FALSE;
2534 : 618561 : after = (connect_flags & G_CONNECT_AFTER) != FALSE;
2535 : :
2536 : 618561 : SIGNAL_LOCK ();
2537 : 618561 : itype = G_TYPE_FROM_INSTANCE (instance);
2538 : 618561 : signal_id = signal_parse_name (detailed_signal, itype, &detail, TRUE);
2539 : 618561 : if (signal_id)
2540 : : {
2541 : 618561 : SignalNode *node = LOOKUP_SIGNAL_NODE (signal_id);
2542 : :
2543 : 618561 : node_check_deprecated (node);
2544 : :
2545 : 618561 : if (detail && !(node->flags & G_SIGNAL_DETAILED))
2546 : 0 : g_critical ("%s: signal '%s' does not support details", G_STRLOC, detailed_signal);
2547 : 618561 : else if (!g_type_is_a (itype, node->itype))
2548 : 0 : g_critical ("%s: signal '%s' is invalid for instance '%p' of type '%s'",
2549 : 0 : G_STRLOC, detailed_signal, instance, g_type_name (itype));
2550 : : else
2551 : : {
2552 : 618561 : Handler *handler = handler_new (signal_id, instance, after);
2553 : :
2554 : 618561 : if (G_TYPE_IS_OBJECT (node->itype))
2555 : 217958 : _g_object_set_has_signal_handler ((GObject *) instance, signal_id);
2556 : :
2557 : 618561 : handler_seq_no = handler->sequential_number;
2558 : 618561 : handler->detail = detail;
2559 : 618561 : handler->closure = g_closure_ref ((swapped ? g_cclosure_new_swap : g_cclosure_new) (c_handler, data, destroy_data));
2560 : 618561 : g_closure_sink (handler->closure);
2561 : 618561 : handler_insert (signal_id, instance, handler);
2562 : 618561 : if (node->c_marshaller && G_CLOSURE_NEEDS_MARSHAL (handler->closure))
2563 : : {
2564 : 618561 : g_closure_set_marshal (handler->closure, node->c_marshaller);
2565 : 618561 : if (node->va_marshaller)
2566 : 618403 : _g_closure_set_va_marshal (handler->closure, node->va_marshaller);
2567 : 101790 : }
2568 : : }
2569 : 101790 : }
2570 : : else
2571 : 0 : g_critical ("%s: signal '%s' is invalid for instance '%p' of type '%s'",
2572 : 0 : G_STRLOC, detailed_signal, instance, g_type_name (itype));
2573 : 618561 : SIGNAL_UNLOCK ();
2574 : :
2575 : 618561 : return handler_seq_no;
2576 : 101790 : }
2577 : :
2578 : : static void
2579 : : signal_handler_block_unlocked (gpointer instance,
2580 : : gulong handler_id);
2581 : :
2582 : : /**
2583 : : * g_signal_handler_block:
2584 : : * @instance: (type GObject.Object): The instance to block the signal handler of.
2585 : : * @handler_id: Handler id of the handler to be blocked.
2586 : : *
2587 : : * Blocks a handler of an instance so it will not be called during any
2588 : : * signal emissions unless it is unblocked again. Thus "blocking" a
2589 : : * signal handler means to temporarily deactivate it, a signal handler
2590 : : * has to be unblocked exactly the same amount of times it has been
2591 : : * blocked before to become active again.
2592 : : *
2593 : : * The @handler_id has to be a valid signal handler id, connected to a
2594 : : * signal of @instance.
2595 : : */
2596 : : void
2597 : 372 : g_signal_handler_block (gpointer instance,
2598 : : gulong handler_id)
2599 : : {
2600 : 372 : g_return_if_fail (G_TYPE_CHECK_INSTANCE (instance));
2601 : 372 : g_return_if_fail (handler_id > 0);
2602 : :
2603 : 372 : SIGNAL_LOCK ();
2604 : 372 : signal_handler_block_unlocked (instance, handler_id);
2605 : 372 : SIGNAL_UNLOCK ();
2606 : 186 : }
2607 : :
2608 : : static void
2609 : 378 : signal_handler_block_unlocked (gpointer instance,
2610 : : gulong handler_id)
2611 : : {
2612 : : Handler *handler;
2613 : :
2614 : 378 : handler = handler_lookup_by_id (instance, handler_id);
2615 : 378 : if (handler)
2616 : : {
2617 : : #ifndef G_DISABLE_CHECKS
2618 : 378 : if (handler->block_count >= HANDLER_MAX_BLOCK_COUNT - 1)
2619 : 0 : g_error (G_STRLOC ": handler block_count overflow, %s", REPORT_BUG);
2620 : : #endif
2621 : 378 : handler->block_count += 1;
2622 : 189 : }
2623 : : else
2624 : 0 : g_critical ("%s: instance '%p' has no handler with id '%lu'", G_STRLOC, instance, handler_id);
2625 : 378 : }
2626 : :
2627 : : static void
2628 : : signal_handler_unblock_unlocked (gpointer instance,
2629 : : gulong handler_id);
2630 : :
2631 : : /**
2632 : : * g_signal_handler_unblock:
2633 : : * @instance: (type GObject.Object): The instance to unblock the signal handler of.
2634 : : * @handler_id: Handler id of the handler to be unblocked.
2635 : : *
2636 : : * Undoes the effect of a previous g_signal_handler_block() call. A
2637 : : * blocked handler is skipped during signal emissions and will not be
2638 : : * invoked, unblocking it (for exactly the amount of times it has been
2639 : : * blocked before) reverts its "blocked" state, so the handler will be
2640 : : * recognized by the signal system and is called upon future or
2641 : : * currently ongoing signal emissions (since the order in which
2642 : : * handlers are called during signal emissions is deterministic,
2643 : : * whether the unblocked handler in question is called as part of a
2644 : : * currently ongoing emission depends on how far that emission has
2645 : : * proceeded yet).
2646 : : *
2647 : : * The @handler_id has to be a valid id of a signal handler that is
2648 : : * connected to a signal of @instance and is currently blocked.
2649 : : */
2650 : : void
2651 : 340 : g_signal_handler_unblock (gpointer instance,
2652 : : gulong handler_id)
2653 : : {
2654 : 340 : g_return_if_fail (G_TYPE_CHECK_INSTANCE (instance));
2655 : 340 : g_return_if_fail (handler_id > 0);
2656 : :
2657 : 340 : SIGNAL_LOCK ();
2658 : 340 : signal_handler_unblock_unlocked (instance, handler_id);
2659 : 340 : SIGNAL_UNLOCK ();
2660 : 170 : }
2661 : :
2662 : : static void
2663 : 346 : signal_handler_unblock_unlocked (gpointer instance,
2664 : : gulong handler_id)
2665 : : {
2666 : : Handler *handler;
2667 : :
2668 : 346 : handler = handler_lookup_by_id (instance, handler_id);
2669 : 346 : if (handler)
2670 : : {
2671 : 346 : if (handler->block_count)
2672 : 346 : handler->block_count -= 1;
2673 : : else
2674 : 0 : g_critical (G_STRLOC ": handler '%lu' of instance '%p' is not blocked", handler_id, instance);
2675 : 173 : }
2676 : : else
2677 : 0 : g_critical ("%s: instance '%p' has no handler with id '%lu'", G_STRLOC, instance, handler_id);
2678 : 346 : }
2679 : :
2680 : : static void
2681 : : signal_handler_disconnect_unlocked (gpointer instance,
2682 : : gulong handler_id);
2683 : :
2684 : : /**
2685 : : * g_signal_handler_disconnect:
2686 : : * @instance: (type GObject.Object): The instance to remove the signal handler from.
2687 : : * @handler_id: Handler id of the handler to be disconnected.
2688 : : *
2689 : : * Disconnects a handler from an instance so it will not be called during
2690 : : * any future or currently ongoing emissions of the signal it has been
2691 : : * connected to. The @handler_id becomes invalid and may be reused.
2692 : : *
2693 : : * The @handler_id has to be a valid signal handler id, connected to a
2694 : : * signal of @instance.
2695 : : */
2696 : : void
2697 : 224147 : g_signal_handler_disconnect (gpointer instance,
2698 : : gulong handler_id)
2699 : : {
2700 : 224147 : g_return_if_fail (G_TYPE_CHECK_INSTANCE (instance));
2701 : 224147 : g_return_if_fail (handler_id > 0);
2702 : :
2703 : 224147 : SIGNAL_LOCK ();
2704 : 224147 : signal_handler_disconnect_unlocked (instance, handler_id);
2705 : 224147 : SIGNAL_UNLOCK ();
2706 : 100503 : }
2707 : :
2708 : : static void
2709 : 627625 : signal_handler_disconnect_unlocked (gpointer instance,
2710 : : gulong handler_id)
2711 : : {
2712 : : Handler *handler;
2713 : :
2714 : 627625 : handler = handler_steal_by_id (instance, handler_id);
2715 : 627625 : if (handler)
2716 : : {
2717 : 627615 : handler->sequential_number = 0;
2718 : 627615 : handler->block_count = 1;
2719 : 627615 : remove_invalid_closure_notify (handler, instance);
2720 : 627615 : handler_unref_R (handler->signal_id, instance, handler);
2721 : 101803 : }
2722 : : else
2723 : 10 : g_critical ("%s: instance '%p' has no handler with id '%lu'", G_STRLOC, instance, handler_id);
2724 : 627625 : }
2725 : :
2726 : : /**
2727 : : * g_signal_handler_is_connected:
2728 : : * @instance: (type GObject.Object): The instance where a signal handler is sought.
2729 : : * @handler_id: the handler ID.
2730 : : *
2731 : : * Returns whether @handler_id is the ID of a handler connected to @instance.
2732 : : *
2733 : : * Returns: whether @handler_id identifies a handler connected to @instance.
2734 : : */
2735 : : gboolean
2736 : 41 : g_signal_handler_is_connected (gpointer instance,
2737 : : gulong handler_id)
2738 : : {
2739 : : Handler *handler;
2740 : : gboolean connected;
2741 : :
2742 : 41 : g_return_val_if_fail (G_TYPE_CHECK_INSTANCE (instance), FALSE);
2743 : :
2744 : 41 : if (handler_id == 0)
2745 : 3 : return FALSE;
2746 : :
2747 : 38 : SIGNAL_LOCK ();
2748 : 38 : handler = handler_lookup_by_id (instance, handler_id);
2749 : 38 : connected = handler != NULL;
2750 : 38 : SIGNAL_UNLOCK ();
2751 : :
2752 : 38 : return connected;
2753 : 6 : }
2754 : :
2755 : : /**
2756 : : * g_signal_handlers_destroy:
2757 : : * @instance: (type GObject.Object): The instance whose signal handlers are destroyed
2758 : : *
2759 : : * Destroy all signal handlers of a type instance. This function is
2760 : : * an implementation detail of the #GObject dispose implementation,
2761 : : * and should not be used outside of the type system.
2762 : : */
2763 : : void
2764 : 28811342 : g_signal_handlers_destroy (gpointer instance)
2765 : : {
2766 : : GBSearchArray *hlbsa;
2767 : :
2768 : 28811342 : g_return_if_fail (G_TYPE_CHECK_INSTANCE (instance));
2769 : :
2770 : 28811342 : SIGNAL_LOCK ();
2771 : 28811342 : hlbsa = g_hash_table_lookup (g_handler_list_bsa_ht, instance);
2772 : 28811342 : if (hlbsa)
2773 : : {
2774 : : guint i;
2775 : :
2776 : : /* reentrancy caution, delete instance trace first */
2777 : 207051 : g_hash_table_remove (g_handler_list_bsa_ht, instance);
2778 : :
2779 : 414662 : for (i = 0; i < hlbsa->n_nodes; i++)
2780 : : {
2781 : 207611 : HandlerList *hlist = g_bsearch_array_get_nth (hlbsa, &g_signal_hlbsa_bconfig, i);
2782 : 207611 : Handler *handler = hlist->handlers;
2783 : :
2784 : 208759 : while (handler)
2785 : : {
2786 : 1148 : Handler *tmp = handler;
2787 : :
2788 : 1148 : handler = tmp->next;
2789 : 1148 : tmp->block_count = 1;
2790 : : /* cruel unlink, this works because _all_ handlers vanish */
2791 : 1148 : tmp->next = NULL;
2792 : 1148 : tmp->prev = tmp;
2793 : 1148 : if (tmp->sequential_number)
2794 : : {
2795 : 1148 : g_hash_table_remove (g_handlers, tmp);
2796 : 1148 : remove_invalid_closure_notify (tmp, instance);
2797 : 1148 : tmp->sequential_number = 0;
2798 : 1148 : handler_unref_R (0, NULL, tmp);
2799 : 322 : }
2800 : : }
2801 : 100597 : }
2802 : 207051 : g_bsearch_array_free (hlbsa, &g_signal_hlbsa_bconfig);
2803 : 100534 : }
2804 : 28811342 : SIGNAL_UNLOCK ();
2805 : 12869521 : }
2806 : :
2807 : : /**
2808 : : * g_signal_handler_find:
2809 : : * @instance: (type GObject.Object): The instance owning the signal handler to be found.
2810 : : * @mask: Mask indicating which of @signal_id, @detail, @closure, @func
2811 : : * and/or @data the handler has to match.
2812 : : * @signal_id: Signal the handler has to be connected to.
2813 : : * @detail: Signal detail the handler has to be connected to.
2814 : : * @closure: (nullable): The closure the handler will invoke.
2815 : : * @func: The C closure callback of the handler (useless for non-C closures).
2816 : : * @data: (nullable) (closure closure): The closure data of the handler's closure.
2817 : : *
2818 : : * Finds the first signal handler that matches certain selection criteria.
2819 : : * The criteria mask is passed as an OR-ed combination of #GSignalMatchType
2820 : : * flags, and the criteria values are passed as arguments.
2821 : : * The match @mask has to be non-0 for successful matches.
2822 : : * If no handler was found, 0 is returned.
2823 : : *
2824 : : * Returns: A valid non-0 signal handler id for a successful match.
2825 : : */
2826 : : gulong
2827 : 23 : g_signal_handler_find (gpointer instance,
2828 : : GSignalMatchType mask,
2829 : : guint signal_id,
2830 : : GQuark detail,
2831 : : GClosure *closure,
2832 : : gpointer func,
2833 : : gpointer data)
2834 : : {
2835 : 23 : gulong handler_seq_no = 0;
2836 : :
2837 : 23 : g_return_val_if_fail (G_TYPE_CHECK_INSTANCE (instance), 0);
2838 : 23 : g_return_val_if_fail ((mask & (unsigned) ~G_SIGNAL_MATCH_MASK) == 0, 0);
2839 : :
2840 : 23 : if (mask & G_SIGNAL_MATCH_MASK)
2841 : : {
2842 : : HandlerMatch *mlist;
2843 : :
2844 : 23 : SIGNAL_LOCK ();
2845 : 23 : mlist = handlers_find (instance, mask, signal_id, detail, closure, func, data, TRUE);
2846 : 23 : if (mlist)
2847 : : {
2848 : 3 : handler_seq_no = mlist->handler->sequential_number;
2849 : 3 : handler_match_free1_R (mlist, instance);
2850 : 1 : }
2851 : 23 : SIGNAL_UNLOCK ();
2852 : 10 : }
2853 : :
2854 : 23 : return handler_seq_no;
2855 : 10 : }
2856 : :
2857 : : typedef void (*CallbackHandlerFunc) (gpointer instance, gulong handler_seq_no);
2858 : :
2859 : : static guint
2860 : 403593 : signal_handlers_foreach_matched_unlocked_R (gpointer instance,
2861 : : GSignalMatchType mask,
2862 : : guint signal_id,
2863 : : GQuark detail,
2864 : : GClosure *closure,
2865 : : gpointer func,
2866 : : gpointer data,
2867 : : CallbackHandlerFunc callback)
2868 : : {
2869 : : HandlerMatch *mlist;
2870 : 403593 : guint n_handlers = 0;
2871 : :
2872 : 403593 : mlist = handlers_find (instance, mask, signal_id, detail, closure, func, data, FALSE);
2873 : 807083 : while (mlist)
2874 : : {
2875 : 403490 : n_handlers++;
2876 : 403490 : if (mlist->handler->sequential_number)
2877 : 403490 : callback (instance, mlist->handler->sequential_number);
2878 : :
2879 : 403490 : mlist = handler_match_free1_R (mlist, instance);
2880 : : }
2881 : :
2882 : 403593 : return n_handlers;
2883 : : }
2884 : :
2885 : : /**
2886 : : * g_signal_handlers_block_matched:
2887 : : * @instance: (type GObject.Object): The instance to block handlers from.
2888 : : * @mask: Mask indicating which of @signal_id, @detail, @closure, @func
2889 : : * and/or @data the handlers have to match.
2890 : : * @signal_id: Signal the handlers have to be connected to.
2891 : : * @detail: Signal detail the handlers have to be connected to.
2892 : : * @closure: (nullable): The closure the handlers will invoke.
2893 : : * @func: The C closure callback of the handlers (useless for non-C closures).
2894 : : * @data: (nullable) (closure closure): The closure data of the handlers' closures.
2895 : : *
2896 : : * Blocks all handlers on an instance that match a certain selection criteria.
2897 : : *
2898 : : * The criteria mask is passed as a combination of #GSignalMatchType flags, and
2899 : : * the criteria values are passed as arguments. A handler must match on all
2900 : : * flags set in @mask to be blocked (i.e. the match is conjunctive).
2901 : : *
2902 : : * Passing at least one of the %G_SIGNAL_MATCH_ID, %G_SIGNAL_MATCH_CLOSURE,
2903 : : * %G_SIGNAL_MATCH_FUNC
2904 : : * or %G_SIGNAL_MATCH_DATA match flags is required for successful matches.
2905 : : * If no handlers were found, 0 is returned, the number of blocked handlers
2906 : : * otherwise.
2907 : : *
2908 : : * Support for %G_SIGNAL_MATCH_ID was added in GLib 2.78.
2909 : : *
2910 : : * Returns: The number of handlers that matched.
2911 : : */
2912 : : guint
2913 : 10 : g_signal_handlers_block_matched (gpointer instance,
2914 : : GSignalMatchType mask,
2915 : : guint signal_id,
2916 : : GQuark detail,
2917 : : GClosure *closure,
2918 : : gpointer func,
2919 : : gpointer data)
2920 : : {
2921 : 10 : guint n_handlers = 0;
2922 : :
2923 : 10 : g_return_val_if_fail (G_TYPE_CHECK_INSTANCE (instance), 0);
2924 : 10 : g_return_val_if_fail ((mask & (unsigned) ~G_SIGNAL_MATCH_MASK) == 0, 0);
2925 : :
2926 : 10 : if (mask & (G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_CLOSURE | G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA))
2927 : : {
2928 : 10 : SIGNAL_LOCK ();
2929 : 5 : n_handlers =
2930 : 15 : signal_handlers_foreach_matched_unlocked_R (instance, mask, signal_id, detail,
2931 : 5 : closure, func, data,
2932 : : signal_handler_block_unlocked);
2933 : 10 : SIGNAL_UNLOCK ();
2934 : 5 : }
2935 : :
2936 : 10 : return n_handlers;
2937 : 5 : }
2938 : :
2939 : : /**
2940 : : * g_signal_handlers_unblock_matched:
2941 : : * @instance: (type GObject.Object): The instance to unblock handlers from.
2942 : : * @mask: Mask indicating which of @signal_id, @detail, @closure, @func
2943 : : * and/or @data the handlers have to match.
2944 : : * @signal_id: Signal the handlers have to be connected to.
2945 : : * @detail: Signal detail the handlers have to be connected to.
2946 : : * @closure: (nullable): The closure the handlers will invoke.
2947 : : * @func: The C closure callback of the handlers (useless for non-C closures).
2948 : : * @data: (nullable) (closure closure): The closure data of the handlers' closures.
2949 : : *
2950 : : * Unblocks all handlers on an instance that match a certain selection
2951 : : * criteria.
2952 : : *
2953 : : * The criteria mask is passed as a combination of #GSignalMatchType flags, and
2954 : : * the criteria values are passed as arguments. A handler must match on all
2955 : : * flags set in @mask to be unblocked (i.e. the match is conjunctive).
2956 : : *
2957 : : * Passing at least one of the %G_SIGNAL_MATCH_ID, %G_SIGNAL_MATCH_CLOSURE,
2958 : : * %G_SIGNAL_MATCH_FUNC
2959 : : * or %G_SIGNAL_MATCH_DATA match flags is required for successful matches.
2960 : : * If no handlers were found, 0 is returned, the number of unblocked handlers
2961 : : * otherwise. The match criteria should not apply to any handlers that are
2962 : : * not currently blocked.
2963 : : *
2964 : : * Support for %G_SIGNAL_MATCH_ID was added in GLib 2.78.
2965 : : *
2966 : : * Returns: The number of handlers that matched.
2967 : : */
2968 : : guint
2969 : 6 : g_signal_handlers_unblock_matched (gpointer instance,
2970 : : GSignalMatchType mask,
2971 : : guint signal_id,
2972 : : GQuark detail,
2973 : : GClosure *closure,
2974 : : gpointer func,
2975 : : gpointer data)
2976 : : {
2977 : 6 : guint n_handlers = 0;
2978 : :
2979 : 6 : g_return_val_if_fail (G_TYPE_CHECK_INSTANCE (instance), 0);
2980 : 6 : g_return_val_if_fail ((mask & (unsigned) ~G_SIGNAL_MATCH_MASK) == 0, 0);
2981 : :
2982 : 6 : if (mask & (G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_CLOSURE | G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA))
2983 : : {
2984 : 6 : SIGNAL_LOCK ();
2985 : 3 : n_handlers =
2986 : 9 : signal_handlers_foreach_matched_unlocked_R (instance, mask, signal_id, detail,
2987 : 3 : closure, func, data,
2988 : : signal_handler_unblock_unlocked);
2989 : 6 : SIGNAL_UNLOCK ();
2990 : 3 : }
2991 : :
2992 : 6 : return n_handlers;
2993 : 3 : }
2994 : :
2995 : : /**
2996 : : * g_signal_handlers_disconnect_matched:
2997 : : * @instance: (type GObject.Object): The instance to remove handlers from.
2998 : : * @mask: Mask indicating which of @signal_id, @detail, @closure, @func
2999 : : * and/or @data the handlers have to match.
3000 : : * @signal_id: Signal the handlers have to be connected to.
3001 : : * @detail: Signal detail the handlers have to be connected to.
3002 : : * @closure: (nullable): The closure the handlers will invoke.
3003 : : * @func: The C closure callback of the handlers (useless for non-C closures).
3004 : : * @data: (nullable) (closure closure): The closure data of the handlers' closures.
3005 : : *
3006 : : * Disconnects all handlers on an instance that match a certain
3007 : : * selection criteria.
3008 : : *
3009 : : * The criteria mask is passed as a combination of #GSignalMatchType flags, and
3010 : : * the criteria values are passed as arguments. A handler must match on all
3011 : : * flags set in @mask to be disconnected (i.e. the match is conjunctive).
3012 : : *
3013 : : * Passing at least one of the %G_SIGNAL_MATCH_ID, %G_SIGNAL_MATCH_CLOSURE,
3014 : : * %G_SIGNAL_MATCH_FUNC or
3015 : : * %G_SIGNAL_MATCH_DATA match flags is required for successful
3016 : : * matches. If no handlers were found, 0 is returned, the number of
3017 : : * disconnected handlers otherwise.
3018 : : *
3019 : : * Support for %G_SIGNAL_MATCH_ID was added in GLib 2.78.
3020 : : *
3021 : : * Returns: The number of handlers that matched.
3022 : : */
3023 : : guint
3024 : 403577 : g_signal_handlers_disconnect_matched (gpointer instance,
3025 : : GSignalMatchType mask,
3026 : : guint signal_id,
3027 : : GQuark detail,
3028 : : GClosure *closure,
3029 : : gpointer func,
3030 : : gpointer data)
3031 : : {
3032 : 403577 : guint n_handlers = 0;
3033 : :
3034 : 403577 : g_return_val_if_fail (G_TYPE_CHECK_INSTANCE (instance), 0);
3035 : 403577 : g_return_val_if_fail ((mask & (unsigned) ~G_SIGNAL_MATCH_MASK) == 0, 0);
3036 : :
3037 : 403577 : if (mask & (G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_CLOSURE | G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA))
3038 : : {
3039 : 403577 : SIGNAL_LOCK ();
3040 : 1315 : n_handlers =
3041 : 404892 : signal_handlers_foreach_matched_unlocked_R (instance, mask, signal_id, detail,
3042 : 1315 : closure, func, data,
3043 : : signal_handler_disconnect_unlocked);
3044 : 403577 : SIGNAL_UNLOCK ();
3045 : 1315 : }
3046 : :
3047 : 403577 : return n_handlers;
3048 : 1315 : }
3049 : :
3050 : : /**
3051 : : * g_signal_has_handler_pending:
3052 : : * @instance: (type GObject.Object): the object whose signal handlers are sought.
3053 : : * @signal_id: the signal id.
3054 : : * @detail: the detail.
3055 : : * @may_be_blocked: whether blocked handlers should count as match.
3056 : : *
3057 : : * Returns whether there are any handlers connected to @instance for the
3058 : : * given signal id and detail.
3059 : : *
3060 : : * If @detail is 0 then it will only match handlers that were connected
3061 : : * without detail. If @detail is non-zero then it will match handlers
3062 : : * connected both without detail and with the given detail. This is
3063 : : * consistent with how a signal emitted with @detail would be delivered
3064 : : * to those handlers.
3065 : : *
3066 : : * Since 2.46 this also checks for a non-default class closure being
3067 : : * installed, as this is basically always what you want.
3068 : : *
3069 : : * One example of when you might use this is when the arguments to the
3070 : : * signal are difficult to compute. A class implementor may opt to not
3071 : : * emit the signal if no one is attached anyway, thus saving the cost
3072 : : * of building the arguments.
3073 : : *
3074 : : * Returns: %TRUE if a handler is connected to the signal, %FALSE
3075 : : * otherwise.
3076 : : */
3077 : : gboolean
3078 : 151 : g_signal_has_handler_pending (gpointer instance,
3079 : : guint signal_id,
3080 : : GQuark detail,
3081 : : gboolean may_be_blocked)
3082 : : {
3083 : : HandlerMatch *mlist;
3084 : : gboolean has_pending;
3085 : : SignalNode *node;
3086 : :
3087 : 151 : g_return_val_if_fail (G_TYPE_CHECK_INSTANCE (instance), FALSE);
3088 : 151 : g_return_val_if_fail (signal_id > 0, FALSE);
3089 : :
3090 : 151 : SIGNAL_LOCK ();
3091 : :
3092 : 151 : node = LOOKUP_SIGNAL_NODE (signal_id);
3093 : 151 : if (detail)
3094 : : {
3095 : 0 : if (!(node->flags & G_SIGNAL_DETAILED))
3096 : : {
3097 : 0 : g_critical ("%s: signal id '%u' does not support detail (%u)", G_STRLOC, signal_id, detail);
3098 : 0 : SIGNAL_UNLOCK ();
3099 : 0 : return FALSE;
3100 : : }
3101 : 0 : }
3102 : 155 : mlist = handlers_find (instance,
3103 : 4 : (G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_DETAIL | (may_be_blocked ? 0 : G_SIGNAL_MATCH_UNBLOCKED)),
3104 : 4 : signal_id, detail, NULL, NULL, NULL, TRUE);
3105 : 151 : if (mlist)
3106 : : {
3107 : 80 : has_pending = TRUE;
3108 : 80 : handler_match_free1_R (mlist, instance);
3109 : 0 : }
3110 : : else
3111 : : {
3112 : 71 : ClassClosure *class_closure = signal_find_class_closure (node, G_TYPE_FROM_INSTANCE (instance));
3113 : 71 : if (class_closure != NULL && class_closure->instance_type != 0)
3114 : 0 : has_pending = TRUE;
3115 : : else
3116 : 71 : has_pending = FALSE;
3117 : : }
3118 : 151 : SIGNAL_UNLOCK ();
3119 : :
3120 : 151 : return has_pending;
3121 : 4 : }
3122 : :
3123 : : static void
3124 : : signal_emitv_unlocked (const GValue *instance_and_params,
3125 : : guint signal_id,
3126 : : GQuark detail,
3127 : : GValue *return_value);
3128 : :
3129 : : /**
3130 : : * g_signal_emitv:
3131 : : * @instance_and_params: (array): argument list for the signal emission.
3132 : : * The first element in the array is a #GValue for the instance the signal
3133 : : * is being emitted on. The rest are any arguments to be passed to the signal.
3134 : : * @signal_id: the signal id
3135 : : * @detail: the detail
3136 : : * @return_value: (inout) (optional): Location to
3137 : : * store the return value of the signal emission. This must be provided if the
3138 : : * specified signal returns a value, but may be ignored otherwise.
3139 : : *
3140 : : * Emits a signal. Signal emission is done synchronously.
3141 : : * The method will only return control after all handlers are called or signal emission was stopped.
3142 : : *
3143 : : * Note that g_signal_emitv() doesn't change @return_value if no handlers are
3144 : : * connected, in contrast to g_signal_emit() and g_signal_emit_valist().
3145 : : */
3146 : : void
3147 : 84 : g_signal_emitv (const GValue *instance_and_params,
3148 : : guint signal_id,
3149 : : GQuark detail,
3150 : : GValue *return_value)
3151 : : {
3152 : 84 : SIGNAL_LOCK ();
3153 : 84 : signal_emitv_unlocked (instance_and_params, signal_id, detail, return_value);
3154 : 84 : SIGNAL_UNLOCK ();
3155 : 84 : }
3156 : :
3157 : : static void
3158 : 84 : signal_emitv_unlocked (const GValue *instance_and_params,
3159 : : guint signal_id,
3160 : : GQuark detail,
3161 : : GValue *return_value)
3162 : : {
3163 : : gpointer instance;
3164 : : SignalNode *node;
3165 : : #ifdef G_ENABLE_DEBUG
3166 : : const GValue *param_values;
3167 : : guint i;
3168 : : #endif
3169 : :
3170 : 86 : g_return_if_fail (instance_and_params != NULL);
3171 : 84 : instance = g_value_peek_pointer (instance_and_params);
3172 : 84 : g_return_if_fail (G_TYPE_CHECK_INSTANCE (instance));
3173 : 84 : g_return_if_fail (signal_id > 0);
3174 : :
3175 : : #ifdef G_ENABLE_DEBUG
3176 : 84 : param_values = instance_and_params + 1;
3177 : : #endif
3178 : :
3179 : 84 : node = LOOKUP_SIGNAL_NODE (signal_id);
3180 : 84 : if (!node || !g_type_is_a (G_TYPE_FROM_INSTANCE (instance), node->itype))
3181 : : {
3182 : 0 : g_critical ("%s: signal id '%u' is invalid for instance '%p'", G_STRLOC, signal_id, instance);
3183 : 0 : return;
3184 : : }
3185 : : #ifdef G_ENABLE_DEBUG
3186 : 84 : if (detail && !(node->flags & G_SIGNAL_DETAILED))
3187 : : {
3188 : 0 : g_critical ("%s: signal id '%u' does not support detail (%u)", G_STRLOC, signal_id, detail);
3189 : 0 : return;
3190 : : }
3191 : 361 : for (i = 0; i < node->n_params; i++)
3192 : 307 : if (!G_TYPE_CHECK_VALUE_TYPE (param_values + i, node->param_types[i] & ~G_SIGNAL_TYPE_STATIC_SCOPE))
3193 : : {
3194 : 0 : g_critical ("%s: value for '%s' parameter %u for signal \"%s\" is of type '%s'",
3195 : : G_STRLOC,
3196 : 0 : type_debug_name (node->param_types[i]),
3197 : 0 : i,
3198 : 0 : node->name,
3199 : 0 : G_VALUE_TYPE_NAME (param_values + i));
3200 : 0 : return;
3201 : : }
3202 : 84 : if (node->return_type != G_TYPE_NONE)
3203 : : {
3204 : 71 : if (!return_value)
3205 : : {
3206 : 2 : g_critical ("%s: return value '%s' for signal \"%s\" is (NULL)",
3207 : : G_STRLOC,
3208 : 1 : type_debug_name (node->return_type),
3209 : 1 : node->name);
3210 : 2 : return;
3211 : : }
3212 : 72 : else if (!node->accumulator && !G_TYPE_CHECK_VALUE_TYPE (return_value, node->return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE))
3213 : : {
3214 : 2 : g_critical ("%s: return value '%s' for signal \"%s\" is of type '%s'",
3215 : : G_STRLOC,
3216 : 1 : type_debug_name (node->return_type),
3217 : 1 : node->name,
3218 : 1 : G_VALUE_TYPE_NAME (return_value));
3219 : 2 : return;
3220 : : }
3221 : 6 : }
3222 : : else
3223 : 13 : return_value = NULL;
3224 : : #endif /* G_ENABLE_DEBUG */
3225 : :
3226 : : /* optimize NOP emissions */
3227 : 80 : if (!node->single_va_closure_is_valid)
3228 : 47 : node_update_single_va_closure (node);
3229 : :
3230 : 80 : if (node->single_va_closure != NULL &&
3231 : 2 : (node->single_va_closure == SINGLE_VA_CLOSURE_EMPTY_MAGIC ||
3232 : 0 : _g_closure_is_void (node->single_va_closure, instance)))
3233 : : {
3234 : : HandlerList* hlist;
3235 : :
3236 : : /* single_va_closure is only true for GObjects, so fast path if no handler ever connected to the signal */
3237 : 2 : if (_g_object_has_signal_handler ((GObject *)instance))
3238 : 2 : hlist = handler_list_lookup (node->signal_id, instance);
3239 : : else
3240 : 0 : hlist = NULL;
3241 : :
3242 : 2 : if (hlist == NULL || hlist->handlers == NULL)
3243 : : {
3244 : : /* nothing to do to emit this signal */
3245 : : /* g_printerr ("omitting emission of \"%s\"\n", node->name); */
3246 : 0 : return;
3247 : : }
3248 : 1 : }
3249 : :
3250 : : /* Pass a stable node pointer, whose address can't change even if the
3251 : : * g_signal_nodes array gets reallocated. */
3252 : 80 : SignalNode node_copy = *node;
3253 : 80 : signal_emit_unlocked_R (&node_copy, detail, instance, return_value, instance_and_params);
3254 : 10 : }
3255 : :
3256 : : static inline gboolean
3257 : 42062936 : accumulate (GSignalInvocationHint *ihint,
3258 : : GValue *return_accu,
3259 : : GValue *handler_return,
3260 : : SignalAccumulator *accumulator)
3261 : : {
3262 : : gboolean continue_emission;
3263 : :
3264 : 42062936 : if (!accumulator)
3265 : 42060448 : return TRUE;
3266 : :
3267 : 2488 : continue_emission = accumulator->func (ihint, return_accu, handler_return, accumulator->data);
3268 : 2488 : g_value_reset (handler_return);
3269 : :
3270 : 2488 : ihint->run_type &= (unsigned) ~G_SIGNAL_ACCUMULATOR_FIRST_RUN;
3271 : :
3272 : 2488 : return continue_emission;
3273 : 26019681 : }
3274 : :
3275 : : static gboolean
3276 : : signal_emit_valist_unlocked (gpointer instance,
3277 : : guint signal_id,
3278 : : GQuark detail,
3279 : : va_list var_args);
3280 : :
3281 : : /**
3282 : : * g_signal_emit_valist: (skip)
3283 : : * @instance: (type GObject.TypeInstance): the instance the signal is being
3284 : : * emitted on.
3285 : : * @signal_id: the signal id
3286 : : * @detail: the detail
3287 : : * @var_args: a list of parameters to be passed to the signal, followed by a
3288 : : * location for the return value. If the return type of the signal
3289 : : * is %G_TYPE_NONE, the return value location can be omitted.
3290 : : *
3291 : : * Emits a signal. Signal emission is done synchronously.
3292 : : * The method will only return control after all handlers are called or signal emission was stopped.
3293 : : *
3294 : : * Note that g_signal_emit_valist() resets the return value to the default
3295 : : * if no handlers are connected, in contrast to g_signal_emitv().
3296 : : */
3297 : : void
3298 : 43250322 : g_signal_emit_valist (gpointer instance,
3299 : : guint signal_id,
3300 : : GQuark detail,
3301 : : va_list var_args)
3302 : : {
3303 : 43250322 : SIGNAL_LOCK ();
3304 : 43250322 : if (signal_emit_valist_unlocked (instance, signal_id, detail, var_args))
3305 : 16925037 : SIGNAL_UNLOCK ();
3306 : 43250314 : }
3307 : :
3308 : : /*<private>
3309 : : * signal_emit_valist_unlocked:
3310 : : * @instance: The instance to emit from
3311 : : * @signal_id: Signal id to emit
3312 : : * @detail: Signal detail
3313 : : * @var_args: Call arguments
3314 : : *
3315 : : * Returns: %TRUE if the signal mutex has been left locked
3316 : : */
3317 : : static gboolean
3318 : 43291855 : signal_emit_valist_unlocked (gpointer instance,
3319 : : guint signal_id,
3320 : : GQuark detail,
3321 : : va_list var_args)
3322 : : {
3323 : : GValue *instance_and_params;
3324 : : GValue *param_values;
3325 : : SignalNode *node;
3326 : : guint i;
3327 : :
3328 : 43291855 : g_return_val_if_fail (G_TYPE_CHECK_INSTANCE (instance), TRUE);
3329 : 43291855 : g_return_val_if_fail (signal_id > 0, TRUE);
3330 : :
3331 : 43291855 : node = LOOKUP_SIGNAL_NODE (signal_id);
3332 : 43291855 : if (!node || !g_type_is_a (G_TYPE_FROM_INSTANCE (instance), node->itype))
3333 : : {
3334 : 13896 : g_critical ("%s: signal id '%u' is invalid for instance '%p'", G_STRLOC, signal_id, instance);
3335 : 13896 : return TRUE;
3336 : : }
3337 : : #ifndef G_DISABLE_CHECKS
3338 : 43291855 : if (detail && !(node->flags & G_SIGNAL_DETAILED))
3339 : : {
3340 : 0 : g_critical ("%s: signal id '%u' does not support detail (%u)", G_STRLOC, signal_id, detail);
3341 : 0 : return TRUE;
3342 : : }
3343 : : #endif /* !G_DISABLE_CHECKS */
3344 : :
3345 : 43291855 : if (!node->single_va_closure_is_valid)
3346 : 638 : node_update_single_va_closure (node);
3347 : :
3348 : : /* There's no need to deep copy this, because a SignalNode instance won't
3349 : : * ever be destroyed, given that _g_signals_destroy() is not called in any
3350 : : * real program, however the SignalNode pointer could change, so just store
3351 : : * the struct contents references, so that we won't try to deference a
3352 : : * potentially invalid (or changed) pointer;
3353 : : */
3354 : 43291855 : SignalNode node_copy = *node;
3355 : :
3356 : 43291855 : if (node->single_va_closure != NULL)
3357 : : {
3358 : : HandlerList* hlist;
3359 : 43180118 : Handler *fastpath_handler = NULL;
3360 : : Handler *l;
3361 : 43180118 : GClosure *closure = NULL;
3362 : 43180118 : gboolean fastpath = TRUE;
3363 : 43180118 : GSignalFlags run_type = G_SIGNAL_RUN_FIRST;
3364 : :
3365 : 61893241 : if (node->single_va_closure != SINGLE_VA_CLOSURE_EMPTY_MAGIC &&
3366 : 42831424 : !_g_closure_is_void (node->single_va_closure, instance))
3367 : : {
3368 : 13628171 : if (_g_closure_supports_invoke_va (node->single_va_closure))
3369 : : {
3370 : 1412824 : closure = node->single_va_closure;
3371 : 1412824 : if (node->single_va_closure_is_after)
3372 : 1963 : run_type = G_SIGNAL_RUN_LAST;
3373 : : else
3374 : 1410861 : run_type = G_SIGNAL_RUN_FIRST;
3375 : 732003 : }
3376 : : else
3377 : 12215347 : fastpath = FALSE;
3378 : 8867447 : }
3379 : :
3380 : : /* single_va_closure is only true for GObjects, so fast path if no handler ever connected to the signal */
3381 : 43180118 : if (_g_object_has_signal_handler ((GObject *)instance))
3382 : 20487732 : hlist = handler_list_lookup (node->signal_id, instance);
3383 : : else
3384 : 22692386 : hlist = NULL;
3385 : :
3386 : 53044905 : for (l = hlist ? hlist->handlers : NULL; fastpath && l != NULL; l = l->next)
3387 : : {
3388 : 19673142 : if (!l->block_count &&
3389 : 14349812 : (!l->detail || l->detail == detail))
3390 : : {
3391 : 13128730 : if (closure != NULL || !_g_closure_supports_invoke_va (l->closure))
3392 : : {
3393 : 4485591 : fastpath = FALSE;
3394 : 4485591 : break;
3395 : : }
3396 : : else
3397 : : {
3398 : 8643139 : fastpath_handler = l;
3399 : 8643139 : closure = l->closure;
3400 : 8643139 : if (l->after)
3401 : 0 : run_type = G_SIGNAL_RUN_LAST;
3402 : : else
3403 : 8643139 : run_type = G_SIGNAL_RUN_FIRST;
3404 : : }
3405 : 5253839 : }
3406 : 5881083 : }
3407 : :
3408 : 43180118 : if (fastpath && closure == NULL && node_copy.return_type == G_TYPE_NONE)
3409 : 16925223 : return TRUE;
3410 : :
3411 : : /* Don't allow no-recurse emission as we might have to restart, which means
3412 : : we will run multiple handlers and thus must ref all arguments */
3413 : 26254895 : if (closure != NULL && (node_copy.flags & (G_SIGNAL_NO_RECURSE)) != 0)
3414 : 7598326 : fastpath = FALSE;
3415 : :
3416 : 26254895 : if (fastpath)
3417 : : {
3418 : : Emission emission;
3419 : 1955657 : GValue *return_accu, accu = G_VALUE_INIT;
3420 : 1955657 : GType instance_type = G_TYPE_FROM_INSTANCE (instance);
3421 : 1955657 : GValue emission_return = G_VALUE_INIT;
3422 : 1955657 : GType rtype = node_copy.return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE;
3423 : 1955657 : gboolean static_scope = node_copy.return_type & G_SIGNAL_TYPE_STATIC_SCOPE;
3424 : :
3425 : 1955657 : if (rtype == G_TYPE_NONE)
3426 : 1954686 : return_accu = NULL;
3427 : 971 : else if (node_copy.accumulator)
3428 : 939 : return_accu = &accu;
3429 : : else
3430 : 32 : return_accu = &emission_return;
3431 : :
3432 : 1955657 : emission.instance = instance;
3433 : 1955657 : emission.ihint.signal_id = signal_id;
3434 : 1955657 : emission.ihint.detail = detail;
3435 : 1955657 : emission.ihint.run_type = run_type | G_SIGNAL_ACCUMULATOR_FIRST_RUN;
3436 : 1955657 : emission.state = EMISSION_RUN;
3437 : 1955657 : emission.chain_type = instance_type;
3438 : 1955657 : emission_push (&emission);
3439 : :
3440 : 1955657 : if (fastpath_handler)
3441 : 1044883 : handler_ref (fastpath_handler);
3442 : :
3443 : 1955657 : if (closure != NULL)
3444 : : {
3445 : 924819 : TRACE (GOBJECT_SIGNAL_EMIT (signal_id, detail, instance, (uintmax_t) instance_type));
3446 : :
3447 : 1955655 : SIGNAL_UNLOCK ();
3448 : :
3449 : 1955655 : if (rtype != G_TYPE_NONE)
3450 : 971 : g_value_init (&emission_return, rtype);
3451 : :
3452 : 1955655 : if (node_copy.accumulator)
3453 : 939 : g_value_init (&accu, rtype);
3454 : :
3455 : : /*
3456 : : * Coverity doesn’t understand the paired ref/unref here and seems
3457 : : * to ignore the ref, thus reports every call to g_signal_emit()
3458 : : * as causing a double-free. That’s incorrect, but I can’t get a
3459 : : * model file to work for avoiding the false positives, so instead
3460 : : * comment out the ref/unref when doing static analysis.
3461 : : */
3462 : : #ifndef __COVERITY__
3463 : 1955655 : g_object_ref (instance);
3464 : : #endif
3465 : 2986491 : _g_closure_invoke_va (closure,
3466 : 1030836 : return_accu,
3467 : 1030836 : instance,
3468 : 1030836 : var_args,
3469 : 1955655 : node_copy.n_params,
3470 : 1030836 : node_copy.param_types);
3471 : 1955653 : accumulate (&emission.ihint, &emission_return, &accu, node_copy.accumulator);
3472 : :
3473 : 1955653 : if (node_copy.accumulator)
3474 : 939 : g_value_unset (&accu);
3475 : :
3476 : 1955653 : SIGNAL_LOCK ();
3477 : 1030836 : }
3478 : :
3479 : 1955655 : emission.chain_type = G_TYPE_NONE;
3480 : 1955655 : emission_pop (&emission);
3481 : :
3482 : 1955655 : if (fastpath_handler)
3483 : 1044879 : handler_unref_R (signal_id, instance, fastpath_handler);
3484 : :
3485 : 1955655 : SIGNAL_UNLOCK ();
3486 : :
3487 : 1955655 : if (rtype != G_TYPE_NONE)
3488 : : {
3489 : 971 : gchar *error = NULL;
3490 : 2548 : for (i = 0; i < node_copy.n_params; i++)
3491 : : {
3492 : 1577 : GType ptype = node_copy.param_types[i] & ~G_SIGNAL_TYPE_STATIC_SCOPE;
3493 : 3154 : G_VALUE_COLLECT_SKIP (ptype, var_args);
3494 : 102 : }
3495 : :
3496 : 971 : if (closure == NULL)
3497 : 0 : g_value_init (&emission_return, rtype);
3498 : :
3499 : 1942 : G_VALUE_LCOPY (&emission_return,
3500 : : var_args,
3501 : 80 : static_scope ? G_VALUE_NOCOPY_CONTENTS : 0,
3502 : : &error);
3503 : 971 : if (!error)
3504 : 971 : g_value_unset (&emission_return);
3505 : : else
3506 : : {
3507 : 0 : g_critical ("%s: %s", G_STRLOC, error);
3508 : 0 : g_free (error);
3509 : : /* we purposely leak the value here, it might not be
3510 : : * in a correct state if an error condition occurred
3511 : : */
3512 : : }
3513 : 80 : }
3514 : :
3515 : 924817 : TRACE (GOBJECT_SIGNAL_EMIT_END (signal_id, detail, instance, (uintmax_t) instance_type));
3516 : :
3517 : : /* See comment above paired ref above */
3518 : : #ifndef __COVERITY__
3519 : 1955655 : if (closure != NULL)
3520 : 1955653 : g_object_unref (instance);
3521 : : #endif
3522 : :
3523 : 1955655 : return FALSE;
3524 : : }
3525 : 15515212 : }
3526 : :
3527 : 24410975 : SIGNAL_UNLOCK ();
3528 : :
3529 : 24410975 : instance_and_params = g_newa0 (GValue, node_copy.n_params + 1);
3530 : 24392873 : param_values = instance_and_params + 1;
3531 : :
3532 : 47786922 : for (i = 0; i < node_copy.n_params; i++)
3533 : : {
3534 : : gchar *error;
3535 : 23394049 : GType ptype = node_copy.param_types[i] & ~G_SIGNAL_TYPE_STATIC_SCOPE;
3536 : 23394049 : gboolean static_scope = node_copy.param_types[i] & G_SIGNAL_TYPE_STATIC_SCOPE;
3537 : :
3538 : 46785633 : G_VALUE_COLLECT_INIT (param_values + i, ptype,
3539 : : var_args,
3540 : 14936192 : static_scope ? G_VALUE_NOCOPY_CONTENTS : 0,
3541 : : &error);
3542 : 23394049 : if (error)
3543 : : {
3544 : 0 : g_critical ("%s: %s", G_STRLOC, error);
3545 : 0 : g_free (error);
3546 : :
3547 : : /* we purposely leak the value here, it might not be
3548 : : * in a correct state if an error condition occurred
3549 : : */
3550 : 0 : while (i--)
3551 : 0 : g_value_unset (param_values + i);
3552 : :
3553 : 0 : return FALSE;
3554 : : }
3555 : 14936192 : }
3556 : :
3557 : 24392873 : g_value_init_from_instance (instance_and_params, instance);
3558 : 24392873 : if (node_copy.return_type == G_TYPE_NONE)
3559 : : {
3560 : 19353461 : SIGNAL_LOCK ();
3561 : 19353461 : signal_emit_unlocked_R (&node_copy, detail, instance, NULL, instance_and_params);
3562 : 19353455 : SIGNAL_UNLOCK ();
3563 : 11412234 : }
3564 : : else
3565 : : {
3566 : 5039412 : GValue return_value = G_VALUE_INIT;
3567 : 5039412 : gchar *error = NULL;
3568 : 5039412 : GType rtype = node_copy.return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE;
3569 : 5039412 : gboolean static_scope = node_copy.return_type & G_SIGNAL_TYPE_STATIC_SCOPE;
3570 : :
3571 : 5039412 : g_value_init (&return_value, rtype);
3572 : :
3573 : 5039412 : SIGNAL_LOCK ();
3574 : 5039412 : signal_emit_unlocked_R (&node_copy, detail, instance, &return_value, instance_and_params);
3575 : 5039412 : SIGNAL_UNLOCK ();
3576 : :
3577 : 10078280 : G_VALUE_LCOPY (&return_value,
3578 : : var_args,
3579 : 4093927 : static_scope ? G_VALUE_NOCOPY_CONTENTS : 0,
3580 : : &error);
3581 : 5039412 : if (!error)
3582 : 5039412 : g_value_unset (&return_value);
3583 : : else
3584 : : {
3585 : 0 : g_critical ("%s: %s", G_STRLOC, error);
3586 : 0 : g_free (error);
3587 : :
3588 : : /* we purposely leak the value here, it might not be
3589 : : * in a correct state if an error condition occurred
3590 : : */
3591 : : }
3592 : : }
3593 : 47778735 : for (i = 0; i < node_copy.n_params; i++)
3594 : 23385868 : g_value_unset (param_values + i);
3595 : 24392867 : g_value_unset (instance_and_params);
3596 : :
3597 : 24392867 : return FALSE;
3598 : 24131743 : }
3599 : :
3600 : : /**
3601 : : * g_signal_emit:
3602 : : * @instance: (type GObject.Object): the instance the signal is being emitted on.
3603 : : * @signal_id: the signal id
3604 : : * @detail: the detail
3605 : : * @...: parameters to be passed to the signal, followed by a
3606 : : * location for the return value. If the return type of the signal
3607 : : * is %G_TYPE_NONE, the return value location can be omitted.
3608 : : *
3609 : : * Emits a signal. Signal emission is done synchronously.
3610 : : * The method will only return control after all handlers are called or signal emission was stopped.
3611 : : *
3612 : : * Note that g_signal_emit() resets the return value to the default
3613 : : * if no handlers are connected, in contrast to g_signal_emitv().
3614 : : */
3615 : : void
3616 : 43251337 : g_signal_emit (gpointer instance,
3617 : : guint signal_id,
3618 : : GQuark detail,
3619 : : ...)
3620 : : {
3621 : : va_list var_args;
3622 : :
3623 : 43251337 : va_start (var_args, detail);
3624 : 43251337 : g_signal_emit_valist (instance, signal_id, detail, var_args);
3625 : 43251329 : va_end (var_args);
3626 : 43251329 : }
3627 : :
3628 : : /**
3629 : : * g_signal_emit_by_name:
3630 : : * @instance: (type GObject.Object): the instance the signal is being emitted on.
3631 : : * @detailed_signal: a string of the form "signal-name::detail".
3632 : : * @...: parameters to be passed to the signal, followed by a
3633 : : * location for the return value. If the return type of the signal
3634 : : * is %G_TYPE_NONE, the return value location can be omitted. The
3635 : : * number of parameters to pass to this function is defined when creating the signal.
3636 : : *
3637 : : * Emits a signal. Signal emission is done synchronously.
3638 : : * The method will only return control after all handlers are called or signal emission was stopped.
3639 : : *
3640 : : * Note that g_signal_emit_by_name() resets the return value to the default
3641 : : * if no handlers are connected, in contrast to g_signal_emitv().
3642 : : */
3643 : : void
3644 : 553 : g_signal_emit_by_name (gpointer instance,
3645 : : const gchar *detailed_signal,
3646 : : ...)
3647 : : {
3648 : 553 : GQuark detail = 0;
3649 : : guint signal_id;
3650 : : GType itype;
3651 : :
3652 : 553 : g_return_if_fail (G_TYPE_CHECK_INSTANCE (instance));
3653 : 553 : g_return_if_fail (detailed_signal != NULL);
3654 : :
3655 : 553 : itype = G_TYPE_FROM_INSTANCE (instance);
3656 : :
3657 : 553 : SIGNAL_LOCK ();
3658 : 553 : signal_id = signal_parse_name (detailed_signal, itype, &detail, TRUE);
3659 : :
3660 : 553 : if (signal_id)
3661 : : {
3662 : : va_list var_args;
3663 : :
3664 : 553 : va_start (var_args, detailed_signal);
3665 : 553 : if (signal_emit_valist_unlocked (instance, signal_id, detail, var_args))
3666 : 186 : SIGNAL_UNLOCK ();
3667 : 553 : va_end (var_args);
3668 : 88 : }
3669 : : else
3670 : : {
3671 : 0 : SIGNAL_UNLOCK ();
3672 : :
3673 : 0 : g_critical ("%s: signal name '%s' is invalid for instance '%p' of type '%s'",
3674 : 0 : G_STRLOC, detailed_signal, instance, g_type_name (itype));
3675 : : }
3676 : 88 : }
3677 : :
3678 : : G_ALWAYS_INLINE static inline GValue *
3679 : 24991545 : maybe_init_accumulator_unlocked (SignalNode *node,
3680 : : GValue *emission_return,
3681 : : GValue *accumulator_value)
3682 : : {
3683 : 40109985 : if (node->accumulator)
3684 : : {
3685 : 1541 : if (accumulator_value->g_type)
3686 : 601 : return accumulator_value;
3687 : :
3688 : 976 : g_value_init (accumulator_value,
3689 : 940 : node->return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE);
3690 : 940 : return accumulator_value;
3691 : : }
3692 : :
3693 : 40108444 : return emission_return;
3694 : 24991545 : }
3695 : :
3696 : : static gboolean
3697 : 24404107 : signal_emit_unlocked_R (SignalNode *node,
3698 : : GQuark detail,
3699 : : gpointer instance,
3700 : : GValue *emission_return,
3701 : : const GValue *instance_and_params)
3702 : : {
3703 : : SignalAccumulator *accumulator;
3704 : : Emission emission;
3705 : : GClosure *class_closure;
3706 : : HandlerList *hlist;
3707 : 24404107 : Handler *handler_list = NULL;
3708 : 24404107 : GValue *return_accu, accu = G_VALUE_INIT;
3709 : : guint signal_id;
3710 : : gulong max_sequential_handler_number;
3711 : 24404107 : gboolean return_value_altered = FALSE;
3712 : : guint n_params;
3713 : :
3714 : 8886784 : TRACE(GOBJECT_SIGNAL_EMIT(node->signal_id, detail, instance, G_TYPE_FROM_INSTANCE (instance)));
3715 : :
3716 : : /* We expect this function to be called with a stable SignalNode pointer
3717 : : * that cannot change location, so accessing its stable members should
3718 : : * always work even after a lock/unlock.
3719 : : */
3720 : 24404107 : signal_id = node->signal_id;
3721 : 24404107 : n_params = node->n_params + 1;
3722 : :
3723 : 24404107 : if (node->flags & G_SIGNAL_NO_RECURSE)
3724 : : {
3725 : 7598326 : Emission *emission_node = emission_find (signal_id, detail, instance);
3726 : :
3727 : 7598326 : if (emission_node)
3728 : : {
3729 : 491605 : emission_node->state = EMISSION_RESTART;
3730 : 491605 : return return_value_altered;
3731 : : }
3732 : 4445341 : }
3733 : 23912502 : accumulator = node->accumulator;
3734 : 23912502 : emission.instance = instance;
3735 : 23912502 : emission.ihint.signal_id = node->signal_id;
3736 : 23912502 : emission.ihint.detail = detail;
3737 : 23912502 : emission.ihint.run_type = 0;
3738 : 23912502 : emission.state = 0;
3739 : 23912502 : emission.chain_type = G_TYPE_NONE;
3740 : 23912502 : emission_push (&emission);
3741 : 23912502 : class_closure = signal_lookup_closure (node, instance);
3742 : :
3743 : 80691 : EMIT_RESTART:
3744 : :
3745 : 24193632 : if (handler_list)
3746 : 281130 : handler_unref_R (signal_id, instance, handler_list);
3747 : 24193632 : max_sequential_handler_number = g_handler_sequential_number;
3748 : 24193632 : hlist = handler_list_lookup (signal_id, instance);
3749 : 24193632 : handler_list = hlist ? hlist->handlers : NULL;
3750 : 24193632 : if (handler_list)
3751 : 16093391 : handler_ref (handler_list);
3752 : :
3753 : 24193632 : emission.ihint.run_type = G_SIGNAL_RUN_FIRST | G_SIGNAL_ACCUMULATOR_FIRST_RUN;
3754 : :
3755 : 24193632 : if ((node->flags & G_SIGNAL_RUN_FIRST) && class_closure)
3756 : : {
3757 : 10729677 : emission.state = EMISSION_RUN;
3758 : :
3759 : 10729677 : emission.chain_type = G_TYPE_FROM_INSTANCE (instance);
3760 : 10729677 : SIGNAL_UNLOCK ();
3761 : 10729677 : return_accu = maybe_init_accumulator_unlocked (node, emission_return, &accu);
3762 : 17103724 : g_closure_invoke (class_closure,
3763 : 6374047 : return_accu,
3764 : 6374047 : n_params,
3765 : 6374047 : instance_and_params,
3766 : 6374047 : &emission.ihint);
3767 : 10729677 : if (!accumulate (&emission.ihint, emission_return, &accu, accumulator) &&
3768 : 0 : emission.state == EMISSION_RUN)
3769 : 0 : emission.state = EMISSION_STOP;
3770 : 10729677 : SIGNAL_LOCK ();
3771 : 10729677 : emission.chain_type = G_TYPE_NONE;
3772 : 10729677 : return_value_altered = TRUE;
3773 : :
3774 : 10729677 : if (emission.state == EMISSION_STOP)
3775 : 0 : goto EMIT_CLEANUP;
3776 : 10729677 : else if (emission.state == EMISSION_RESTART)
3777 : 110155 : goto EMIT_RESTART;
3778 : 6301319 : }
3779 : :
3780 : 24083477 : if (node->emission_hooks)
3781 : : {
3782 : : GHook *hook;
3783 : : GHook *static_emission_hooks[3];
3784 : 28 : size_t n_emission_hooks = 0;
3785 : 28 : const gboolean may_recurse = TRUE;
3786 : : guint i;
3787 : :
3788 : 28 : emission.state = EMISSION_HOOK;
3789 : :
3790 : : /* Quick check to determine whether any hooks match this emission,
3791 : : * before committing to the more complex work of calling those hooks.
3792 : : * We save a few of them into a static array, to try to avoid further
3793 : : * allocations.
3794 : : */
3795 : 28 : hook = g_hook_first_valid (node->emission_hooks, may_recurse);
3796 : 102 : while (hook)
3797 : : {
3798 : 74 : SignalHook *signal_hook = SIGNAL_HOOK (hook);
3799 : :
3800 : 74 : if (!signal_hook->detail || signal_hook->detail == detail)
3801 : : {
3802 : 74 : if (n_emission_hooks < G_N_ELEMENTS (static_emission_hooks))
3803 : : {
3804 : 32 : static_emission_hooks[n_emission_hooks] =
3805 : 32 : g_hook_ref (node->emission_hooks, hook);
3806 : 16 : }
3807 : :
3808 : 74 : n_emission_hooks += 1;
3809 : 37 : }
3810 : :
3811 : 74 : hook = g_hook_next_valid (node->emission_hooks, hook, may_recurse);
3812 : : }
3813 : :
3814 : : /* Re-iterate back through the matching hooks and copy them into
3815 : : * an array which won’t change when we unlock to call the
3816 : : * user-provided hook functions.
3817 : : * These functions may change hook configuration for this signal,
3818 : : * add / remove signal handlers, etc.
3819 : : */
3820 : 28 : if G_UNLIKELY (n_emission_hooks > 0)
3821 : : {
3822 : : guint8 static_hook_returns[G_N_ELEMENTS (static_emission_hooks)];
3823 : 20 : GHook **emission_hooks = NULL;
3824 : 20 : guint8 *hook_returns = NULL;
3825 : :
3826 : 20 : if G_LIKELY (n_emission_hooks <= G_N_ELEMENTS (static_emission_hooks))
3827 : : {
3828 : 14 : emission_hooks = static_emission_hooks;
3829 : 14 : hook_returns = static_hook_returns;
3830 : 7 : }
3831 : : else
3832 : : {
3833 : 6 : emission_hooks = g_newa (GHook *, n_emission_hooks);
3834 : 6 : hook_returns = g_newa (guint8, n_emission_hooks);
3835 : :
3836 : : /* We can't just memcpy the ones we have in the static array,
3837 : : * to the alloca()'d one because otherwise we'd get an invalid
3838 : : * ID assertion during unref
3839 : : */
3840 : 6 : i = 0;
3841 : 36 : for (hook = g_hook_first_valid (node->emission_hooks, may_recurse);
3842 : 66 : hook != NULL;
3843 : 60 : hook = g_hook_next_valid (node->emission_hooks, hook, may_recurse))
3844 : : {
3845 : 60 : SignalHook *signal_hook = SIGNAL_HOOK (hook);
3846 : :
3847 : 60 : if (!signal_hook->detail || signal_hook->detail == detail)
3848 : : {
3849 : 60 : if (i < G_N_ELEMENTS (static_emission_hooks))
3850 : : {
3851 : 18 : emission_hooks[i] = g_steal_pointer (&static_emission_hooks[i]);
3852 : 18 : g_assert (emission_hooks[i] == hook);
3853 : 9 : }
3854 : : else
3855 : : {
3856 : 42 : emission_hooks[i] = g_hook_ref (node->emission_hooks, hook);
3857 : : }
3858 : :
3859 : 60 : i += 1;
3860 : 30 : }
3861 : 30 : }
3862 : :
3863 : 6 : g_assert (i == n_emission_hooks);
3864 : : }
3865 : :
3866 : 20 : SIGNAL_UNLOCK ();
3867 : :
3868 : 94 : for (i = 0; i < n_emission_hooks; ++i)
3869 : : {
3870 : : GSignalEmissionHook hook_func;
3871 : : gboolean need_destroy;
3872 : : guint old_flags;
3873 : :
3874 : 74 : hook = emission_hooks[i];
3875 : 74 : hook_func = (GSignalEmissionHook) hook->func;
3876 : :
3877 : 74 : old_flags = g_atomic_int_or (&hook->flags, G_HOOK_FLAG_IN_CALL);
3878 : 111 : need_destroy = !hook_func (&emission.ihint, n_params,
3879 : 37 : instance_and_params, hook->data);
3880 : :
3881 : 74 : if (!(old_flags & G_HOOK_FLAG_IN_CALL))
3882 : : {
3883 : 111 : g_atomic_int_compare_and_exchange ((gint *) &hook->flags,
3884 : 37 : (gint) old_flags | G_HOOK_FLAG_IN_CALL,
3885 : 37 : (gint) old_flags);
3886 : 37 : }
3887 : :
3888 : 74 : hook_returns[i] = !!need_destroy;
3889 : 37 : }
3890 : :
3891 : 20 : SIGNAL_LOCK ();
3892 : :
3893 : 94 : for (i = 0; i < n_emission_hooks; i++)
3894 : : {
3895 : 74 : hook = emission_hooks[i];
3896 : :
3897 : 74 : g_hook_unref (node->emission_hooks, hook);
3898 : :
3899 : 74 : if (hook_returns[i])
3900 : 22 : g_hook_destroy_link (node->emission_hooks, hook);
3901 : 37 : }
3902 : 10 : }
3903 : :
3904 : 28 : if (emission.state == EMISSION_RESTART)
3905 : 0 : goto EMIT_RESTART;
3906 : 14 : }
3907 : :
3908 : 24083477 : if (handler_list)
3909 : : {
3910 : 15983236 : Handler *handler = handler_list;
3911 : :
3912 : 15983236 : emission.state = EMISSION_RUN;
3913 : 15983236 : handler_ref (handler);
3914 : 9574255 : do
3915 : : {
3916 : : Handler *tmp;
3917 : :
3918 : 16643060 : if (handler->after)
3919 : : {
3920 : 46 : handler_unref_R (signal_id, instance, handler_list);
3921 : 46 : handler_list = handler;
3922 : 46 : break;
3923 : : }
3924 : 16643014 : else if (!handler->block_count && (!handler->detail || handler->detail == detail) &&
3925 : 16324180 : handler->sequential_number < max_sequential_handler_number)
3926 : : {
3927 : 15985524 : SIGNAL_UNLOCK ();
3928 : 15985524 : return_accu = maybe_init_accumulator_unlocked (node, emission_return, &accu);
3929 : 25560902 : g_closure_invoke (handler->closure,
3930 : 9575378 : return_accu,
3931 : 9575378 : n_params,
3932 : 9575378 : instance_and_params,
3933 : 9575378 : &emission.ihint);
3934 : 15985518 : if (!accumulate (&emission.ihint, emission_return, &accu, accumulator) &&
3935 : 356 : emission.state == EMISSION_RUN)
3936 : 356 : emission.state = EMISSION_STOP;
3937 : 15985518 : SIGNAL_LOCK ();
3938 : 15985518 : return_value_altered = TRUE;
3939 : :
3940 : 15985518 : tmp = emission.state == EMISSION_RUN ? handler->next : NULL;
3941 : 9575378 : }
3942 : : else
3943 : 657490 : tmp = handler->next;
3944 : :
3945 : 16643008 : if (tmp)
3946 : 659824 : handler_ref (tmp);
3947 : 16643008 : handler_unref_R (signal_id, instance, handler_list);
3948 : 16643008 : handler_list = handler;
3949 : 16643008 : handler = tmp;
3950 : 9914033 : }
3951 : 16643008 : while (handler);
3952 : :
3953 : 15983230 : if (emission.state == EMISSION_STOP)
3954 : 360 : goto EMIT_CLEANUP;
3955 : 15982870 : else if (emission.state == EMISSION_RESTART)
3956 : 170975 : goto EMIT_RESTART;
3957 : 9446531 : }
3958 : :
3959 : 23912136 : emission.ihint.run_type &= (unsigned) ~G_SIGNAL_RUN_FIRST;
3960 : 23912136 : emission.ihint.run_type |= G_SIGNAL_RUN_LAST;
3961 : :
3962 : 23912136 : if ((node->flags & G_SIGNAL_RUN_LAST) && class_closure)
3963 : : {
3964 : 13421412 : emission.state = EMISSION_RUN;
3965 : :
3966 : 13421412 : emission.chain_type = G_TYPE_FROM_INSTANCE (instance);
3967 : 13421412 : SIGNAL_UNLOCK ();
3968 : 13421412 : return_accu = maybe_init_accumulator_unlocked (node, emission_return, &accu);
3969 : 22490183 : g_closure_invoke (class_closure,
3970 : 9068771 : return_accu,
3971 : 9068771 : n_params,
3972 : 9068771 : instance_and_params,
3973 : 9068771 : &emission.ihint);
3974 : 13421412 : if (!accumulate (&emission.ihint, emission_return, &accu, accumulator) &&
3975 : 5 : emission.state == EMISSION_RUN)
3976 : 5 : emission.state = EMISSION_STOP;
3977 : 13421412 : SIGNAL_LOCK ();
3978 : 13421412 : emission.chain_type = G_TYPE_NONE;
3979 : 13421412 : return_value_altered = TRUE;
3980 : :
3981 : 13421412 : if (emission.state == EMISSION_STOP)
3982 : 5 : goto EMIT_CLEANUP;
3983 : 13421407 : else if (emission.state == EMISSION_RESTART)
3984 : 0 : goto EMIT_RESTART;
3985 : 9068768 : }
3986 : :
3987 : 33358659 : if (handler_list)
3988 : : {
3989 : 15811893 : Handler *handler = handler_list;
3990 : :
3991 : 15811893 : emission.state = EMISSION_RUN;
3992 : 15811893 : handler_ref (handler);
3993 : 9446530 : do
3994 : : {
3995 : : Handler *tmp;
3996 : :
3997 : 15811893 : if (handler->after && !handler->block_count && (!handler->detail || handler->detail == detail) &&
3998 : 44 : handler->sequential_number < max_sequential_handler_number)
3999 : : {
4000 : 44 : SIGNAL_UNLOCK ();
4001 : 44 : return_accu = maybe_init_accumulator_unlocked (node, emission_return, &accu);
4002 : 65 : g_closure_invoke (handler->closure,
4003 : 21 : return_accu,
4004 : 21 : n_params,
4005 : 21 : instance_and_params,
4006 : 21 : &emission.ihint);
4007 : 44 : if (!accumulate (&emission.ihint, emission_return, &accu, accumulator) &&
4008 : 4 : emission.state == EMISSION_RUN)
4009 : 4 : emission.state = EMISSION_STOP;
4010 : 44 : SIGNAL_LOCK ();
4011 : 44 : return_value_altered = TRUE;
4012 : :
4013 : 44 : tmp = emission.state == EMISSION_RUN ? handler->next : NULL;
4014 : 21 : }
4015 : : else
4016 : 15811849 : tmp = handler->next;
4017 : :
4018 : 15811893 : if (tmp)
4019 : 0 : handler_ref (tmp);
4020 : 15811893 : handler_unref_R (signal_id, instance, handler);
4021 : 15811893 : handler = tmp;
4022 : 9446530 : }
4023 : 15811893 : while (handler);
4024 : :
4025 : 15811893 : if (emission.state == EMISSION_STOP)
4026 : 4 : goto EMIT_CLEANUP;
4027 : 15811889 : else if (emission.state == EMISSION_RESTART)
4028 : 0 : goto EMIT_RESTART;
4029 : 9446528 : }
4030 : :
4031 : 8645305 : EMIT_CLEANUP:
4032 : :
4033 : 23912496 : emission.ihint.run_type &= (unsigned) ~G_SIGNAL_RUN_LAST;
4034 : 23912496 : emission.ihint.run_type |= G_SIGNAL_RUN_CLEANUP;
4035 : :
4036 : 23912496 : if ((node->flags & G_SIGNAL_RUN_CLEANUP) && class_closure)
4037 : : {
4038 : 8 : gboolean need_unset = FALSE;
4039 : :
4040 : 8 : emission.state = EMISSION_STOP;
4041 : :
4042 : 8 : emission.chain_type = G_TYPE_FROM_INSTANCE (instance);
4043 : 8 : SIGNAL_UNLOCK ();
4044 : 8 : if (node->return_type != G_TYPE_NONE && !accumulator)
4045 : : {
4046 : 0 : g_value_init (&accu, node->return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE);
4047 : 0 : need_unset = TRUE;
4048 : 0 : }
4049 : 12 : g_closure_invoke (class_closure,
4050 : 8 : node->return_type != G_TYPE_NONE ? &accu : NULL,
4051 : 4 : n_params,
4052 : 4 : instance_and_params,
4053 : 4 : &emission.ihint);
4054 : 8 : if (!accumulate (&emission.ihint, emission_return, &accu, accumulator) &&
4055 : 0 : emission.state == EMISSION_RUN)
4056 : 0 : emission.state = EMISSION_STOP;
4057 : 8 : if (need_unset)
4058 : 0 : g_value_unset (&accu);
4059 : 8 : SIGNAL_LOCK ();
4060 : 8 : return_value_altered = TRUE;
4061 : :
4062 : 8 : emission.chain_type = G_TYPE_NONE;
4063 : :
4064 : 8 : if (emission.state == EMISSION_RESTART)
4065 : 0 : goto EMIT_RESTART;
4066 : 4 : }
4067 : :
4068 : 23912496 : if (handler_list)
4069 : 15812255 : handler_unref_R (signal_id, instance, handler_list);
4070 : :
4071 : 23912496 : emission_pop (&emission);
4072 : 23912496 : if (accumulator)
4073 : 940 : g_value_unset (&accu);
4074 : :
4075 : 8645656 : TRACE(GOBJECT_SIGNAL_EMIT_END(node->signal_id, detail, instance, G_TYPE_FROM_INSTANCE (instance)));
4076 : :
4077 : 23912496 : return return_value_altered;
4078 : 15517323 : }
4079 : :
4080 : : static void
4081 : 10759 : add_invalid_closure_notify (Handler *handler,
4082 : : gpointer instance)
4083 : : {
4084 : 10759 : g_closure_add_invalidate_notifier (handler->closure, instance, invalid_closure_notify);
4085 : 10759 : handler->has_invalid_closure_notify = 1;
4086 : 10759 : }
4087 : :
4088 : : static void
4089 : 628763 : remove_invalid_closure_notify (Handler *handler,
4090 : : gpointer instance)
4091 : : {
4092 : 628763 : if (handler->has_invalid_closure_notify)
4093 : : {
4094 : 10638 : g_closure_remove_invalidate_notifier (handler->closure, instance, invalid_closure_notify);
4095 : 10638 : handler->has_invalid_closure_notify = 0;
4096 : 360 : }
4097 : 628763 : }
4098 : :
4099 : : static void
4100 : 114 : invalid_closure_notify (gpointer instance,
4101 : : GClosure *closure)
4102 : : {
4103 : : Handler *handler;
4104 : : guint signal_id;
4105 : :
4106 : 114 : SIGNAL_LOCK ();
4107 : :
4108 : 114 : handler = handler_lookup_by_closure (instance, closure, &signal_id);
4109 : : /* See https://bugzilla.gnome.org/show_bug.cgi?id=730296 for discussion about this... */
4110 : 114 : g_assert (handler != NULL);
4111 : 114 : g_assert (handler->closure == closure);
4112 : :
4113 : 114 : g_hash_table_remove (g_handlers, handler);
4114 : 114 : handler->sequential_number = 0;
4115 : 114 : handler->block_count = 1;
4116 : 114 : handler_unref_R (signal_id, instance, handler);
4117 : :
4118 : 114 : SIGNAL_UNLOCK ();
4119 : 114 : }
4120 : :
4121 : : static const gchar*
4122 : 4 : type_debug_name (GType type)
4123 : : {
4124 : 4 : if (type)
4125 : : {
4126 : 4 : const char *name = g_type_name (type & ~G_SIGNAL_TYPE_STATIC_SCOPE);
4127 : 4 : return name ? name : "<unknown>";
4128 : : }
4129 : : else
4130 : 0 : return "<invalid>";
4131 : 2 : }
4132 : :
4133 : : /**
4134 : : * g_signal_accumulator_true_handled:
4135 : : * @ihint: standard #GSignalAccumulator parameter
4136 : : * @return_accu: standard #GSignalAccumulator parameter
4137 : : * @handler_return: standard #GSignalAccumulator parameter
4138 : : * @dummy: standard #GSignalAccumulator parameter
4139 : : *
4140 : : * A predefined #GSignalAccumulator for signals that return a
4141 : : * boolean values. The behavior that this accumulator gives is
4142 : : * that a return of %TRUE stops the signal emission: no further
4143 : : * callbacks will be invoked, while a return of %FALSE allows
4144 : : * the emission to continue. The idea here is that a %TRUE return
4145 : : * indicates that the callback handled the signal, and no further
4146 : : * handling is needed.
4147 : : *
4148 : : * Since: 2.4
4149 : : *
4150 : : * Returns: standard #GSignalAccumulator result
4151 : : */
4152 : : gboolean
4153 : 944 : g_signal_accumulator_true_handled (GSignalInvocationHint *ihint,
4154 : : GValue *return_accu,
4155 : : const GValue *handler_return,
4156 : : gpointer dummy)
4157 : : {
4158 : : gboolean continue_emission;
4159 : : gboolean signal_handled;
4160 : :
4161 : 944 : signal_handled = g_value_get_boolean (handler_return);
4162 : 944 : g_value_set_boolean (return_accu, signal_handled);
4163 : 944 : continue_emission = !signal_handled;
4164 : :
4165 : 944 : return continue_emission;
4166 : : }
4167 : :
4168 : : /**
4169 : : * g_signal_accumulator_first_wins:
4170 : : * @ihint: standard #GSignalAccumulator parameter
4171 : : * @return_accu: standard #GSignalAccumulator parameter
4172 : : * @handler_return: standard #GSignalAccumulator parameter
4173 : : * @dummy: standard #GSignalAccumulator parameter
4174 : : *
4175 : : * A predefined #GSignalAccumulator for signals intended to be used as a
4176 : : * hook for application code to provide a particular value. Usually
4177 : : * only one such value is desired and multiple handlers for the same
4178 : : * signal don't make much sense (except for the case of the default
4179 : : * handler defined in the class structure, in which case you will
4180 : : * usually want the signal connection to override the class handler).
4181 : : *
4182 : : * This accumulator will use the return value from the first signal
4183 : : * handler that is run as the return value for the signal and not run
4184 : : * any further handlers (ie: the first handler "wins").
4185 : : *
4186 : : * Returns: standard #GSignalAccumulator result
4187 : : *
4188 : : * Since: 2.28
4189 : : **/
4190 : : gboolean
4191 : 10 : g_signal_accumulator_first_wins (GSignalInvocationHint *ihint,
4192 : : GValue *return_accu,
4193 : : const GValue *handler_return,
4194 : : gpointer dummy)
4195 : : {
4196 : 10 : g_value_copy (handler_return, return_accu);
4197 : 10 : return FALSE;
4198 : : }
4199 : :
4200 : : /**
4201 : : * g_clear_signal_handler:
4202 : : * @handler_id_ptr: A pointer to a handler ID (of type #gulong) of the handler to be disconnected.
4203 : : * @instance: (type GObject.Object): The instance to remove the signal handler from.
4204 : : * This pointer may be %NULL or invalid, if the handler ID is zero.
4205 : : *
4206 : : * Disconnects a handler from @instance so it will not be called during
4207 : : * any future or currently ongoing emissions of the signal it has been
4208 : : * connected to. The @handler_id_ptr is then set to zero, which is never a valid handler ID value (see g_signal_connect()).
4209 : : *
4210 : : * If the handler ID is 0 then this function does nothing.
4211 : : *
4212 : : * There is also a macro version of this function so that the code
4213 : : * will be inlined.
4214 : : *
4215 : : * Since: 2.62
4216 : : */
4217 : : void
4218 : 0 : (g_clear_signal_handler) (gulong *handler_id_ptr,
4219 : : gpointer instance)
4220 : : {
4221 : 0 : g_return_if_fail (handler_id_ptr != NULL);
4222 : :
4223 : : #ifndef g_clear_signal_handler
4224 : : #error g_clear_signal_handler() macro is not defined
4225 : : #endif
4226 : :
4227 : 0 : g_clear_signal_handler (handler_id_ptr, instance);
4228 : 0 : }
|