LCOV - code coverage report
Current view: top level - gobject - gsignal.c (source / functions) Coverage Total Hit
Test: unnamed Lines: 87.5 % 1494 1307
Test Date: 2025-11-11 05:25:45 Functions: 96.5 % 85 82
Branches: - 0 0

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

Generated by: LCOV version 2.0-1