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

Generated by: LCOV version 2.0-1