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