LCOV - code coverage report
Current view: top level - glib/gobject - gsignal.c (source / functions) Hit Total Coverage
Test: unnamed Lines: 1307 1494 87.5 %
Date: 2024-06-11 05:24:59 Functions: 82 85 96.5 %
Branches: 702 1020 68.8 %

           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                 :   46609921 : LOOKUP_SIGNAL_NODE (guint signal_id)
     247                 :            : {
     248         [ +  - ]:   46609921 :   if (signal_id < g_n_signal_nodes)
     249                 :   46609921 :     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                 :       3614 : is_canonical (const gchar *key)
     275                 :            : {
     276                 :       3614 :   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                 :       1812 : 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         [ -  + ]:       1812 :   if (g_str_equal (name, "-gtk-private-changed"))
     298                 :          0 :     return TRUE;
     299                 :            : 
     300                 :       1812 :   return g_param_spec_is_valid_name (name);
     301                 :            : }
     302                 :            : 
     303                 :            : static inline guint
     304                 :     540409 : signal_id_lookup (const gchar *name,
     305                 :            :                   GType  itype)
     306                 :            : {
     307                 :            :   GQuark quark;
     308                 :     540409 :   GType *ifaces, type = itype;
     309                 :            :   SignalKey key;
     310                 :            :   guint n_ifaces;
     311                 :            : 
     312                 :     540409 :   quark = g_quark_try_string (name);
     313                 :     540409 :   key.quark = quark;
     314                 :            : 
     315                 :            :   /* try looking up signals for this type and its ancestors */
     316                 :            :   do
     317                 :            :     {
     318                 :            :       SignalKey *signal_key;
     319                 :            :       
     320                 :     948540 :       key.itype = type;
     321                 :     948540 :       signal_key = g_bsearch_array_lookup (g_signal_key_bsa, &g_signal_key_bconfig, &key);
     322                 :            :       
     323         [ +  + ]:     948540 :       if (signal_key)
     324                 :     137954 :         return signal_key->signal_id;
     325                 :            :       
     326                 :     810586 :       type = g_type_parent (type);
     327                 :            :     }
     328         [ +  + ]:     810586 :   while (type);
     329                 :            : 
     330                 :            :   /* no luck, try interfaces it exports */
     331                 :     402455 :   ifaces = g_type_interfaces (itype, &n_ifaces);
     332         [ +  + ]:     804571 :   while (n_ifaces--)
     333                 :            :     {
     334                 :            :       SignalKey *signal_key;
     335                 :            : 
     336                 :     802760 :       key.itype = ifaces[n_ifaces];
     337                 :     802760 :       signal_key = g_bsearch_array_lookup (g_signal_key_bsa, &g_signal_key_bconfig, &key);
     338                 :            : 
     339         [ +  + ]:     802760 :       if (signal_key)
     340                 :            :         {
     341                 :     400644 :           g_free (ifaces);
     342                 :     400644 :           return signal_key->signal_id;
     343                 :            :         }
     344                 :            :     }
     345                 :       1811 :   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         [ +  + ]:       1811 :   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                 :       1808 :   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                 :   42810485 : handler_lists_cmp (gconstpointer node1,
     376                 :            :                    gconstpointer node2)
     377                 :            : {
     378                 :   42810485 :   const HandlerList *hlist1 = node1, *hlist2 = node2;
     379                 :            :   
     380   [ +  +  +  + ]:   42810485 :   return G_BSEARCH_ARRAY_CMP (hlist1->signal_id, hlist2->signal_id);
     381                 :            : }
     382                 :            : 
     383                 :            : static inline HandlerList*
     384                 :     536175 : handler_list_ensure (guint    signal_id,
     385                 :            :                      gpointer instance)
     386                 :            : {
     387                 :     536175 :   GBSearchArray *hlbsa = g_hash_table_lookup (g_handler_list_bsa_ht, instance);
     388                 :            :   HandlerList key;
     389                 :            :   
     390                 :     536175 :   key.signal_id = signal_id;
     391                 :     536175 :   key.handlers    = NULL;
     392                 :     536175 :   key.tail_before = NULL;
     393                 :     536175 :   key.tail_after  = NULL;
     394         [ +  + ]:     536175 :   if (!hlbsa)
     395                 :            :     {
     396                 :     107082 :       hlbsa = g_bsearch_array_create (&g_signal_hlbsa_bconfig);
     397                 :            :     }
     398                 :     536175 :   hlbsa = g_bsearch_array_insert (hlbsa, &g_signal_hlbsa_bconfig, &key);
     399                 :     536175 :   g_hash_table_insert (g_handler_list_bsa_ht, instance, hlbsa);
     400                 :     536175 :   return g_bsearch_array_lookup (hlbsa, &g_signal_hlbsa_bconfig, &key);
     401                 :            : }
     402                 :            : 
     403                 :            : static inline HandlerList*
     404                 :   32939671 : handler_list_lookup (guint    signal_id,
     405                 :            :                      gpointer instance)
     406                 :            : {
     407                 :   32939671 :   GBSearchArray *hlbsa = g_hash_table_lookup (g_handler_list_bsa_ht, instance);
     408                 :            :   HandlerList key;
     409                 :            :   
     410                 :   32939671 :   key.signal_id = signal_id;
     411                 :            :   
     412         [ +  + ]:   32939671 :   return hlbsa ? g_bsearch_array_lookup (hlbsa, &g_signal_hlbsa_bconfig, &key) : NULL;
     413                 :            : }
     414                 :            : 
     415                 :            : static guint
     416                 :    1607415 : handler_hash (gconstpointer key)
     417                 :            : {
     418                 :    1607415 :   return (guint)((Handler*)key)->sequential_number;
     419                 :            : }
     420                 :            : 
     421                 :            : static gboolean
     422                 :    1071324 : handler_equal (gconstpointer a, gconstpointer b)
     423                 :            : {
     424                 :    1071324 :   Handler *ha = (Handler *)a;
     425                 :    1071324 :   Handler *hb = (Handler *)b;
     426         [ +  + ]:    2142542 :   return (ha->sequential_number == hb->sequential_number) &&
     427         [ +  + ]:    1071218 :       (ha->instance  == hb->instance);
     428                 :            : }
     429                 :            : 
     430                 :            : static Handler*
     431                 :     535453 : handler_lookup (gpointer  instance,
     432                 :            :                 gulong    handler_id,
     433                 :            :                 GClosure *closure,
     434                 :            :                 guint    *signal_id_p)
     435                 :            : {
     436                 :            :   GBSearchArray *hlbsa;
     437                 :            : 
     438         [ +  + ]:     535453 :   if (handler_id)
     439                 :            :     {
     440                 :            :       Handler key;
     441                 :     535395 :       key.sequential_number = handler_id;
     442                 :     535395 :       key.instance = instance;
     443                 :     535395 :       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                 :     402033 : handler_match_prepend (HandlerMatch *list,
     474                 :            :                        Handler      *handler,
     475                 :            :                        guint         signal_id)
     476                 :            : {
     477                 :            :   HandlerMatch *node;
     478                 :            :   
     479                 :     402033 :   node = g_slice_new (HandlerMatch);
     480                 :     402033 :   node->handler = handler;
     481                 :     402033 :   node->next = list;
     482                 :     402033 :   node->signal_id = signal_id;
     483                 :     402033 :   handler_ref (handler);
     484                 :            :   
     485                 :     402033 :   return node;
     486                 :            : }
     487                 :            : static inline HandlerMatch*
     488                 :     402033 : handler_match_free1_R (HandlerMatch *node,
     489                 :            :                        gpointer      instance)
     490                 :            : {
     491                 :     402033 :   HandlerMatch *next = node->next;
     492                 :            :   
     493                 :     402033 :   handler_unref_R (node->signal_id, instance, node->handler);
     494                 :     402033 :   g_slice_free (HandlerMatch, node);
     495                 :            :   
     496                 :     402033 :   return next;
     497                 :            : }
     498                 :            : 
     499                 :            : static HandlerMatch*
     500                 :     402179 : 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                 :     402179 :   HandlerMatch *mlist = NULL;
     510                 :            :   
     511         [ +  + ]:     402179 :   if (mask & G_SIGNAL_MATCH_ID)
     512                 :            :     {
     513                 :        131 :       HandlerList *hlist = handler_list_lookup (signal_id, instance);
     514                 :            :       Handler *handler;
     515                 :        131 :       SignalNode *node = NULL;
     516                 :            :       
     517         [ +  + ]:        131 :       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                 :        131 :       mask = ~mask;
     525   [ +  +  +  + ]:        135 :       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                 :     402048 :       GBSearchArray *hlbsa = g_hash_table_lookup (g_handler_list_bsa_ht, instance);
     543                 :            :       
     544                 :     402048 :       mask = ~mask;
     545         [ +  + ]:     402048 :       if (hlbsa)
     546                 :            :         {
     547                 :            :           guint i;
     548                 :            :           
     549         [ +  + ]:    2004792 :           for (i = 0; i < hlbsa->n_nodes; i++)
     550                 :            :             {
     551                 :    1602762 :               HandlerList *hlist = g_bsearch_array_get_nth (hlbsa, &g_signal_hlbsa_bconfig, i);
     552                 :    1602762 :               SignalNode *node = NULL;
     553                 :            :               Handler *handler;
     554                 :            :               
     555         [ +  + ]:    1602762 :               if (!(mask & G_SIGNAL_MATCH_FUNC))
     556                 :            :                 {
     557                 :    1602754 :                   node = LOOKUP_SIGNAL_NODE (hlist->signal_id);
     558         [ -  + ]:    1602754 :                   if (!node->c_marshaller)
     559                 :          0 :                     continue;
     560                 :            :                 }
     561                 :            :               
     562         [ +  + ]:    3129790 :               for (handler = hlist->handlers; handler; handler = handler->next)
     563         [ +  - ]:    1527028 :                 if (handler->sequential_number &&
     564   [ -  +  -  - ]:    1527028 :                     ((mask & G_SIGNAL_MATCH_DETAIL) || handler->detail == detail) &&
     565   [ -  +  -  - ]:    1527028 :                     ((mask & G_SIGNAL_MATCH_CLOSURE) || handler->closure == closure) &&
     566   [ +  +  +  + ]:    1527028 :                     ((mask & G_SIGNAL_MATCH_DATA) || handler->closure->data == data) &&
     567   [ -  +  -  - ]:    1002241 :                     ((mask & G_SIGNAL_MATCH_UNBLOCKED) || handler->block_count == 0) &&
     568   [ +  +  +  - ]:    1002241 :                     ((mask & G_SIGNAL_MATCH_FUNC) || (handler->closure->marshal == node->c_marshaller &&
     569         [ +  - ]:    1002233 :                                                       G_REAL_CLOSURE (handler->closure)->meta_marshal == NULL &&
     570         [ +  + ]:    1002233 :                                                       ((GCClosure*) handler->closure)->callback == func)))
     571                 :            :                   {
     572                 :     401951 :                     mlist = handler_match_prepend (mlist, handler, hlist->signal_id);
     573         [ -  + ]:     401951 :                     if (one_and_only)
     574                 :          0 :                       return mlist;
     575                 :            :                   }
     576                 :            :             }
     577                 :            :         }
     578                 :            :     }
     579                 :            :   
     580                 :     402101 :   return mlist;
     581                 :            : }
     582                 :            : 
     583                 :            : static inline Handler*
     584                 :     536175 : handler_new (guint signal_id, gpointer instance, gboolean after)
     585                 :            : {
     586                 :     536175 :   Handler *handler = g_slice_new (Handler);
     587                 :            : #ifndef G_DISABLE_CHECKS
     588         [ -  + ]:     536175 :   if (g_handler_sequential_number < 1)
     589                 :          0 :     g_error (G_STRLOC ": handler id overflow, %s", REPORT_BUG);
     590                 :            : #endif
     591                 :            :   
     592                 :     536175 :   handler->sequential_number = g_handler_sequential_number++;
     593                 :     536175 :   handler->prev = NULL;
     594                 :     536175 :   handler->next = NULL;
     595                 :     536175 :   handler->detail = 0;
     596                 :     536175 :   handler->signal_id = signal_id;
     597                 :     536175 :   handler->instance = instance;
     598                 :     536175 :   handler->ref_count = 1;
     599                 :     536175 :   handler->block_count = 0;
     600                 :     536175 :   handler->after = after != FALSE;
     601                 :     536175 :   handler->closure = NULL;
     602                 :     536175 :   handler->has_invalid_closure_notify = 0;
     603                 :            : 
     604                 :     536175 :   g_hash_table_add (g_handlers, handler);
     605                 :            :   
     606                 :     536175 :   return handler;
     607                 :            : }
     608                 :            : 
     609                 :            : static inline void
     610                 :   33260594 : handler_ref (Handler *handler)
     611                 :            : {
     612                 :   33260594 :   g_return_if_fail (handler->ref_count > 0);
     613                 :            :   
     614                 :   33260594 :   handler->ref_count++;
     615                 :            : }
     616                 :            : 
     617                 :            : static inline void
     618                 :   33796425 : handler_unref_R (guint    signal_id,
     619                 :            :                  gpointer instance,
     620                 :            :                  Handler *handler)
     621                 :            : {
     622                 :   33796425 :   g_return_if_fail (handler->ref_count > 0);
     623                 :            : 
     624                 :   33796425 :   handler->ref_count--;
     625                 :            : 
     626         [ +  + ]:   33796425 :   if (G_UNLIKELY (handler->ref_count == 0))
     627                 :            :     {
     628                 :     535839 :       HandlerList *hlist = NULL;
     629                 :            : 
     630         [ +  + ]:     535839 :       if (handler->next)
     631                 :       5353 :         handler->next->prev = handler->prev;
     632         [ +  + ]:     535839 :       if (handler->prev)    /* watch out for g_signal_handlers_destroy()! */
     633                 :      12321 :         handler->prev->next = handler->next;
     634                 :            :       else
     635                 :            :         {
     636                 :     523518 :           hlist = handler_list_lookup (signal_id, instance);
     637                 :     523518 :           g_assert (hlist != NULL);
     638                 :     523518 :           hlist->handlers = handler->next;
     639                 :            :         }
     640                 :            : 
     641         [ +  + ]:     535839 :       if (instance)
     642                 :            :         {
     643                 :            :           /*  check if we are removing the handler pointed to by tail_before  */
     644   [ +  +  +  +  :     535052 :           if (!handler->after && (!handler->next || handler->next->after))
                   +  + ]
     645                 :            :             {
     646         [ +  + ]:     529698 :               if (!hlist)
     647                 :      10733 :                 hlist = handler_list_lookup (signal_id, instance);
     648         [ +  - ]:     529698 :               if (hlist)
     649                 :            :                 {
     650                 :     529698 :                   g_assert (hlist->tail_before == handler); /* paranoid */
     651                 :     529698 :                   hlist->tail_before = handler->prev;
     652                 :            :                 }
     653                 :            :             }
     654                 :            : 
     655                 :            :           /*  check if we are removing the handler pointed to by tail_after  */
     656         [ +  + ]:     535052 :           if (!handler->next)
     657                 :            :             {
     658         [ +  + ]:     529699 :               if (!hlist)
     659                 :          2 :                 hlist = handler_list_lookup (signal_id, instance);
     660         [ +  - ]:     529699 :               if (hlist)
     661                 :            :                 {
     662                 :     529699 :                   g_assert (hlist->tail_after == handler); /* paranoid */
     663                 :     529699 :                   hlist->tail_after = handler->prev;
     664                 :            :                 }
     665                 :            :             }
     666                 :            :         }
     667                 :            : 
     668                 :     535839 :       SIGNAL_UNLOCK ();
     669                 :     535766 :       g_closure_unref (handler->closure);
     670                 :     535644 :       SIGNAL_LOCK ();
     671                 :     535839 :       g_slice_free (Handler, handler);
     672                 :            :     }
     673                 :            : }
     674                 :            : 
     675                 :            : static void
     676                 :     536175 : handler_insert (guint    signal_id,
     677                 :            :                 gpointer instance,
     678                 :            :                 Handler  *handler)
     679                 :            : {
     680                 :            :   HandlerList *hlist;
     681                 :            :   
     682                 :     536175 :   g_assert (handler->prev == NULL && handler->next == NULL); /* paranoid */
     683                 :            : 
     684                 :     536175 :   hlist = handler_list_ensure (signal_id, instance);
     685         [ +  + ]:     536175 :   if (!hlist->handlers)
     686                 :            :     {
     687                 :     520030 :       hlist->handlers = handler;
     688         [ +  + ]:     520030 :       if (!handler->after)
     689                 :     520029 :         hlist->tail_before = handler;
     690                 :            :     }
     691         [ +  + ]:      16145 :   else if (handler->after)
     692                 :            :     {
     693                 :         17 :       handler->prev = hlist->tail_after;
     694                 :         17 :       hlist->tail_after->next = handler;
     695                 :            :     }
     696                 :            :   else
     697                 :            :     {
     698         [ +  + ]:      16128 :       if (hlist->tail_before)
     699                 :            :         {
     700                 :      16126 :           handler->next = hlist->tail_before->next;
     701         [ +  + ]:      16126 :           if (handler->next)
     702                 :         28 :             handler->next->prev = handler;
     703                 :      16126 :           handler->prev = hlist->tail_before;
     704                 :      16126 :           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                 :      16128 :       hlist->tail_before = handler;
     714                 :            :     }
     715                 :            : 
     716         [ +  + ]:     536175 :   if (!handler->next)
     717                 :     536145 :     hlist->tail_after = handler;
     718                 :     536175 : }
     719                 :            : 
     720                 :            : static void
     721                 :        479 : node_update_single_va_closure (SignalNode *node)
     722                 :            : {
     723                 :        479 :   GClosure *closure = NULL;
     724                 :        479 :   gboolean is_after = FALSE;
     725                 :            : 
     726                 :            :   /* Fast path single-handler without boxing the arguments in GValues */
     727         [ +  + ]:        479 :   if (G_TYPE_IS_OBJECT (node->itype) &&
     728         [ +  + ]:        405 :       (node->flags & (G_SIGNAL_MUST_COLLECT)) == 0 &&
     729   [ +  +  +  + ]:        382 :       (node->emission_hooks == NULL || node->emission_hooks->hooks == NULL))
     730                 :            :     {
     731                 :            :       GSignalFlags run_type;
     732                 :            :       ClassClosure * cc; 
     733                 :        374 :       GBSearchArray *bsa = node->class_closure_bsa;
     734                 :            : 
     735   [ +  +  -  + ]:        374 :       if (bsa == NULL || bsa->n_nodes == 0)
     736                 :         26 :         closure = SINGLE_VA_CLOSURE_EMPTY_MAGIC;
     737         [ +  + ]:        348 :       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                 :        344 :           cc = g_bsearch_array_get_nth (bsa, &g_class_closure_bconfig, 0);
     742         [ +  - ]:        344 :           if (cc->instance_type == 0)
     743                 :            :             {
     744                 :        344 :               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   [ +  +  +  + ]:        344 :               if (run_type == G_SIGNAL_RUN_FIRST ||
     747                 :            :                   run_type == G_SIGNAL_RUN_LAST)
     748                 :            :                 {
     749                 :        339 :                   closure = cc->closure;
     750                 :        339 :                   is_after = (run_type == G_SIGNAL_RUN_LAST);
     751                 :            :                 }
     752                 :            :             }
     753                 :            :         }
     754                 :            :     }
     755                 :            : 
     756                 :        479 :   node->single_va_closure_is_valid = TRUE;
     757                 :        479 :   node->single_va_closure = closure;
     758                 :        479 :   node->single_va_closure_is_after = is_after;
     759                 :        479 : }
     760                 :            : 
     761                 :            : static inline void
     762                 :   19225016 : emission_push (Emission  *emission)
     763                 :            : {
     764                 :   19225016 :   emission->next = g_emissions;
     765                 :   19225016 :   g_emissions = emission;
     766                 :   19225016 : }
     767                 :            : 
     768                 :            : static inline void
     769                 :   19225008 : emission_pop (Emission  *emission)
     770                 :            : {
     771                 :   19225008 :   Emission *node, *last = NULL;
     772                 :            : 
     773         [ +  - ]:   19606038 :   for (node = g_emissions; node; last = node, node = last->next)
     774         [ +  + ]:   19606038 :     if (node == emission)
     775                 :            :       {
     776         [ +  + ]:   19225008 :         if (last)
     777                 :     345526 :           last->next = node->next;
     778                 :            :         else
     779                 :   18879482 :           g_emissions = node->next;
     780                 :   19225008 :         return;
     781                 :            :       }
     782                 :            :   g_assert_not_reached ();
     783                 :            : }
     784                 :            : 
     785                 :            : static inline Emission*
     786                 :    4897796 : emission_find (guint     signal_id,
     787                 :            :                GQuark    detail,
     788                 :            :                gpointer  instance)
     789                 :            : {
     790                 :            :   Emission *emission;
     791                 :            :   
     792         [ +  + ]:    6650705 :   for (emission = g_emissions; emission; emission = emission->next)
     793         [ +  + ]:    2055490 :     if (emission->instance == instance &&
     794         [ +  + ]:     302648 :         emission->ihint.signal_id == signal_id &&
     795         [ +  + ]:     302587 :         emission->ihint.detail == detail)
     796                 :     302581 :       return emission;
     797                 :    4595215 :   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                 :    7802646 : signal_key_cmp (gconstpointer node1,
     814                 :            :                 gconstpointer node2)
     815                 :            : {
     816                 :    7802646 :   const SignalKey *key1 = node1, *key2 = node2;
     817                 :            :   
     818         [ +  + ]:    7802646 :   if (key1->itype == key2->itype)
     819   [ +  +  +  + ]:    1344700 :     return G_BSEARCH_ARRAY_CMP (key1->quark, key2->quark);
     820                 :            :   else
     821   [ +  +  -  + ]:    6457946 :     return G_BSEARCH_ARRAY_CMP (key1->itype, key2->itype);
     822                 :            : }
     823                 :            : 
     824                 :            : void
     825                 :        537 : _g_signal_init (void)
     826                 :            : {
     827                 :        537 :   SIGNAL_LOCK ();
     828         [ +  - ]:        537 :   if (!g_n_signal_nodes)
     829                 :            :     {
     830                 :            :       /* setup handler list binary searchable array hash table (in german, that'd be one word ;) */
     831                 :        537 :       g_handler_list_bsa_ht = g_hash_table_new (g_direct_hash, NULL);
     832                 :        537 :       g_signal_key_bsa = g_bsearch_array_create (&g_signal_key_bconfig);
     833                 :            :       
     834                 :            :       /* invalid (0) signal_id */
     835                 :        537 :       g_n_signal_nodes = 1;
     836                 :        537 :       g_signal_nodes = g_renew (SignalNode*, g_signal_nodes, g_n_signal_nodes);
     837                 :        537 :       g_signal_nodes[0] = NULL;
     838                 :        537 :       g_handlers = g_hash_table_new (handler_hash, handler_equal);
     839                 :            :     }
     840                 :        537 :   SIGNAL_UNLOCK ();
     841                 :        537 : }
     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                 :     536300 : signal_parse_name (const gchar *name,
    1043                 :            :                    GType        itype,
    1044                 :            :                    GQuark      *detail_p,
    1045                 :            :                    gboolean     force_quark)
    1046                 :            : {
    1047                 :     536300 :   const gchar *colon = strchr (name, ':');
    1048                 :            :   guint signal_id;
    1049                 :            :   
    1050         [ +  + ]:     536300 :   if (!colon)
    1051                 :            :     {
    1052                 :     535931 :       signal_id = signal_id_lookup (name, itype);
    1053   [ +  +  +  - ]:     535931 :       if (signal_id && detail_p)
    1054                 :     535928 :         *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                 :     536298 :   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                 :       2309 : g_signal_lookup (const gchar *name,
    1214                 :            :                  GType        itype)
    1215                 :            : {
    1216                 :            :   guint signal_id;
    1217                 :       2309 :   g_return_val_if_fail (name != NULL, 0);
    1218                 :       2309 :   g_return_val_if_fail (G_TYPE_IS_INSTANTIATABLE (itype) || G_TYPE_IS_INTERFACE (itype), 0);
    1219                 :            :   
    1220                 :       2309 :   SIGNAL_LOCK ();
    1221                 :       2309 :   signal_id = signal_id_lookup (name, itype);
    1222                 :       2309 :   SIGNAL_UNLOCK ();
    1223         [ +  + ]:       2309 :   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                 :       2309 :   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                 :       1801 : 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                 :       1801 :   g_return_val_if_fail (signal_name != NULL, 0);
    1414                 :            :   
    1415                 :       1801 :   va_start (args, n_params);
    1416                 :            : 
    1417         [ +  + ]:       3541 :   signal_id = g_signal_new_valist (signal_name, itype, signal_flags,
    1418                 :       1740 :                                    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                 :       1801 :   va_end (args);
    1423                 :            : 
    1424                 :       1801 :   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                 :   18944886 : signal_find_class_closure (SignalNode *node,
    1499                 :            :                            GType       itype)
    1500                 :            : {
    1501                 :   18944886 :   GBSearchArray *bsa = node->class_closure_bsa;
    1502                 :            :   ClassClosure *cc;
    1503                 :            : 
    1504         [ +  + ]:   18944886 :   if (bsa)
    1505                 :            :     {
    1506                 :            :       ClassClosure key;
    1507                 :            : 
    1508                 :            :       /* cc->instance_type is 0 for default closure */
    1509                 :            : 
    1510         [ +  + ]:   18924179 :       if (g_bsearch_array_get_n_nodes (bsa) == 1)
    1511                 :            :         {
    1512                 :   18924144 :           cc = g_bsearch_array_get_nth (bsa, &g_class_closure_bconfig, 0);
    1513   [ +  -  +  - ]:   18924144 :           if (cc && cc->instance_type == 0) /* check for default closure */
    1514                 :   18924144 :             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                 :      20707 :     cc = NULL;
    1527                 :      20742 :   return cc;
    1528                 :            : }
    1529                 :            : 
    1530                 :            : static inline GClosure*
    1531                 :   18944811 : signal_lookup_closure (SignalNode    *node,
    1532                 :            :                        GTypeInstance *instance)
    1533                 :            : {
    1534                 :            :   ClassClosure *cc;
    1535                 :            : 
    1536                 :   18944811 :   cc = signal_find_class_closure (node, G_TYPE_FROM_INSTANCE (instance));
    1537         [ +  + ]:   18944811 :   return cc ? cc->closure : NULL;
    1538                 :            : }
    1539                 :            : 
    1540                 :            : static void
    1541                 :       1749 : signal_add_class_closure (SignalNode *node,
    1542                 :            :                           GType       itype,
    1543                 :            :                           GClosure   *closure)
    1544                 :            : {
    1545                 :            :   ClassClosure key;
    1546                 :            : 
    1547                 :       1749 :   node->single_va_closure_is_valid = FALSE;
    1548                 :            : 
    1549         [ +  + ]:       1749 :   if (!node->class_closure_bsa)
    1550                 :       1742 :     node->class_closure_bsa = g_bsearch_array_create (&g_class_closure_bconfig);
    1551                 :       1749 :   key.instance_type = itype;
    1552                 :       1749 :   key.closure = g_closure_ref (closure);
    1553                 :       1749 :   node->class_closure_bsa = g_bsearch_array_insert (node->class_closure_bsa,
    1554                 :            :                                                     &g_class_closure_bconfig,
    1555                 :            :                                                     &key);
    1556                 :       1749 :   g_closure_sink (closure);
    1557   [ +  -  +  -  :       1749 :   if (node->c_marshaller && closure && G_CLOSURE_NEEDS_MARSHAL (closure))
                   +  - ]
    1558                 :            :     {
    1559                 :       1749 :       g_closure_set_marshal (closure, node->c_marshaller);
    1560         [ +  + ]:       1749 :       if (node->va_marshaller)
    1561                 :        646 :         _g_closure_set_va_marshal (closure, node->va_marshaller);
    1562                 :            :     }
    1563                 :       1749 : }
    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                 :       1803 : 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                 :       1803 :   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                 :       1803 :   g_return_val_if_fail (signal_name != NULL, 0);
    1616                 :       1803 :   g_return_val_if_fail (g_signal_is_valid_name (signal_name), 0);
    1617                 :       1803 :   g_return_val_if_fail (G_TYPE_IS_INSTANTIATABLE (itype) || G_TYPE_IS_INTERFACE (itype), 0);
    1618         [ +  + ]:       1803 :   if (n_params)
    1619                 :       1570 :     g_return_val_if_fail (param_types != NULL, 0);
    1620                 :       1803 :   g_return_val_if_fail ((return_type & G_SIGNAL_TYPE_STATIC_SCOPE) == 0, 0);
    1621         [ +  + ]:       1803 :   if (return_type == (G_TYPE_NONE & ~G_SIGNAL_TYPE_STATIC_SCOPE))
    1622                 :       1369 :     g_return_val_if_fail (accumulator == NULL, 0);
    1623         [ +  + ]:       1803 :   if (!accumulator)
    1624                 :       1381 :     g_return_val_if_fail (accu_data == NULL, 0);
    1625                 :       1803 :   g_return_val_if_fail ((signal_flags & G_SIGNAL_ACCUMULATOR_FIRST_RUN) == 0, 0);
    1626                 :            : 
    1627         [ +  + ]:       1803 :   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                 :       1802 :       name = signal_name;
    1636                 :            :     }
    1637                 :            :   
    1638                 :       1803 :   SIGNAL_LOCK ();
    1639                 :            :   
    1640                 :       1803 :   signal_id = signal_id_lookup (name, itype);
    1641                 :       1803 :   node = LOOKUP_SIGNAL_NODE (signal_id);
    1642   [ -  +  -  - ]:       1803 :   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   [ -  +  -  - ]:       1803 :   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         [ +  + ]:       4798 :   for (i = 0; i < n_params; i++)
    1663         [ -  + ]:       2995 :     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   [ +  +  -  + ]:       1803 :   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         [ +  - ]:       1803 :   if (!node)
    1682                 :            :     {
    1683                 :            :       SignalKey key;
    1684                 :            :       
    1685                 :       1803 :       signal_id = g_n_signal_nodes++;
    1686                 :       1803 :       node = g_new (SignalNode, 1);
    1687                 :       1803 :       node->signal_id = signal_id;
    1688                 :       1803 :       g_signal_nodes = g_renew (SignalNode*, g_signal_nodes, g_n_signal_nodes);
    1689                 :       1803 :       g_signal_nodes[signal_id] = node;
    1690                 :       1803 :       node->itype = itype;
    1691                 :       1803 :       key.itype = itype;
    1692                 :       1803 :       key.signal_id = signal_id;
    1693                 :       1803 :       node->name = g_intern_string (name);
    1694                 :       1803 :       key.quark = g_quark_from_string (name);
    1695                 :       1803 :       g_signal_key_bsa = g_bsearch_array_insert (g_signal_key_bsa, &g_signal_key_bconfig, &key);
    1696                 :            : 
    1697                 :       1803 :       TRACE(GOBJECT_SIGNAL_NEW(signal_id, name, itype));
    1698                 :            :     }
    1699                 :       1803 :   node->destroyed = FALSE;
    1700                 :            : 
    1701                 :            :   /* setup reinitializable portion */
    1702                 :       1803 :   node->single_va_closure_is_valid = FALSE;
    1703                 :       1803 :   node->flags = signal_flags & G_SIGNAL_FLAGS_MASK;
    1704                 :       1803 :   node->n_params = n_params;
    1705                 :       1803 :   node->param_types = g_memdup2 (param_types, sizeof (GType) * n_params);
    1706                 :       1803 :   node->return_type = return_type;
    1707                 :       1803 :   node->class_closure_bsa = NULL;
    1708         [ +  + ]:       1803 :   if (accumulator)
    1709                 :            :     {
    1710                 :        422 :       node->accumulator = g_new (SignalAccumulator, 1);
    1711                 :        422 :       node->accumulator->func = accumulator;
    1712                 :        422 :       node->accumulator->data = accu_data;
    1713                 :            :     }
    1714                 :            :   else
    1715                 :       1381 :     node->accumulator = NULL;
    1716                 :            : 
    1717                 :       1803 :   builtin_c_marshaller = NULL;
    1718                 :       1803 :   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   [ +  +  +  + ]:       1803 :   if (n_params == 0 && return_type == G_TYPE_NONE)
    1723                 :            :     {
    1724                 :        206 :       builtin_c_marshaller = g_cclosure_marshal_VOID__VOID;
    1725                 :        206 :       builtin_va_marshaller = g_cclosure_marshal_VOID__VOIDv;
    1726                 :            :     }
    1727   [ +  +  +  + ]:       1597 :   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   [ +  +  -  + ]:        494 :       ADD_CHECK (BOOLEAN)
    1738   [ +  -  -  + ]:        472 :       ADD_CHECK (CHAR)
    1739   [ +  -  -  + ]:        472 :       ADD_CHECK (UCHAR)
    1740   [ +  +  -  + ]:        472 :       ADD_CHECK (INT)
    1741   [ +  -  -  + ]:        462 :       ADD_CHECK (UINT)
    1742   [ +  -  -  + ]:        462 :       ADD_CHECK (LONG)
    1743   [ +  -  -  + ]:        462 :       ADD_CHECK (ULONG)
    1744   [ +  -  +  + ]:        462 :       ADD_CHECK (ENUM)
    1745   [ +  -  -  + ]:        457 :       ADD_CHECK (FLAGS)
    1746   [ +  -  -  + ]:        457 :       ADD_CHECK (FLOAT)
    1747   [ +  +  -  + ]:        457 :       ADD_CHECK (DOUBLE)
    1748   [ +  +  -  + ]:        456 :       ADD_CHECK (STRING)
    1749   [ +  +  -  + ]:        412 :       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         [ +  + ]:       1803 :   if (c_marshaller == NULL)
    1757                 :            :     {
    1758         [ +  + ]:        691 :       if (builtin_c_marshaller)
    1759                 :            :         {
    1760                 :        670 :           c_marshaller = builtin_c_marshaller;
    1761                 :        670 :           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                 :       1112 :     va_marshaller = NULL;
    1771                 :            : 
    1772                 :       1803 :   node->c_marshaller = c_marshaller;
    1773                 :       1803 :   node->va_marshaller = va_marshaller;
    1774                 :       1803 :   node->emission_hooks = NULL;
    1775         [ +  + ]:       1803 :   if (class_closure)
    1776                 :       1742 :     signal_add_class_closure (node, 0, class_closure);
    1777                 :            : 
    1778                 :       1803 :   SIGNAL_UNLOCK ();
    1779                 :            : 
    1780                 :       1803 :   g_free (signal_name_copy);
    1781                 :            : 
    1782                 :       1803 :   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                 :        992 : g_signal_set_va_marshaller (guint              signal_id,
    1800                 :            :                             GType              instance_type,
    1801                 :            :                             GSignalCVaMarshaller va_marshaller)
    1802                 :            : {
    1803                 :            :   SignalNode *node;
    1804                 :            :   
    1805                 :        992 :   g_return_if_fail (signal_id > 0);
    1806                 :        992 :   g_return_if_fail (va_marshaller != NULL);
    1807                 :            :   
    1808                 :        992 :   SIGNAL_LOCK ();
    1809                 :        992 :   node = LOOKUP_SIGNAL_NODE (signal_id);
    1810         [ +  - ]:        992 :   if (node)
    1811                 :            :     {
    1812                 :        992 :       node->va_marshaller = va_marshaller;
    1813         [ +  + ]:        992 :       if (node->class_closure_bsa)
    1814                 :            :         {
    1815                 :        984 :           ClassClosure *cc = g_bsearch_array_get_nth (node->class_closure_bsa, &g_class_closure_bconfig, 0);
    1816         [ +  - ]:        984 :           if (cc->closure->marshal == node->c_marshaller)
    1817                 :        984 :             _g_closure_set_va_marshal (cc->closure, va_marshaller);
    1818                 :            :         }
    1819                 :            : 
    1820                 :        992 :       node->single_va_closure_is_valid = FALSE;
    1821                 :            :     }
    1822                 :            : 
    1823                 :        992 :   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                 :       1802 : 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                 :       1802 :   GType *param_types_heap = NULL;
    1871                 :            :   GType *param_types;
    1872                 :            :   guint i;
    1873                 :            :   guint signal_id;
    1874                 :            : 
    1875                 :       1802 :   param_types = param_types_stack;
    1876         [ +  + ]:       1802 :   if (n_params > 0)
    1877                 :            :     {
    1878         [ -  + ]:       1570 :       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         [ +  + ]:       4565 :       for (i = 0; i < n_params; i++)
    1885                 :       2995 :         param_types[i] = va_arg (args, GType);
    1886                 :            :     }
    1887                 :            : 
    1888                 :       1802 :   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                 :       1802 :   g_free (param_types_heap);
    1892                 :            : 
    1893                 :       1802 :   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                 :     535812 : node_check_deprecated (const SignalNode *node)
    2434                 :            : {
    2435                 :            :   static const gchar * g_enable_diagnostic = NULL;
    2436                 :            : 
    2437         [ +  + ]:     535812 :   if (G_UNLIKELY (!g_enable_diagnostic))
    2438                 :            :     {
    2439                 :        191 :       g_enable_diagnostic = g_getenv ("G_ENABLE_DIAGNOSTIC");
    2440         [ -  + ]:        191 :       if (!g_enable_diagnostic)
    2441                 :          0 :         g_enable_diagnostic = "0";
    2442                 :            :     }
    2443                 :            : 
    2444         [ +  + ]:     535812 :   if (g_enable_diagnostic[0] == '1')
    2445                 :            :     {
    2446         [ -  + ]:     535808 :       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                 :     535812 : }
    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                 :     535721 : 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                 :     535721 :   gulong handler_seq_no = 0;
    2485                 :     535721 :   GQuark detail = 0;
    2486                 :            :   GType itype;
    2487                 :            :   gboolean swapped, after;
    2488                 :            :   
    2489                 :     535721 :   g_return_val_if_fail (G_TYPE_CHECK_INSTANCE (instance), 0);
    2490                 :     535721 :   g_return_val_if_fail (detailed_signal != NULL, 0);
    2491                 :     535721 :   g_return_val_if_fail (c_handler != NULL, 0);
    2492                 :            : 
    2493                 :     535721 :   swapped = (connect_flags & G_CONNECT_SWAPPED) != FALSE;
    2494                 :     535721 :   after = (connect_flags & G_CONNECT_AFTER) != FALSE;
    2495                 :            : 
    2496                 :     535721 :   SIGNAL_LOCK ();
    2497                 :     535779 :   itype = G_TYPE_FROM_INSTANCE (instance);
    2498                 :     535779 :   signal_id = signal_parse_name (detailed_signal, itype, &detail, TRUE);
    2499         [ +  - ]:     535779 :   if (signal_id)
    2500                 :            :     {
    2501                 :     535779 :       SignalNode *node = LOOKUP_SIGNAL_NODE (signal_id);
    2502                 :            : 
    2503                 :     535779 :       node_check_deprecated (node);
    2504                 :            : 
    2505   [ +  +  -  + ]:     535779 :       if (detail && !(node->flags & G_SIGNAL_DETAILED))
    2506                 :          0 :         g_critical ("%s: signal '%s' does not support details", G_STRLOC, detailed_signal);
    2507   [ +  +  -  + ]:     535779 :       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                 :     535779 :           Handler *handler = handler_new (signal_id, instance, after);
    2513                 :            : 
    2514         [ +  + ]:     535779 :           if (G_TYPE_IS_OBJECT (node->itype))
    2515                 :     135264 :             _g_object_set_has_signal_handler ((GObject *) instance, signal_id);
    2516                 :            : 
    2517                 :     535779 :           handler_seq_no = handler->sequential_number;
    2518                 :     535779 :           handler->detail = detail;
    2519         [ +  + ]:     535779 :           handler->closure = g_closure_ref ((swapped ? g_cclosure_new_swap : g_cclosure_new) (c_handler, data, destroy_data));
    2520                 :     535779 :           g_closure_sink (handler->closure);
    2521                 :     535779 :           handler_insert (signal_id, instance, handler);
    2522   [ +  -  +  - ]:     535779 :           if (node->c_marshaller && G_CLOSURE_NEEDS_MARSHAL (handler->closure))
    2523                 :            :             {
    2524                 :     535779 :               g_closure_set_marshal (handler->closure, node->c_marshaller);
    2525         [ +  + ]:     535779 :               if (node->va_marshaller)
    2526                 :     535679 :                 _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                 :     535779 :   SIGNAL_UNLOCK ();
    2534                 :            : 
    2535                 :     535611 :   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                 :     133055 : g_signal_handler_disconnect (gpointer instance,
    2658                 :            :                              gulong   handler_id)
    2659                 :            : {
    2660                 :     133055 :   g_return_if_fail (G_TYPE_CHECK_INSTANCE (instance));
    2661                 :     133055 :   g_return_if_fail (handler_id > 0);
    2662                 :            :   
    2663                 :     133055 :   SIGNAL_LOCK ();
    2664                 :     133055 :   signal_handler_disconnect_unlocked (instance, handler_id);
    2665                 :     133055 :   SIGNAL_UNLOCK ();
    2666                 :            : }
    2667                 :            : 
    2668                 :            : static void
    2669                 :     535004 : signal_handler_disconnect_unlocked (gpointer instance,
    2670                 :            :                                     gulong   handler_id)
    2671                 :            : {
    2672                 :            :   Handler *handler;
    2673                 :            : 
    2674                 :     535004 :   handler = handler_lookup (instance, handler_id, 0, 0);
    2675         [ +  + ]:     535004 :   if (handler)
    2676                 :            :     {
    2677                 :     535001 :       g_hash_table_remove (g_handlers, handler);
    2678                 :     535001 :       handler->sequential_number = 0;
    2679                 :     535001 :       handler->block_count = 1;
    2680                 :     535001 :       remove_invalid_closure_notify (handler, instance);
    2681                 :     535001 :       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                 :     535004 : }
    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                 :    9046780 : g_signal_handlers_destroy (gpointer instance)
    2723                 :            : {
    2724                 :            :   GBSearchArray *hlbsa;
    2725                 :            :   
    2726                 :    9046780 :   g_return_if_fail (G_TYPE_CHECK_INSTANCE (instance));
    2727                 :            :   
    2728                 :    9046780 :   SIGNAL_LOCK ();
    2729                 :    9049747 :   hlbsa = g_hash_table_lookup (g_handler_list_bsa_ht, instance);
    2730         [ +  + ]:    9049747 :   if (hlbsa)
    2731                 :            :     {
    2732                 :            :       guint i;
    2733                 :            :       
    2734                 :            :       /* reentrancy caution, delete instance trace first */
    2735                 :     106543 :       g_hash_table_remove (g_handler_list_bsa_ht, instance);
    2736                 :            :       
    2737         [ +  + ]:     213555 :       for (i = 0; i < hlbsa->n_nodes; i++)
    2738                 :            :         {
    2739                 :     107012 :           HandlerList *hlist = g_bsearch_array_get_nth (hlbsa, &g_signal_hlbsa_bconfig, i);
    2740                 :     107012 :           Handler *handler = hlist->handlers;
    2741                 :            :           
    2742         [ +  + ]:     107799 :           while (handler)
    2743                 :            :             {
    2744                 :        787 :               Handler *tmp = handler;
    2745                 :            :               
    2746                 :        787 :               handler = tmp->next;
    2747                 :        787 :               tmp->block_count = 1;
    2748                 :            :               /* cruel unlink, this works because _all_ handlers vanish */
    2749                 :        787 :               tmp->next = NULL;
    2750                 :        787 :               tmp->prev = tmp;
    2751         [ +  - ]:        787 :               if (tmp->sequential_number)
    2752                 :            :                 {
    2753                 :        787 :                   g_hash_table_remove (g_handlers, tmp);
    2754                 :        787 :                   remove_invalid_closure_notify (tmp, instance);
    2755                 :        787 :                   tmp->sequential_number = 0;
    2756                 :        787 :                   handler_unref_R (0, NULL, tmp);
    2757                 :            :                 }
    2758                 :            :             }
    2759                 :            :         }
    2760                 :     106543 :       g_bsearch_array_free (hlbsa, &g_signal_hlbsa_bconfig);
    2761                 :            :     }
    2762                 :    9049747 :   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                 :     402046 : 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                 :     402046 :   guint n_handlers = 0;
    2829                 :            : 
    2830                 :     402046 :   mlist = handlers_find (instance, mask, signal_id, detail, closure, func, data, FALSE);
    2831         [ +  + ]:     804001 :   while (mlist)
    2832                 :            :     {
    2833                 :     401955 :       n_handlers++;
    2834         [ +  - ]:     401955 :       if (mlist->handler->sequential_number)
    2835                 :     401955 :         callback (instance, mlist->handler->sequential_number);
    2836                 :            : 
    2837                 :     401955 :       mlist = handler_match_free1_R (mlist, instance);
    2838                 :            :     }
    2839                 :            : 
    2840                 :     402046 :   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                 :     401983 : 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                 :     401983 :   guint n_handlers = 0;
    2991                 :            :   
    2992                 :     401983 :   g_return_val_if_fail (G_TYPE_CHECK_INSTANCE (instance), 0);
    2993                 :     401983 :   g_return_val_if_fail ((mask & ~G_SIGNAL_MATCH_MASK) == 0, 0);
    2994                 :            :   
    2995         [ +  + ]:     401983 :   if (mask & (G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_CLOSURE | G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA))
    2996                 :            :     {
    2997                 :     401928 :       SIGNAL_LOCK ();
    2998                 :            :       n_handlers =
    2999                 :     402038 :         signal_handlers_foreach_matched_unlocked_R (instance, mask, signal_id, detail,
    3000                 :            :                                                     closure, func, data,
    3001                 :            :                                                     signal_handler_disconnect_unlocked);
    3002                 :     402038 :       SIGNAL_UNLOCK ();
    3003                 :            :     }
    3004                 :            :   
    3005                 :     401976 :   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                 :        120 : 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                 :        120 :   g_return_val_if_fail (G_TYPE_CHECK_INSTANCE (instance), FALSE);
    3046                 :        120 :   g_return_val_if_fail (signal_id > 0, FALSE);
    3047                 :            :   
    3048                 :        120 :   SIGNAL_LOCK ();
    3049                 :            : 
    3050                 :        120 :   node = LOOKUP_SIGNAL_NODE (signal_id);
    3051         [ -  + ]:        120 :   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         [ +  + ]:        120 :   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         [ +  + ]:        120 :   if (mlist)
    3064                 :            :     {
    3065                 :         76 :       has_pending = TRUE;
    3066                 :         76 :       handler_match_free1_R (mlist, instance);
    3067                 :            :     }
    3068                 :            :   else
    3069                 :            :     {
    3070                 :         44 :       ClassClosure *class_closure = signal_find_class_closure (node, G_TYPE_FROM_INSTANCE (instance));
    3071   [ +  +  -  + ]:         44 :       if (class_closure != NULL && class_closure->instance_type != 0)
    3072                 :          0 :         has_pending = TRUE;
    3073                 :            :       else
    3074                 :         44 :         has_pending = FALSE;
    3075                 :            :     }
    3076                 :        120 :   SIGNAL_UNLOCK ();
    3077                 :            : 
    3078                 :        120 :   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                 :         50 : g_signal_emitv (const GValue *instance_and_params,
    3106                 :            :                 guint         signal_id,
    3107                 :            :                 GQuark        detail,
    3108                 :            :                 GValue       *return_value)
    3109                 :            : {
    3110                 :         50 :   SIGNAL_LOCK ();
    3111                 :         50 :   signal_emitv_unlocked (instance_and_params, signal_id, detail, return_value);
    3112                 :         50 :   SIGNAL_UNLOCK ();
    3113                 :         50 : }
    3114                 :            : 
    3115                 :            : static void
    3116                 :         50 : 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                 :         52 :   g_return_if_fail (instance_and_params != NULL);
    3129                 :         50 :   instance = g_value_peek_pointer (instance_and_params);
    3130                 :         50 :   g_return_if_fail (G_TYPE_CHECK_INSTANCE (instance));
    3131                 :         50 :   g_return_if_fail (signal_id > 0);
    3132                 :            : 
    3133                 :            : #ifdef G_ENABLE_DEBUG
    3134                 :         50 :   param_values = instance_and_params + 1;
    3135                 :            : #endif
    3136                 :            : 
    3137                 :         50 :   node = LOOKUP_SIGNAL_NODE (signal_id);
    3138   [ +  -  +  +  :         50 :   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   [ -  +  -  - ]:         50 :   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         [ +  + ]:        219 :   for (i = 0; i < node->n_params; i++)
    3150   [ -  +  +  -  :        169 :     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         [ +  + ]:         50 :   if (node->return_type != G_TYPE_NONE)
    3161                 :            :     {
    3162         [ +  + ]:         39 :       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   [ +  +  -  +  :         38 :       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         [ +  + ]:         48 :   if (!node->single_va_closure_is_valid)
    3186                 :         34 :     node_update_single_va_closure (node);
    3187                 :            : 
    3188         [ -  + ]:         48 :   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                 :         48 :   SignalNode node_copy = *node;
    3211                 :         48 :   signal_emit_unlocked_R (&node_copy, detail, instance, return_value, instance_and_params);
    3212                 :            : }
    3213                 :            : 
    3214                 :            : static inline gboolean
    3215                 :   30137228 : accumulate (GSignalInvocationHint *ihint,
    3216                 :            :             GValue                *return_accu,
    3217                 :            :             GValue                *handler_return,
    3218                 :            :             SignalAccumulator     *accumulator)
    3219                 :            : {
    3220                 :            :   gboolean continue_emission;
    3221                 :            : 
    3222         [ +  # ]:   30137228 :   if (!accumulator)
    3223                 :   30146960 :     return TRUE;
    3224                 :            : 
    3225                 :          0 :   continue_emission = accumulator->func (ihint, return_accu, handler_return, accumulator->data);
    3226                 :       2315 :   g_value_reset (handler_return);
    3227                 :            : 
    3228                 :       2315 :   ihint->run_type &= ~G_SIGNAL_ACCUMULATOR_FIRST_RUN;
    3229                 :            : 
    3230                 :       2315 :   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                 :   44388277 : g_signal_emit_valist (gpointer instance,
    3257                 :            :                       guint    signal_id,
    3258                 :            :                       GQuark   detail,
    3259                 :            :                       va_list  var_args)
    3260                 :            : {
    3261                 :   44388277 :   SIGNAL_LOCK ();
    3262         [ +  + ]:   44467381 :   if (signal_emit_valist_unlocked (instance, signal_id, detail, var_args))
    3263                 :   24940090 :     SIGNAL_UNLOCK ();
    3264                 :   44361920 : }
    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                 :   44467794 : 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                 :   44467794 :   g_return_val_if_fail (G_TYPE_CHECK_INSTANCE (instance), TRUE);
    3287                 :   44467794 :   g_return_val_if_fail (signal_id > 0, TRUE);
    3288                 :            : 
    3289                 :   44467794 :   node = LOOKUP_SIGNAL_NODE (signal_id);
    3290   [ +  -  +  +  :   44467794 :   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   [ +  +  -  + ]:   44467794 :   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         [ +  + ]:   44467794 :   if (!node->single_va_closure_is_valid)
    3304                 :        445 :     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                 :   44467794 :   SignalNode node_copy = *node;
    3313                 :            : 
    3314         [ +  + ]:   44467794 :   if (node->single_va_closure != NULL)
    3315                 :            :     {
    3316                 :            :       HandlerList* hlist;
    3317                 :   44365139 :       Handler *fastpath_handler = NULL;
    3318                 :            :       Handler *l;
    3319                 :   44365139 :       GClosure *closure = NULL;
    3320                 :   44365139 :       gboolean fastpath = TRUE;
    3321                 :   44365139 :       GSignalFlags run_type = G_SIGNAL_RUN_FIRST;
    3322                 :            : 
    3323   [ +  +  +  + ]:   88400374 :       if (node->single_va_closure != SINGLE_VA_CLOSURE_EMPTY_MAGIC &&
    3324                 :   44035235 :           !_g_closure_is_void (node->single_va_closure, instance))
    3325                 :            :         {
    3326         [ +  + ]:   11553295 :           if (_g_closure_supports_invoke_va (node->single_va_closure))
    3327                 :            :             {
    3328                 :     172638 :               closure = node->single_va_closure;
    3329         [ +  + ]:     172638 :               if (node->single_va_closure_is_after)
    3330                 :       1888 :                 run_type = G_SIGNAL_RUN_LAST;
    3331                 :            :               else
    3332                 :     170750 :                 run_type = G_SIGNAL_RUN_FIRST;
    3333                 :            :             }
    3334                 :            :           else
    3335                 :   11380657 :             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         [ +  + ]:   44365139 :       if (_g_object_has_signal_handler ((GObject *)instance))
    3340                 :   13353153 :         hlist = handler_list_lookup (node->signal_id, instance);
    3341                 :            :       else
    3342                 :   31011986 :         hlist = NULL;
    3343                 :            : 
    3344   [ +  +  +  +  :   49585297 :       for (l = hlist ? hlist->handlers : NULL; fastpath && l != NULL; l = l->next)
                   +  + ]
    3345                 :            :         {
    3346         [ +  + ]:    8086413 :           if (!l->block_count &&
    3347   [ +  +  +  + ]:    8086130 :               (!l->detail || l->detail == detail))
    3348                 :            :             {
    3349   [ +  +  +  + ]:    7947972 :               if (closure != NULL || !_g_closure_supports_invoke_va (l->closure))
    3350                 :            :                 {
    3351                 :    2866255 :                   fastpath = FALSE;
    3352                 :    2866255 :                   break;
    3353                 :            :                 }
    3354                 :            :               else
    3355                 :            :                 {
    3356                 :    5081717 :                   fastpath_handler = l;
    3357                 :    5081717 :                   closure = l->closure;
    3358         [ -  + ]:    5081717 :                   if (l->after)
    3359                 :          0 :                     run_type = G_SIGNAL_RUN_LAST;
    3360                 :            :                   else
    3361                 :    5081717 :                     run_type = G_SIGNAL_RUN_FIRST;
    3362                 :            :                 }
    3363                 :            :             }
    3364                 :            :         }
    3365                 :            : 
    3366   [ +  +  +  +  :   44365139 :       if (fastpath && closure == NULL && node_copy.return_type == G_TYPE_NONE)
                   +  - ]
    3367                 :   24940247 :         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   [ +  +  +  + ]:   19424892 :       if (closure != NULL && (node_copy.flags & (G_SIGNAL_NO_RECURSE)) != 0)
    3372                 :    4897794 :         fastpath = FALSE;
    3373                 :            :       
    3374         [ +  + ]:   19424892 :       if (fastpath)
    3375                 :            :         {
    3376                 :            :           Emission emission;
    3377                 :     280205 :           GValue *return_accu, accu = G_VALUE_INIT;
    3378                 :     280205 :           GType instance_type = G_TYPE_FROM_INSTANCE (instance);
    3379                 :     280205 :           GValue emission_return = G_VALUE_INIT;
    3380                 :     280205 :           GType rtype = node_copy.return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE;
    3381                 :     280205 :           gboolean static_scope = node_copy.return_type & G_SIGNAL_TYPE_STATIC_SCOPE;
    3382                 :            : 
    3383         [ +  + ]:     280205 :           if (rtype == G_TYPE_NONE)
    3384                 :     279319 :             return_accu = NULL;
    3385         [ +  + ]:        886 :           else if (node_copy.accumulator)
    3386                 :        871 :             return_accu = &accu;
    3387                 :            :           else
    3388                 :         15 :             return_accu = &emission_return;
    3389                 :            : 
    3390                 :     280205 :           emission.instance = instance;
    3391                 :     280205 :           emission.ihint.signal_id = signal_id;
    3392                 :     280205 :           emission.ihint.detail = detail;
    3393                 :     280205 :           emission.ihint.run_type = run_type | G_SIGNAL_ACCUMULATOR_FIRST_RUN;
    3394                 :     280205 :           emission.state = EMISSION_RUN;
    3395                 :     280205 :           emission.chain_type = instance_type;
    3396                 :     280205 :           emission_push (&emission);
    3397                 :            : 
    3398         [ +  + ]:     280205 :           if (fastpath_handler)
    3399                 :     184014 :             handler_ref (fastpath_handler);
    3400                 :            : 
    3401         [ +  - ]:     280205 :           if (closure != NULL)
    3402                 :            :             {
    3403                 :     280205 :           TRACE(GOBJECT_SIGNAL_EMIT(signal_id, detail, instance, instance_type));
    3404                 :            : 
    3405                 :     280205 :               SIGNAL_UNLOCK ();
    3406                 :            : 
    3407         [ +  + ]:     280205 :           if (rtype != G_TYPE_NONE)
    3408                 :        886 :             g_value_init (&emission_return, rtype);
    3409                 :            : 
    3410         [ +  + ]:     280205 :               if (node_copy.accumulator)
    3411                 :        871 :                 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                 :     280205 :               g_object_ref (instance);
    3422                 :            : #endif
    3423                 :     280205 :               _g_closure_invoke_va (closure,
    3424                 :            :                                     return_accu,
    3425                 :            :                                     instance,
    3426                 :            :                                     var_args,
    3427                 :     280205 :                                     node_copy.n_params,
    3428                 :            :                                     node_copy.param_types);
    3429                 :     280203 :               accumulate (&emission.ihint, &emission_return, &accu, node_copy.accumulator);
    3430                 :            : 
    3431         [ +  + ]:     280203 :               if (node_copy.accumulator)
    3432                 :        871 :                 g_value_unset (&accu);
    3433                 :            : 
    3434                 :     280203 :               SIGNAL_LOCK ();
    3435                 :            :             }
    3436                 :            : 
    3437                 :     280203 :           emission.chain_type = G_TYPE_NONE;
    3438                 :     280203 :           emission_pop (&emission);
    3439                 :            : 
    3440         [ +  + ]:     280203 :           if (fastpath_handler)
    3441                 :     184012 :             handler_unref_R (signal_id, instance, fastpath_handler);
    3442                 :            : 
    3443                 :     280203 :           SIGNAL_UNLOCK ();
    3444                 :            : 
    3445         [ +  + ]:     280203 :           if (rtype != G_TYPE_NONE)
    3446                 :            :             {
    3447                 :        886 :               gchar *error = NULL;
    3448         [ +  + ]:       2354 :               for (i = 0; i < node_copy.n_params; i++)
    3449                 :            :                 {
    3450                 :       1468 :                   GType ptype = node_copy.param_types[i] & ~G_SIGNAL_TYPE_STATIC_SCOPE;
    3451   [ +  -  -  -  :       2936 :                   G_VALUE_COLLECT_SKIP (ptype, var_args);
             +  -  +  + ]
    3452                 :            :                 }
    3453                 :            : 
    3454         [ -  + ]:        886 :               if (closure == NULL)
    3455                 :          0 :                 g_value_init (&emission_return, rtype);
    3456                 :            : 
    3457   [ -  +  -  -  :       1772 :               G_VALUE_LCOPY (&emission_return,
          -  -  +  -  +  
                      + ]
    3458                 :            :                              var_args,
    3459                 :            :                              static_scope ? G_VALUE_NOCOPY_CONTENTS : 0,
    3460                 :            :                              &error);
    3461         [ +  - ]:        886 :               if (!error)
    3462                 :        886 :                 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                 :     280203 :           TRACE(GOBJECT_SIGNAL_EMIT_END(signal_id, detail, instance, instance_type));
    3474                 :            : 
    3475                 :            :           /* See comment above paired ref above */
    3476                 :            : #ifndef __COVERITY__
    3477         [ +  - ]:     280203 :           if (closure != NULL)
    3478                 :     280203 :             g_object_unref (instance);
    3479                 :            : #endif
    3480                 :            : 
    3481                 :     280203 :           return FALSE;
    3482                 :            :         }
    3483                 :            :     }
    3484                 :            : 
    3485                 :   19247342 :   SIGNAL_UNLOCK ();
    3486                 :            : 
    3487         [ +  # ]:   19229825 :   instance_and_params = g_newa0 (GValue, node_copy.n_params + 1);
    3488                 :   19229825 :   param_values = instance_and_params + 1;
    3489                 :            : 
    3490         [ +  + ]:   38395016 :   for (i = 0; i < node_copy.n_params; i++)
    3491                 :            :     {
    3492                 :            :       gchar *error;
    3493                 :   19171538 :       GType ptype = node_copy.param_types[i] & ~G_SIGNAL_TYPE_STATIC_SCOPE;
    3494                 :   19171538 :       gboolean static_scope = node_copy.param_types[i] & G_SIGNAL_TYPE_STATIC_SCOPE;
    3495                 :            : 
    3496   [ +  +  +  +  :   38342955 :       G_VALUE_COLLECT_INIT (param_values + i, ptype,
          +  +  +  -  +  
                      + ]
    3497                 :            :                             var_args,
    3498                 :            :                             static_scope ? G_VALUE_NOCOPY_CONTENTS : 0,
    3499                 :            :                             &error);
    3500         [ +  + ]:   19170846 :       if (error)
    3501                 :            :         {
    3502                 :       5655 :           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                 :   19223478 :   g_value_init_from_instance (instance_and_params, instance);
    3516         [ +  + ]:   19232282 :   if (node_copy.return_type == G_TYPE_NONE)
    3517                 :            :     {
    3518                 :   15191631 :       SIGNAL_LOCK ();
    3519                 :   15195770 :       signal_emit_unlocked_R (&node_copy, detail, instance, NULL, instance_and_params);
    3520                 :   15195764 :       SIGNAL_UNLOCK ();
    3521                 :            :     }
    3522                 :            :   else
    3523                 :            :     {
    3524                 :    4040651 :       GValue return_value = G_VALUE_INIT;
    3525                 :    4040651 :       gchar *error = NULL;
    3526                 :    4040651 :       GType rtype = node_copy.return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE;
    3527                 :    4040651 :       gboolean static_scope = node_copy.return_type & G_SIGNAL_TYPE_STATIC_SCOPE;
    3528                 :            :       
    3529                 :    4040651 :       g_value_init (&return_value, rtype);
    3530                 :            : 
    3531                 :    4042252 :       SIGNAL_LOCK ();
    3532                 :    4051572 :       signal_emit_unlocked_R (&node_copy, detail, instance, &return_value, instance_and_params);
    3533                 :    4051572 :       SIGNAL_UNLOCK ();
    3534                 :            : 
    3535   [ -  +  -  -  :    8096472 :       G_VALUE_LCOPY (&return_value,
          -  -  +  -  +  
                      + ]
    3536                 :            :                      var_args,
    3537                 :            :                      static_scope ? G_VALUE_NOCOPY_CONTENTS : 0,
    3538                 :            :                      &error);
    3539         [ +  # ]:    4044676 :       if (!error)
    3540                 :    4050304 :         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         [ +  + ]:   38398866 :   for (i = 0; i < node_copy.n_params; i++)
    3552                 :   19170133 :     g_value_unset (param_values + i);
    3553                 :   19228733 :   g_value_unset (instance_and_params);
    3554                 :            : 
    3555                 :   19221906 :   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                 :   44357136 : g_signal_emit (gpointer instance,
    3575                 :            :                guint    signal_id,
    3576                 :            :                GQuark   detail,
    3577                 :            :                ...)
    3578                 :            : {
    3579                 :            :   va_list var_args;
    3580                 :            : 
    3581                 :   44357136 :   va_start (var_args, detail);
    3582                 :   44357136 :   g_signal_emit_valist (instance, signal_id, detail, var_args);
    3583                 :   44411048 :   va_end (var_args);
    3584                 :   44411048 : }
    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                 :        413 : g_signal_emit_by_name (gpointer     instance,
    3603                 :            :                        const gchar *detailed_signal,
    3604                 :            :                        ...)
    3605                 :            : {
    3606                 :        413 :   GQuark detail = 0;
    3607                 :            :   guint signal_id;
    3608                 :            :   GType itype;
    3609                 :            : 
    3610                 :        413 :   g_return_if_fail (G_TYPE_CHECK_INSTANCE (instance));
    3611                 :        413 :   g_return_if_fail (detailed_signal != NULL);
    3612                 :            : 
    3613                 :        413 :   itype = G_TYPE_FROM_INSTANCE (instance);
    3614                 :            : 
    3615                 :        413 :   SIGNAL_LOCK ();
    3616                 :        413 :   signal_id = signal_parse_name (detailed_signal, itype, &detail, TRUE);
    3617                 :            : 
    3618         [ +  - ]:        413 :   if (signal_id)
    3619                 :            :     {
    3620                 :            :       va_list var_args;
    3621                 :            : 
    3622                 :        413 :       va_start (var_args, detailed_signal);
    3623         [ +  + ]:        413 :       if (signal_emit_valist_unlocked (instance, signal_id, detail, var_args))
    3624                 :        157 :         SIGNAL_UNLOCK ();
    3625                 :        413 :       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   [ +  +  +  +  :   29856383 :   if (node->accumulator)
             +  +  +  + ]
    3642                 :            :     {
    3643   [ -  +  +  +  :       1440 :       if (accumulator_value->g_type)
             +  +  +  - ]
    3644                 :        563 :         return accumulator_value;
    3645                 :            : 
    3646                 :        877 :       g_value_init (accumulator_value,
    3647                 :        877 :                     node->return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE);
    3648                 :        877 :       return accumulator_value;
    3649                 :            :     }
    3650                 :            : 
    3651                 :   29854943 :   return emission_return;
    3652                 :            : }
    3653                 :            : 
    3654                 :            : static gboolean
    3655                 :   19247390 : 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                 :   19247390 :   Handler *handler_list = NULL;
    3666                 :   19247390 :   GValue *return_accu, accu = G_VALUE_INIT;
    3667                 :            :   guint signal_id;
    3668                 :            :   gulong max_sequential_handler_number;
    3669                 :   19247390 :   gboolean return_value_altered = FALSE;
    3670                 :            :   guint n_params;
    3671                 :            : 
    3672                 :   19247390 :   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                 :   19247390 :   signal_id = node->signal_id;
    3679                 :   19247390 :   n_params = node->n_params + 1;
    3680                 :            : 
    3681         [ +  + ]:   19247390 :   if (node->flags & G_SIGNAL_NO_RECURSE)
    3682                 :            :     {
    3683                 :    4897794 :       Emission *emission_node = emission_find (signal_id, detail, instance);
    3684                 :            : 
    3685         [ +  + ]:    4897794 :       if (emission_node)
    3686                 :            :         {
    3687                 :     302579 :           emission_node->state = EMISSION_RESTART;
    3688                 :     302579 :           return return_value_altered;
    3689                 :            :         }
    3690                 :            :     }
    3691                 :   18944811 :   accumulator = node->accumulator;
    3692                 :   18944811 :   emission.instance = instance;
    3693                 :   18944811 :   emission.ihint.signal_id = node->signal_id;
    3694                 :   18944811 :   emission.ihint.detail = detail;
    3695                 :   18944811 :   emission.ihint.run_type = 0;
    3696                 :   18944811 :   emission.state = 0;
    3697                 :   18944811 :   emission.chain_type = G_TYPE_NONE;
    3698                 :   18944811 :   emission_push (&emission);
    3699                 :   18944811 :   class_closure = signal_lookup_closure (node, instance);
    3700                 :            :   
    3701                 :     107323 :  EMIT_RESTART:
    3702                 :            :   
    3703         [ +  + ]:   19052134 :   if (handler_list)
    3704                 :     107323 :     handler_unref_R (signal_id, instance, handler_list);
    3705                 :   19052134 :   max_sequential_handler_number = g_handler_sequential_number;
    3706                 :   19052134 :   hlist = handler_list_lookup (signal_id, instance);
    3707         [ +  + ]:   19052134 :   handler_list = hlist ? hlist->handlers : NULL;
    3708         [ +  + ]:   19052134 :   if (handler_list)
    3709                 :   10901062 :     handler_ref (handler_list);
    3710                 :            :   
    3711                 :   19052134 :   emission.ihint.run_type = G_SIGNAL_RUN_FIRST | G_SIGNAL_ACCUMULATOR_FIRST_RUN;
    3712                 :            :   
    3713   [ +  +  +  + ]:   19052134 :   if ((node->flags & G_SIGNAL_RUN_FIRST) && class_closure)
    3714                 :            :     {
    3715                 :    5154660 :       emission.state = EMISSION_RUN;
    3716                 :            : 
    3717                 :    5154660 :       emission.chain_type = G_TYPE_FROM_INSTANCE (instance);
    3718                 :    5154660 :       SIGNAL_UNLOCK ();
    3719                 :    5154651 :       return_accu = maybe_init_accumulator_unlocked (node, emission_return, &accu);
    3720                 :    5154651 :       g_closure_invoke (class_closure,
    3721                 :            :                         return_accu,
    3722                 :            :                         n_params,
    3723                 :            :                         instance_and_params,
    3724                 :            :                         &emission.ihint);
    3725         [ -  + ]:    5154552 :       if (!accumulate (&emission.ihint, emission_return, &accu, accumulator) &&
    3726         [ #  # ]:          0 :           emission.state == EMISSION_RUN)
    3727                 :          0 :         emission.state = EMISSION_STOP;
    3728                 :    5154528 :       SIGNAL_LOCK ();
    3729                 :    5154660 :       emission.chain_type = G_TYPE_NONE;
    3730                 :    5154660 :       return_value_altered = TRUE;
    3731                 :            :       
    3732         [ -  + ]:    5154660 :       if (emission.state == EMISSION_STOP)
    3733                 :          0 :         goto EMIT_CLEANUP;
    3734         [ +  + ]:    5154660 :       else if (emission.state == EMISSION_RESTART)
    3735                 :      60024 :         goto EMIT_RESTART;
    3736                 :            :     }
    3737                 :            : 
    3738         [ +  + ]:   18992110 :   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         [ +  + ]:   18992110 :   if (handler_list)
    3867                 :            :     {
    3868                 :   10841038 :       Handler *handler = handler_list;
    3869                 :            :       
    3870                 :   10841038 :       emission.state = EMISSION_RUN;
    3871                 :   10841038 :       handler_ref (handler);
    3872                 :            :       do
    3873                 :            :         {
    3874                 :            :           Handler *tmp;
    3875                 :            :           
    3876         [ +  + ]:   10980077 :           if (handler->after)
    3877                 :            :             {
    3878                 :         24 :               handler_unref_R (signal_id, instance, handler_list);
    3879                 :         24 :               handler_list = handler;
    3880                 :         24 :               break;
    3881                 :            :             }
    3882   [ +  -  +  +  :   10980053 :           else if (!handler->block_count && (!handler->detail || handler->detail == detail) &&
                   +  + ]
    3883         [ +  + ]:   10842201 :                    handler->sequential_number < max_sequential_handler_number)
    3884                 :            :             {
    3885                 :   10842200 :               SIGNAL_UNLOCK ();
    3886                 :   10841900 :               return_accu = maybe_init_accumulator_unlocked (node, emission_return, &accu);
    3887                 :   10841900 :               g_closure_invoke (handler->closure,
    3888                 :            :                                 return_accu,
    3889                 :            :                                 n_params,
    3890                 :            :                                 instance_and_params,
    3891                 :            :                                 &emission.ihint);
    3892         [ +  + ]:   10841140 :               if (!accumulate (&emission.ihint, emission_return, &accu, accumulator) &&
    3893         [ +  - ]:        322 :                   emission.state == EMISSION_RUN)
    3894                 :        322 :                 emission.state = EMISSION_STOP;
    3895                 :   10841018 :               SIGNAL_LOCK ();
    3896                 :   10842194 :               return_value_altered = TRUE;
    3897                 :            :               
    3898         [ +  + ]:   10842194 :               tmp = emission.state == EMISSION_RUN ? handler->next : NULL;
    3899                 :            :             }
    3900                 :            :           else
    3901                 :     137853 :             tmp = handler->next;
    3902                 :            :           
    3903         [ +  + ]:   10980047 :           if (tmp)
    3904                 :     139039 :             handler_ref (tmp);
    3905                 :   10980047 :           handler_unref_R (signal_id, instance, handler_list);
    3906                 :   10980047 :           handler_list = handler;
    3907                 :   10980047 :           handler = tmp;
    3908                 :            :         }
    3909         [ +  + ]:   10980047 :       while (handler);
    3910                 :            :       
    3911         [ +  + ]:   10841032 :       if (emission.state == EMISSION_STOP)
    3912                 :        324 :         goto EMIT_CLEANUP;
    3913         [ +  + ]:   10840708 :       else if (emission.state == EMISSION_RESTART)
    3914                 :      47299 :         goto EMIT_RESTART;
    3915                 :            :     }
    3916                 :            :   
    3917                 :   18944481 :   emission.ihint.run_type &= ~G_SIGNAL_RUN_FIRST;
    3918                 :   18944481 :   emission.ihint.run_type |= G_SIGNAL_RUN_LAST;
    3919                 :            :   
    3920   [ +  +  +  + ]:   18944481 :   if ((node->flags & G_SIGNAL_RUN_LAST) && class_closure)
    3921                 :            :     {
    3922                 :   13876451 :       emission.state = EMISSION_RUN;
    3923                 :            :       
    3924                 :   13876451 :       emission.chain_type = G_TYPE_FROM_INSTANCE (instance);
    3925                 :   13876451 :       SIGNAL_UNLOCK ();
    3926                 :   13859809 :       return_accu = maybe_init_accumulator_unlocked (node, emission_return, &accu);
    3927                 :   13859809 :       g_closure_invoke (class_closure,
    3928                 :            :                         return_accu,
    3929                 :            :                         n_params,
    3930                 :            :                         instance_and_params,
    3931                 :            :                         &emission.ihint);
    3932         [ +  + ]:   13854960 :       if (!accumulate (&emission.ihint, emission_return, &accu, accumulator) &&
    3933         [ +  - ]:          2 :           emission.state == EMISSION_RUN)
    3934                 :          2 :         emission.state = EMISSION_STOP;
    3935                 :   13873028 :       SIGNAL_LOCK ();
    3936                 :   13876451 :       emission.chain_type = G_TYPE_NONE;
    3937                 :   13876451 :       return_value_altered = TRUE;
    3938                 :            :       
    3939         [ +  + ]:   13876451 :       if (emission.state == EMISSION_STOP)
    3940                 :          2 :         goto EMIT_CLEANUP;
    3941         [ -  + ]:   13876449 :       else if (emission.state == EMISSION_RESTART)
    3942                 :          0 :         goto EMIT_RESTART;
    3943                 :            :     }
    3944                 :            :   
    3945         [ +  + ]:   18944479 :   if (handler_list)
    3946                 :            :     {
    3947                 :   10793408 :       Handler *handler = handler_list;
    3948                 :            :       
    3949                 :   10793408 :       emission.state = EMISSION_RUN;
    3950                 :   10793408 :       handler_ref (handler);
    3951                 :            :       do
    3952                 :            :         {
    3953                 :            :           Handler *tmp;
    3954                 :            :           
    3955   [ +  +  +  -  :   10793408 :           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                 :   10793385 :             tmp = handler->next;
    3975                 :            :           
    3976         [ -  + ]:   10793408 :           if (tmp)
    3977                 :          0 :             handler_ref (tmp);
    3978                 :   10793408 :           handler_unref_R (signal_id, instance, handler);
    3979                 :   10793408 :           handler = tmp;
    3980                 :            :         }
    3981         [ -  + ]:   10793408 :       while (handler);
    3982                 :            :       
    3983         [ +  + ]:   10793408 :       if (emission.state == EMISSION_STOP)
    3984                 :          2 :         goto EMIT_CLEANUP;
    3985         [ +  - ]:   10793406 :       else if (emission.state == EMISSION_RESTART)
    3986                 :          0 :         goto EMIT_RESTART;
    3987                 :            :     }
    3988                 :            :   
    3989                 :   18944477 :  EMIT_CLEANUP:
    3990                 :            :   
    3991                 :   18944805 :   emission.ihint.run_type &= ~G_SIGNAL_RUN_LAST;
    3992                 :   18944805 :   emission.ihint.run_type |= G_SIGNAL_RUN_CLEANUP;
    3993                 :            :   
    3994   [ +  +  +  - ]:   18944805 :   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         [ +  + ]:   18944805 :   if (handler_list)
    4027                 :   10793733 :     handler_unref_R (signal_id, instance, handler_list);
    4028                 :            :   
    4029                 :   18944805 :   emission_pop (&emission);
    4030         [ +  + ]:   18944805 :   if (accumulator)
    4031                 :        877 :     g_value_unset (&accu);
    4032                 :            : 
    4033                 :   18944805 :   TRACE(GOBJECT_SIGNAL_EMIT_END(node->signal_id, detail, instance, G_TYPE_FROM_INSTANCE (instance)));
    4034                 :            : 
    4035                 :   18944805 :   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                 :     535788 : remove_invalid_closure_notify (Handler  *handler,
    4048                 :            :                                gpointer  instance)
    4049                 :            : {
    4050         [ +  + ]:     535788 :   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                 :     535788 : }
    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                 :        851 : 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                 :        851 :   signal_handled = g_value_get_boolean (handler_return);
    4120                 :        851 :   g_value_set_boolean (return_accu, signal_handled);
    4121                 :        851 :   continue_emission = !signal_handled;
    4122                 :            :   
    4123                 :        851 :   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 1.14