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