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