LCOV - code coverage report
Current view: top level - glib - gmain.c (source / functions) Coverage Total Hit
Test: unnamed Lines: 88.6 % 2007 1778
Test Date: 2026-07-14 05:12:09 Functions: 96.3 % 163 157
Branches: - 0 0

             Branch data     Line data    Source code
       1                 :             : /* GLIB - Library of useful routines for C programming
       2                 :             :  * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
       3                 :             :  *
       4                 :             :  * gmain.c: Main loop abstraction, timeouts, and idle functions
       5                 :             :  * Copyright 1998 Owen Taylor
       6                 :             :  *
       7                 :             :  * SPDX-License-Identifier: LGPL-2.1-or-later
       8                 :             :  *
       9                 :             :  * This library is free software; you can redistribute it and/or
      10                 :             :  * modify it under the terms of the GNU Lesser General Public
      11                 :             :  * License as published by the Free Software Foundation; either
      12                 :             :  * version 2.1 of the License, or (at your option) any later version.
      13                 :             :  *
      14                 :             :  * This library is distributed in the hope that it will be useful,
      15                 :             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      16                 :             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      17                 :             :  * Lesser General Public License for more details.
      18                 :             :  *
      19                 :             :  * You should have received a copy of the GNU Lesser General Public
      20                 :             :  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
      21                 :             :  */
      22                 :             : 
      23                 :             : /*
      24                 :             :  * Modified by the GLib Team and others 1997-2000.  See the AUTHORS
      25                 :             :  * file for a list of people on the GLib Team.  See the ChangeLog
      26                 :             :  * files for a list of changes.  These files are distributed with
      27                 :             :  * GLib at ftp://ftp.gtk.org/pub/gtk/.
      28                 :             :  */
      29                 :             : 
      30                 :             : /*
      31                 :             :  * MT safe
      32                 :             :  */
      33                 :             : 
      34                 :             : #include "config.h"
      35                 :             : 
      36                 :             : /* We need to include this as early as possible, because on some
      37                 :             :  * platforms like AIX, <poll.h> redefines the names we use for
      38                 :             :  * GPollFD struct members.
      39                 :             :  * See https://gitlab.gnome.org/GNOME/glib/-/issues/3500 */
      40                 :             : 
      41                 :             : #ifdef HAVE_POLL_H
      42                 :             : #include <poll.h>
      43                 :             : #endif
      44                 :             : 
      45                 :             : #include "glib.h"
      46                 :             : #include "glibconfig.h"
      47                 :             : #include "glib_trace.h"
      48                 :             : 
      49                 :             : /* Uncomment the next line (and the corresponding line in gpoll.c) to
      50                 :             :  * enable debugging printouts if the environment variable
      51                 :             :  * G_MAIN_POLL_DEBUG is set to some value.
      52                 :             :  */
      53                 :             : /* #define G_MAIN_POLL_DEBUG */
      54                 :             : 
      55                 :             : #ifdef _WIN32
      56                 :             : /* Always enable debugging printout on Windows, as it is more often
      57                 :             :  * needed there...
      58                 :             :  */
      59                 :             : #define G_MAIN_POLL_DEBUG
      60                 :             : #endif
      61                 :             : 
      62                 :             : 
      63                 :             : #ifdef G_OS_UNIX
      64                 :             : #include "glib-unix.h"
      65                 :             : #include <pthread.h>
      66                 :             : #ifdef HAVE_EVENTFD
      67                 :             : #include <sys/eventfd.h>
      68                 :             : #endif
      69                 :             : #endif
      70                 :             : 
      71                 :             : #include <signal.h>
      72                 :             : #include <sys/types.h>
      73                 :             : #include <time.h>
      74                 :             : #include <stdlib.h>
      75                 :             : #ifdef HAVE_SYS_TIME_H
      76                 :             : #include <sys/time.h>
      77                 :             : #endif /* HAVE_SYS_TIME_H */
      78                 :             : #ifdef G_OS_UNIX
      79                 :             : #include <unistd.h>
      80                 :             : #endif /* G_OS_UNIX */
      81                 :             : #include <errno.h>
      82                 :             : #include <string.h>
      83                 :             : 
      84                 :             : #ifdef HAVE_PIDFD
      85                 :             : #include <sys/syscall.h>
      86                 :             : #include <sys/wait.h>
      87                 :             : #include <linux/wait.h>  /* P_PIDFD */
      88                 :             : #ifndef W_EXITCODE
      89                 :             : #define W_EXITCODE(ret, sig) ((ret) << 8 | (sig))
      90                 :             : #endif
      91                 :             : #ifndef W_STOPCODE
      92                 :             : #define W_STOPCODE(sig)      ((sig) << 8 | 0x7f)
      93                 :             : #endif
      94                 :             : #ifndef WCOREFLAG
      95                 :             : /* musl doesn’t define WCOREFLAG while glibc does. Unfortunately, there’s no way
      96                 :             :  * to detect we’re building against musl, so just define it and hope.
      97                 :             :  * See https://git.musl-libc.org/cgit/musl/tree/include/sys/wait.h#n51 */
      98                 :             : #define WCOREFLAG 0x80
      99                 :             : #endif
     100                 :             : #ifndef __W_CONTINUED
     101                 :             : /* Same as above, for musl */
     102                 :             : #define __W_CONTINUED 0xffff
     103                 :             : #endif
     104                 :             : #endif  /* HAVE_PIDFD */
     105                 :             : 
     106                 :             : #ifdef G_OS_WIN32
     107                 :             : #include <windows.h>
     108                 :             : #endif
     109                 :             : 
     110                 :             : #ifdef HAVE_MACH_MACH_TIME_H
     111                 :             : #include <mach/mach_time.h>
     112                 :             : #endif
     113                 :             : 
     114                 :             : #include "glib_trace.h"
     115                 :             : 
     116                 :             : #include "gmain.h"
     117                 :             : 
     118                 :             : #include "garray.h"
     119                 :             : #include "giochannel.h"
     120                 :             : #include "ghash.h"
     121                 :             : #include "ghook.h"
     122                 :             : #include "gqueue.h"
     123                 :             : #include "gstrfuncs.h"
     124                 :             : #include "gtestutils.h"
     125                 :             : #include "gthreadprivate.h"
     126                 :             : #include "gtrace-private.h"
     127                 :             : 
     128                 :             : #ifdef G_OS_WIN32
     129                 :             : #include "gwin32.h"
     130                 :             : #endif
     131                 :             : 
     132                 :             : #ifdef  G_MAIN_POLL_DEBUG
     133                 :             : #include "gtimer.h"
     134                 :             : #endif
     135                 :             : 
     136                 :             : #include "gwakeup.h"
     137                 :             : #include "gmain-internal.h"
     138                 :             : #include "glib-init.h"
     139                 :             : #include "glib-private.h"
     140                 :             : 
     141                 :             : /* Types */
     142                 :             : 
     143                 :             : typedef struct _GIdleSource GIdleSource;
     144                 :             : typedef struct _GTimeoutSource GTimeoutSource;
     145                 :             : typedef struct _GChildWatchSource GChildWatchSource;
     146                 :             : typedef struct _GUnixSignalWatchSource GUnixSignalWatchSource;
     147                 :             : typedef struct _GPollRec GPollRec;
     148                 :             : typedef struct _GSourceCallback GSourceCallback;
     149                 :             : 
     150                 :             : typedef enum
     151                 :             : {
     152                 :             :   G_SOURCE_READY = 1 << G_HOOK_FLAG_USER_SHIFT,
     153                 :             :   G_SOURCE_CAN_RECURSE = 1 << (G_HOOK_FLAG_USER_SHIFT + 1),
     154                 :             :   G_SOURCE_BLOCKED = 1 << (G_HOOK_FLAG_USER_SHIFT + 2)
     155                 :             : } G_GNUC_FLAG_ENUM GSourceFlags;
     156                 :             : 
     157                 :             : typedef struct _GSourceList GSourceList;
     158                 :             : 
     159                 :             : struct _GSourceList
     160                 :             : {
     161                 :             :   GList link;
     162                 :             :   GSource *head, *tail;
     163                 :             :   gint priority;
     164                 :             : };
     165                 :             : 
     166                 :             : typedef struct _GMainWaiter GMainWaiter;
     167                 :             : 
     168                 :             : struct _GMainWaiter
     169                 :             : {
     170                 :             :   GCond *cond;
     171                 :             :   GMutex *mutex;
     172                 :             : };
     173                 :             : 
     174                 :             : typedef struct _GMainDispatch GMainDispatch;
     175                 :             : 
     176                 :             : struct _GMainDispatch
     177                 :             : {
     178                 :             :   gint depth;
     179                 :             :   GSource *source;
     180                 :             : };
     181                 :             : 
     182                 :             : #ifdef G_MAIN_POLL_DEBUG
     183                 :             : gboolean _g_main_poll_debug = FALSE;
     184                 :             : #endif
     185                 :             : 
     186                 :             : struct _GMainContext
     187                 :             : {
     188                 :             :   /* The following lock is used for both the list of sources
     189                 :             :    * and the list of poll records
     190                 :             :    */
     191                 :             :   GMutex mutex;
     192                 :             :   GCond cond;
     193                 :             :   GThread *owner;
     194                 :             :   guint owner_count;
     195                 :             :   GMainContextFlags flags;
     196                 :             :   GSList *waiters;
     197                 :             : 
     198                 :             :   gint ref_count;  /* (atomic) */
     199                 :             : 
     200                 :             :   GHashTable *sources;              /* guint -> GSource */
     201                 :             : 
     202                 :             :   GPtrArray *pending_dispatches;
     203                 :             :   gint64 timeout_usec; /* Timeout for current iteration */
     204                 :             : 
     205                 :             :   guint next_id;
     206                 :             :   GQueue source_lists;
     207                 :             :   gint in_check_or_prepare;
     208                 :             : 
     209                 :             :   GPollRec *poll_records;
     210                 :             :   guint n_poll_records;
     211                 :             :   GPollFD *cached_poll_array;
     212                 :             :   guint cached_poll_array_size;
     213                 :             : 
     214                 :             :   GWakeup *wakeup;
     215                 :             : 
     216                 :             :   GPollFD wake_up_rec;
     217                 :             : 
     218                 :             : /* Flag indicating whether the set of fd's changed during a poll */
     219                 :             :   gboolean poll_changed;
     220                 :             : 
     221                 :             :   GPollFunc poll_func;
     222                 :             : 
     223                 :             :   gint64   time;
     224                 :             :   gboolean time_is_fresh;
     225                 :             : };
     226                 :             : 
     227                 :             : struct _GSourceCallback
     228                 :             : {
     229                 :             :   gint ref_count;  /* (atomic) */
     230                 :             :   GSourceFunc func;
     231                 :             :   gpointer    data;
     232                 :             :   GDestroyNotify notify;
     233                 :             : };
     234                 :             : 
     235                 :             : struct _GMainLoop
     236                 :             : {
     237                 :             :   GMainContext *context;
     238                 :             :   gboolean is_running; /* (atomic) */
     239                 :             :   gint ref_count;  /* (atomic) */
     240                 :             : };
     241                 :             : 
     242                 :             : struct _GIdleSource
     243                 :             : {
     244                 :             :   GSource  source;
     245                 :             :   gboolean one_shot;
     246                 :             : };
     247                 :             : 
     248                 :             : struct _GTimeoutSource
     249                 :             : {
     250                 :             :   GSource     source;
     251                 :             :   /* Measured in seconds if 'seconds' is TRUE, or milliseconds otherwise. */
     252                 :             :   guint       interval;
     253                 :             :   gboolean    seconds;
     254                 :             :   gboolean    one_shot;
     255                 :             : };
     256                 :             : 
     257                 :             : struct _GChildWatchSource
     258                 :             : {
     259                 :             :   GSource     source;
     260                 :             :   GPid        pid;
     261                 :             :   /* @poll is always used on Windows.
     262                 :             :    * On Unix, poll.fd will be negative if PIDFD is unavailable. */
     263                 :             :   GPollFD     poll;
     264                 :             : #ifndef G_OS_WIN32
     265                 :             :   gboolean child_maybe_exited; /* (atomic) */
     266                 :             : #endif /* G_OS_WIN32 */
     267                 :             : };
     268                 :             : 
     269                 :             : struct _GUnixSignalWatchSource
     270                 :             : {
     271                 :             :   GSource     source;
     272                 :             :   int         signum;
     273                 :             :   gboolean    pending; /* (atomic) */
     274                 :             : };
     275                 :             : 
     276                 :             : struct _GPollRec
     277                 :             : {
     278                 :             :   GPollFD *fd;
     279                 :             :   GPollRec *prev;
     280                 :             :   GPollRec *next;
     281                 :             :   gint priority;
     282                 :             : };
     283                 :             : 
     284                 :             : struct _GSourcePrivate
     285                 :             : {
     286                 :             :   GSList *child_sources;
     287                 :             :   GSource *parent_source;
     288                 :             : 
     289                 :             :   gint64 ready_time;
     290                 :             : 
     291                 :             :   /* This is currently only used on UNIX, but we always declare it (and
     292                 :             :    * let it remain empty on Windows) to avoid #ifdef all over the place.
     293                 :             :    */
     294                 :             :   GSList *fds;
     295                 :             : 
     296                 :             :   GSourceDisposeFunc dispose;
     297                 :             : 
     298                 :             :   gboolean static_name;
     299                 :             : };
     300                 :             : 
     301                 :             : typedef struct _GSourceIter
     302                 :             : {
     303                 :             :   GMainContext *context;
     304                 :             :   gboolean may_modify;
     305                 :             :   GList *current_list;
     306                 :             :   GSource *source;
     307                 :             : } GSourceIter;
     308                 :             : 
     309                 :             : #define LOCK_CONTEXT(context) g_mutex_lock (&context->mutex)
     310                 :             : #define UNLOCK_CONTEXT(context) g_mutex_unlock (&context->mutex)
     311                 :             : #define G_THREAD_SELF g_thread_self ()
     312                 :             : 
     313                 :             : #define SOURCE_DESTROYED(source) \
     314                 :             :   ((g_atomic_int_get (&((source)->flags)) & G_HOOK_FLAG_ACTIVE) == 0)
     315                 :             : #define SOURCE_BLOCKED(source) \
     316                 :             :   ((g_atomic_int_get (&((source)->flags)) & G_SOURCE_BLOCKED) != 0)
     317                 :             : 
     318                 :             : /* Forward declarations */
     319                 :             : 
     320                 :             : static void g_source_unref_internal             (GSource      *source,
     321                 :             :                                                  GMainContext *context,
     322                 :             :                                                  gboolean      have_lock);
     323                 :             : static void g_source_destroy_internal           (GSource      *source,
     324                 :             :                                                  GMainContext *context,
     325                 :             :                                                  gboolean      have_lock);
     326                 :             : static void g_source_set_priority_unlocked      (GSource      *source,
     327                 :             :                                                  GMainContext *context,
     328                 :             :                                                  gint          priority);
     329                 :             : static void g_child_source_remove_internal      (GSource      *child_source,
     330                 :             :                                                  GMainContext *context);
     331                 :             : 
     332                 :             : static gboolean g_main_context_acquire_unlocked (GMainContext *context);
     333                 :             : static void g_main_context_release_unlocked     (GMainContext *context);
     334                 :             : static gboolean g_main_context_prepare_unlocked (GMainContext *context,
     335                 :             :                                                  gint         *priority);
     336                 :             : static gint g_main_context_query_unlocked       (GMainContext *context,
     337                 :             :                                                  gint          max_priority,
     338                 :             :                                                  gint64       *timeout_usec,
     339                 :             :                                                  GPollFD      *fds,
     340                 :             :                                                  gint          n_fds);
     341                 :             : static gboolean g_main_context_check_unlocked   (GMainContext *context,
     342                 :             :                                                  gint          max_priority,
     343                 :             :                                                  GPollFD      *fds,
     344                 :             :                                                  gint          n_fds);
     345                 :             : static void g_main_context_dispatch_unlocked    (GMainContext *context);
     346                 :             : static void g_main_context_poll_unlocked        (GMainContext *context,
     347                 :             :                                                  gint64        timeout_usec,
     348                 :             :                                                  int           priority,
     349                 :             :                                                  GPollFD      *fds,
     350                 :             :                                                  int           n_fds);
     351                 :             : static void g_main_context_add_poll_unlocked    (GMainContext *context,
     352                 :             :                                                  gint          priority,
     353                 :             :                                                  GPollFD      *fd);
     354                 :             : static void g_main_context_remove_poll_unlocked (GMainContext *context,
     355                 :             :                                                  GPollFD      *fd);
     356                 :             : 
     357                 :             : static void     g_source_iter_init  (GSourceIter   *iter,
     358                 :             :                                      GMainContext  *context,
     359                 :             :                                      gboolean       may_modify);
     360                 :             : static gboolean g_source_iter_next  (GSourceIter   *iter,
     361                 :             :                                      GSource      **source);
     362                 :             : static void     g_source_iter_clear (GSourceIter   *iter);
     363                 :             : 
     364                 :             : static gboolean g_timeout_dispatch (GSource     *source,
     365                 :             :                                     GSourceFunc  callback,
     366                 :             :                                     gpointer     user_data);
     367                 :             : static gboolean g_child_watch_prepare  (GSource     *source,
     368                 :             :                                         gint        *timeout);
     369                 :             : static gboolean g_child_watch_check    (GSource     *source);
     370                 :             : static gboolean g_child_watch_dispatch (GSource     *source,
     371                 :             :                                         GSourceFunc  callback,
     372                 :             :                                         gpointer     user_data);
     373                 :             : static void     g_child_watch_finalize (GSource     *source);
     374                 :             : 
     375                 :             : #ifndef G_OS_WIN32
     376                 :             : static void unref_unix_signal_handler_unlocked (int signum);
     377                 :             : #endif
     378                 :             : 
     379                 :             : #ifdef G_OS_UNIX
     380                 :             : static void g_unix_signal_handler (int signum);
     381                 :             : static gboolean g_unix_signal_watch_prepare  (GSource     *source,
     382                 :             :                                               gint        *timeout);
     383                 :             : static gboolean g_unix_signal_watch_check    (GSource     *source);
     384                 :             : static gboolean g_unix_signal_watch_dispatch (GSource     *source,
     385                 :             :                                               GSourceFunc  callback,
     386                 :             :                                               gpointer     user_data);
     387                 :             : static void     g_unix_signal_watch_finalize  (GSource     *source);
     388                 :             : #endif
     389                 :             : static gboolean g_idle_prepare     (GSource     *source,
     390                 :             :                                     gint        *timeout);
     391                 :             : static gboolean g_idle_check       (GSource     *source);
     392                 :             : static gboolean g_idle_dispatch    (GSource     *source,
     393                 :             :                                     GSourceFunc  callback,
     394                 :             :                                     gpointer     user_data);
     395                 :             : 
     396                 :             : static void block_source (GSource      *source,
     397                 :             :                           GMainContext *context);
     398                 :             : static GMainContext *source_dup_main_context (GSource *source);
     399                 :             : 
     400                 :             : /* Lock for serializing access for safe execution of
     401                 :             :  * g_main_context_unref() with concurrent use of
     402                 :             :  * g_source_destroy() and g_source_unref().
     403                 :             :  *
     404                 :             :  * Locking order is source_destroy_lock, then context lock.
     405                 :             :  */
     406                 :             : static GRWLock source_destroy_lock;
     407                 :             : 
     408                 :             : static GMainContext *glib_worker_context;
     409                 :             : 
     410                 :             : #ifndef G_OS_WIN32
     411                 :             : 
     412                 :             : 
     413                 :             : /* UNIX signals work by marking one of these variables then waking the
     414                 :             :  * worker context to check on them and dispatch accordingly.
     415                 :             :  *
     416                 :             :  * Both variables must be accessed using atomic primitives, unless those atomic
     417                 :             :  * primitives are implemented using fallback mutexes (as those aren’t safe in
     418                 :             :  * an interrupt context).
     419                 :             :  *
     420                 :             :  * If using atomic primitives, the variables must be of type `int` (so they’re
     421                 :             :  * the right size for the atomic primitives). Otherwise, use `sig_atomic_t` if
     422                 :             :  * it’s available, which is guaranteed to be async-signal-safe (but it’s *not*
     423                 :             :  * guaranteed to be thread-safe, which is why we use atomic primitives if
     424                 :             :  * possible).
     425                 :             :  *
     426                 :             :  * Typically, `sig_atomic_t` is a typedef to `int`, but that’s not the case on
     427                 :             :  * FreeBSD, so we can’t use it unconditionally if it’s defined.
     428                 :             :  */
     429                 :             : #if (defined(G_ATOMIC_LOCK_FREE) && defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4)) || !defined(HAVE_SIG_ATOMIC_T)
     430                 :             : static volatile int unix_signal_pending[NSIG];
     431                 :             : static volatile int any_unix_signal_pending;
     432                 :             : #else
     433                 :             : static volatile sig_atomic_t unix_signal_pending[NSIG];
     434                 :             : static volatile sig_atomic_t any_unix_signal_pending;
     435                 :             : #endif
     436                 :             : 
     437                 :             : /* Guards all the data below */
     438                 :             : G_LOCK_DEFINE_STATIC (unix_signal_lock);
     439                 :             : static guint unix_signal_refcount[NSIG];
     440                 :             : static GSList *unix_signal_watches;
     441                 :             : static GSList *unix_child_watches;
     442                 :             : 
     443                 :             : GSourceFuncs g_unix_signal_funcs =
     444                 :             : {
     445                 :             :   g_unix_signal_watch_prepare,
     446                 :             :   g_unix_signal_watch_check,
     447                 :             :   g_unix_signal_watch_dispatch,
     448                 :             :   g_unix_signal_watch_finalize,
     449                 :             :   NULL, NULL
     450                 :             : };
     451                 :             : #endif /* !G_OS_WIN32 */
     452                 :             : 
     453                 :             : GSourceFuncs g_timeout_funcs =
     454                 :             : {
     455                 :             :   NULL, /* prepare */
     456                 :             :   NULL, /* check */
     457                 :             :   g_timeout_dispatch,
     458                 :             :   NULL, NULL, NULL
     459                 :             : };
     460                 :             : 
     461                 :             : GSourceFuncs g_child_watch_funcs =
     462                 :             : {
     463                 :             :   g_child_watch_prepare,
     464                 :             :   g_child_watch_check,
     465                 :             :   g_child_watch_dispatch,
     466                 :             :   g_child_watch_finalize,
     467                 :             :   NULL, NULL
     468                 :             : };
     469                 :             : 
     470                 :             : GSourceFuncs g_idle_funcs =
     471                 :             : {
     472                 :             :   g_idle_prepare,
     473                 :             :   g_idle_check,
     474                 :             :   g_idle_dispatch,
     475                 :             :   NULL, NULL, NULL
     476                 :             : };
     477                 :             : 
     478                 :             : /**
     479                 :             :  * g_main_context_ref:
     480                 :             :  * @context: (not nullable): a main context
     481                 :             :  * 
     482                 :             :  * Increases the reference count on a [struct@GLib.MainContext] object by one.
     483                 :             :  *
     484                 :             :  * Returns: the @context that was passed in (since 2.6)
     485                 :             :  **/
     486                 :             : GMainContext *
     487                 :      587690 : g_main_context_ref (GMainContext *context)
     488                 :             : {
     489                 :             :   int old_ref_count;
     490                 :             : 
     491                 :      587690 :   g_return_val_if_fail (context != NULL, NULL);
     492                 :             : 
     493                 :      587690 :   old_ref_count = g_atomic_int_add (&context->ref_count, 1);
     494                 :      587690 :   g_return_val_if_fail (old_ref_count > 0, NULL);
     495                 :             : 
     496                 :      587690 :   return context;
     497                 :       18211 : }
     498                 :             : 
     499                 :             : static inline void
     500                 :       30586 : poll_rec_list_free (GMainContext *context,
     501                 :             :                     GPollRec     *list)
     502                 :             : {
     503                 :       30586 :   g_slice_free_chain (GPollRec, list, next);
     504                 :       30586 : }
     505                 :             : 
     506                 :             : /**
     507                 :             :  * g_main_context_unref:
     508                 :             :  * @context: (not nullable): a main context
     509                 :             :  * 
     510                 :             :  * Decreases the reference count on a [struct@GLib.MainContext] object by one.
     511                 :             :  * If
     512                 :             :  * the result is zero, free the context and free all associated memory.
     513                 :             :  **/
     514                 :             : void
     515                 :     2457553 : g_main_context_unref (GMainContext *context)
     516                 :             : {
     517                 :             :   GSourceIter iter;
     518                 :             :   GSource *source;
     519                 :             :   GList *sl_iter;
     520                 :     2457553 :   GSList *s_iter, *remaining_sources = NULL;
     521                 :             :   GSourceList *list;
     522                 :             :   guint i;
     523                 :             :   guint old_ref;
     524                 :             :   GSource **pending_dispatches;
     525                 :             :   gsize pending_dispatches_len;
     526                 :             : 
     527                 :     4375257 :   g_return_if_fail (context != NULL);
     528                 :     2457553 :   g_return_if_fail (g_atomic_int_get (&context->ref_count) > 0); 
     529                 :             : 
     530                 :     1937012 : retry_decrement:
     531                 :     2458707 :   old_ref = g_atomic_int_get (&context->ref_count);
     532                 :     2458707 :   if (old_ref > 1)
     533                 :             :     {
     534                 :     2428121 :       if (!g_atomic_int_compare_and_exchange (&context->ref_count, old_ref, old_ref - 1))
     535                 :        1154 :         goto retry_decrement;
     536                 :             : 
     537                 :     2426967 :       return;
     538                 :             :     }
     539                 :             : 
     540                 :       30586 :   g_rw_lock_writer_lock (&source_destroy_lock);
     541                 :             : 
     542                 :             :   /* if a weak ref got to the source_destroy lock first, we need to retry */
     543                 :       30586 :   old_ref = g_atomic_int_add (&context->ref_count, -1);
     544                 :       30586 :   if (old_ref != 1)
     545                 :             :     {
     546                 :           0 :       g_rw_lock_writer_unlock (&source_destroy_lock);
     547                 :           0 :       return;
     548                 :             :     }
     549                 :             : 
     550                 :       30586 :   LOCK_CONTEXT (context);
     551                 :       30586 :   pending_dispatches = (GSource **) g_ptr_array_steal (context->pending_dispatches, &pending_dispatches_len);
     552                 :       30586 :   UNLOCK_CONTEXT (context);
     553                 :             : 
     554                 :             :   /* Free pending dispatches */
     555                 :       30588 :   for (i = 0; i < pending_dispatches_len; i++)
     556                 :           2 :     g_source_unref_internal (pending_dispatches[i], context, FALSE);
     557                 :             : 
     558                 :       30586 :   g_clear_pointer (&pending_dispatches, g_free);
     559                 :             : 
     560                 :             :   /* g_source_iter_next() assumes the context is locked. */
     561                 :       30586 :   LOCK_CONTEXT (context);
     562                 :             : 
     563                 :             :   /* First collect all remaining sources from the sources lists and store a
     564                 :             :    * new reference in a separate list. Also set the context of the sources
     565                 :             :    * to NULL so that they can't access a partially destroyed context anymore.
     566                 :             :    *
     567                 :             :    * We have to do this first so that we have a strong reference to all
     568                 :             :    * sources and destroying them below does not also free them, and so that
     569                 :             :    * none of the sources can access the context from their finalize/dispose
     570                 :             :    * functions. */
     571                 :       30586 :   g_source_iter_init (&iter, context, FALSE);
     572                 :       30629 :   while (g_source_iter_next (&iter, &source))
     573                 :             :     {
     574                 :          43 :       source->context = NULL;
     575                 :          43 :       remaining_sources = g_slist_prepend (remaining_sources, g_source_ref (source));
     576                 :             :     }
     577                 :       30586 :   g_source_iter_clear (&iter);
     578                 :             : 
     579                 :       30586 :   g_rw_lock_writer_unlock (&source_destroy_lock);
     580                 :             : 
     581                 :             :   /* Next destroy all sources. As we still hold a reference to all of them,
     582                 :             :    * this won't cause any of them to be freed yet and especially prevents any
     583                 :             :    * source that unrefs another source from its finalize function to be freed.
     584                 :             :    */
     585                 :       30629 :   for (s_iter = remaining_sources; s_iter; s_iter = s_iter->next)
     586                 :             :     {
     587                 :          43 :       source = s_iter->data;
     588                 :          43 :       g_source_destroy_internal (source, context, TRUE);
     589                 :          21 :     }
     590                 :             : 
     591                 :             :   /* the context is going to die now */
     592                 :       30586 :   g_return_if_fail (old_ref > 0);
     593                 :             : 
     594                 :       30586 :   sl_iter = context->source_lists.head;
     595                 :       30615 :   while (sl_iter != NULL)
     596                 :             :     {
     597                 :          29 :       list = sl_iter->data;
     598                 :          29 :       sl_iter = sl_iter->next;
     599                 :          29 :       g_slice_free (GSourceList, list);
     600                 :             :     }
     601                 :             : 
     602                 :       30586 :   g_hash_table_remove_all (context->sources);
     603                 :             : 
     604                 :       30586 :   UNLOCK_CONTEXT (context);
     605                 :             : 
     606                 :             :   /* if the object has been reffed meanwhile by an internal weak ref, keep the
     607                 :             :    * resources alive until the last reference is gone.
     608                 :             :    */
     609                 :       30586 :   if (old_ref == 1)
     610                 :             :     {
     611                 :       30586 :       g_mutex_clear (&context->mutex);
     612                 :             : 
     613                 :       30586 :       g_ptr_array_free (context->pending_dispatches, TRUE);
     614                 :       30586 :       g_free (context->cached_poll_array);
     615                 :             : 
     616                 :       30586 :       poll_rec_list_free (context, context->poll_records);
     617                 :             : 
     618                 :       30586 :       g_wakeup_free (context->wakeup);
     619                 :       30586 :       g_cond_clear (&context->cond);
     620                 :             : 
     621                 :       30586 :       g_hash_table_unref (context->sources);
     622                 :             : 
     623                 :       30586 :       g_free (context);
     624                 :       12377 :     }
     625                 :             : 
     626                 :             :   /* And now finally get rid of our references to the sources. This will cause
     627                 :             :    * them to be freed unless something else still has a reference to them. Due
     628                 :             :    * to setting the context pointers in the sources to NULL above, this won't
     629                 :             :    * ever access the context or the internal linked list inside the GSource.
     630                 :             :    * We already removed the sources completely from the context above. */
     631                 :       30629 :   for (s_iter = remaining_sources; s_iter; s_iter = s_iter->next)
     632                 :             :     {
     633                 :          43 :       source = s_iter->data;
     634                 :          43 :       g_source_unref_internal (source, NULL, FALSE);
     635                 :          21 :     }
     636                 :       30586 :   g_slist_free (remaining_sources);
     637                 :      521640 : }
     638                 :             : 
     639                 :             : /* Helper function used by mainloop/overflow test.
     640                 :             :  */
     641                 :             : GMainContext *
     642                 :           2 : g_main_context_new_with_next_id (guint next_id)
     643                 :             : {
     644                 :           2 :   GMainContext *ret = g_main_context_new ();
     645                 :             :   
     646                 :           2 :   ret->next_id = next_id;
     647                 :             :   
     648                 :           2 :   return ret;
     649                 :             : }
     650                 :             : 
     651                 :             : /**
     652                 :             :  * g_main_context_new:
     653                 :             :  *
     654                 :             :  * Creates a new [struct@GLib.MainContext] structure.
     655                 :             :  *
     656                 :             :  * Returns: (transfer full): the new main context
     657                 :             :  **/
     658                 :             : GMainContext *
     659                 :       31315 : g_main_context_new (void)
     660                 :             : {
     661                 :       31315 :   return g_main_context_new_with_flags (G_MAIN_CONTEXT_FLAGS_NONE);
     662                 :             : }
     663                 :             : 
     664                 :             : /**
     665                 :             :  * g_main_context_new_with_flags:
     666                 :             :  * @flags: a bitwise-OR combination of flags that can only be set at creation
     667                 :             :  *   time
     668                 :             :  *
     669                 :             :  * Creates a new [struct@GLib.MainContext] structure.
     670                 :             :  *
     671                 :             :  * Returns: (transfer full): the new main context
     672                 :             :  * Since: 2.72
     673                 :             :  */
     674                 :             : GMainContext *
     675                 :       31319 : g_main_context_new_with_flags (GMainContextFlags flags)
     676                 :             : {
     677                 :             :   static gsize initialised;
     678                 :             :   GMainContext *context;
     679                 :             : 
     680                 :       31319 :   if (g_once_init_enter (&initialised))
     681                 :             :     {
     682                 :             : #ifdef G_MAIN_POLL_DEBUG
     683                 :         129 :       if (g_getenv ("G_MAIN_POLL_DEBUG") != NULL)
     684                 :           0 :         _g_main_poll_debug = TRUE;
     685                 :             : #endif
     686                 :             : 
     687                 :         443 :       g_once_init_leave (&initialised, TRUE);
     688                 :         129 :     }
     689                 :             : 
     690                 :       31319 :   context = g_new0 (GMainContext, 1);
     691                 :             : 
     692                 :       18790 :   TRACE (GLIB_MAIN_CONTEXT_NEW (context));
     693                 :             : 
     694                 :       31319 :   g_mutex_init (&context->mutex);
     695                 :       31319 :   g_cond_init (&context->cond);
     696                 :             : 
     697                 :       31319 :   context->sources = g_hash_table_new (g_uint_hash, g_uint_equal);
     698                 :       31319 :   context->owner = NULL;
     699                 :       31319 :   context->flags = flags;
     700                 :       31319 :   context->waiters = NULL;
     701                 :             : 
     702                 :       31319 :   context->ref_count = 1;
     703                 :             : 
     704                 :       31319 :   context->next_id = 1;
     705                 :             : 
     706                 :       31319 :   context->poll_func = g_poll;
     707                 :             :   
     708                 :       31319 :   context->cached_poll_array = NULL;
     709                 :       31319 :   context->cached_poll_array_size = 0;
     710                 :             :   
     711                 :       31319 :   context->pending_dispatches = g_ptr_array_new ();
     712                 :             :   
     713                 :       31319 :   context->time_is_fresh = FALSE;
     714                 :             :   
     715                 :       31319 :   context->wakeup = g_wakeup_new ();
     716                 :       31319 :   g_wakeup_get_pollfd (context->wakeup, &context->wake_up_rec);
     717                 :       31319 :   g_main_context_add_poll_unlocked (context, 0, &context->wake_up_rec);
     718                 :             : 
     719                 :             : #ifdef G_MAIN_POLL_DEBUG
     720                 :       12529 :   if (_g_main_poll_debug)
     721                 :           0 :     g_print ("created context=%p\n", context);
     722                 :             : #endif
     723                 :             : 
     724                 :       31319 :   return context;
     725                 :             : }
     726                 :             : 
     727                 :             : /**
     728                 :             :  * g_main_context_default:
     729                 :             :  *
     730                 :             :  * Returns the global-default main context.
     731                 :             :  *
     732                 :             :  * This is the main context
     733                 :             :  * used for main loop functions when a main loop is not explicitly
     734                 :             :  * specified, and corresponds to the ‘main’ main loop. See also
     735                 :             :  * [func@GLib.MainContext.get_thread_default].
     736                 :             :  *
     737                 :             :  * Returns: (transfer none): the global-default main context.
     738                 :             :  **/
     739                 :             : GMainContext *
     740                 :      970885 : g_main_context_default (void)
     741                 :             : {
     742                 :             :   static GMainContext *default_main_context = NULL;
     743                 :             : 
     744                 :      970885 :   if (g_once_init_enter_pointer (&default_main_context))
     745                 :             :     {
     746                 :             :       GMainContext *context;
     747                 :             : 
     748                 :         294 :       context = g_main_context_new ();
     749                 :             : 
     750                 :         210 :       TRACE (GLIB_MAIN_CONTEXT_DEFAULT (context));
     751                 :             : 
     752                 :             : #ifdef G_MAIN_POLL_DEBUG
     753                 :          84 :       if (_g_main_poll_debug)
     754                 :           0 :         g_print ("global-default main context=%p\n", context);
     755                 :             : #endif
     756                 :             : 
     757                 :         294 :       g_once_init_leave_pointer (&default_main_context, context);
     758                 :          84 :     }
     759                 :             : 
     760                 :      970885 :   return default_main_context;
     761                 :             : }
     762                 :             : 
     763                 :             : static void
     764                 :           3 : free_context (gpointer data)
     765                 :             : {
     766                 :           3 :   GMainContext *context = data;
     767                 :             : 
     768                 :           3 :   TRACE (GLIB_MAIN_CONTEXT_FREE (context));
     769                 :             : 
     770                 :           3 :   g_main_context_release (context);
     771                 :           3 :   if (context)
     772                 :           3 :     g_main_context_unref (context);
     773                 :           3 : }
     774                 :             : 
     775                 :             : static void
     776                 :        1118 : free_context_stack (gpointer data)
     777                 :             : {
     778                 :        1118 :   g_queue_free_full((GQueue *) data, (GDestroyNotify) free_context);
     779                 :        1118 : }
     780                 :             : 
     781                 :             : static GPrivate thread_context_stack = G_PRIVATE_INIT (free_context_stack);
     782                 :             : 
     783                 :             : /**
     784                 :             :  * g_main_context_push_thread_default:
     785                 :             :  * @context: (nullable): a main context, or `NULL` for the global-default
     786                 :             :  *   main context
     787                 :             :  *
     788                 :             :  * Acquires @context and sets it as the thread-default context for the
     789                 :             :  * current thread. This will cause certain asynchronous operations
     790                 :             :  * (such as most [Gio](../gio/index.html)-based I/O) which are
     791                 :             :  * started in this thread to run under @context and deliver their
     792                 :             :  * results to its main loop, rather than running under the global
     793                 :             :  * default main context in the main thread. Note that calling this function
     794                 :             :  * changes the context returned by [func@GLib.MainContext.get_thread_default],
     795                 :             :  * not the one returned by [func@GLib.MainContext.default], so it does not
     796                 :             :  * affect the context used by functions like [func@GLib.idle_add].
     797                 :             :  *
     798                 :             :  * Normally you would call this function shortly after creating a new
     799                 :             :  * thread, passing it a [struct@GLib.MainContext] which will be run by a
     800                 :             :  * [struct@GLib.MainLoop] in that thread, to set a new default context for all
     801                 :             :  * async operations in that thread. In this case you may not need to
     802                 :             :  * ever call [method@GLib.MainContext.pop_thread_default], assuming you want
     803                 :             :  * the new [struct@GLib.MainContext] to be the default for the whole lifecycle
     804                 :             :  * of the thread.
     805                 :             :  *
     806                 :             :  * If you don’t have control over how the new thread was created (e.g.
     807                 :             :  * in the new thread isn’t newly created, or if the thread life
     808                 :             :  * cycle is managed by a #GThreadPool), it is always suggested to wrap
     809                 :             :  * the logic that needs to use the new [struct@GLib.MainContext] inside a
     810                 :             :  * [method@GLib.MainContext.push_thread_default] /
     811                 :             :  * [method@GLib.MainContext.pop_thread_default] pair, otherwise threads that
     812                 :             :  * are re-used will end up never explicitly releasing the
     813                 :             :  * [struct@GLib.MainContext] reference they hold.
     814                 :             :  *
     815                 :             :  * In some cases you may want to schedule a single operation in a
     816                 :             :  * non-default context, or temporarily use a non-default context in
     817                 :             :  * the main thread. In that case, you can wrap the call to the
     818                 :             :  * asynchronous operation inside a
     819                 :             :  * [method@GLib.MainContext.push_thread_default] /
     820                 :             :  * [method@GLib.MainContext.pop_thread_default] pair, but it is up to you to
     821                 :             :  * ensure that no other asynchronous operations accidentally get
     822                 :             :  * started while the non-default context is active.
     823                 :             :  *
     824                 :             :  * Beware that libraries that predate this function may not correctly
     825                 :             :  * handle being used from a thread with a thread-default context. For example,
     826                 :             :  * see `g_file_supports_thread_contexts()`.
     827                 :             :  *
     828                 :             :  * Since: 2.22
     829                 :             :  **/
     830                 :             : void
     831                 :      148880 : g_main_context_push_thread_default (GMainContext *context)
     832                 :             : {
     833                 :             :   GQueue *stack;
     834                 :             :   gboolean acquired_context;
     835                 :             : 
     836                 :      148880 :   acquired_context = g_main_context_acquire (context);
     837                 :      148880 :   g_return_if_fail (acquired_context);
     838                 :             : 
     839                 :      148880 :   if (context == g_main_context_default ())
     840                 :       43203 :     context = NULL;
     841                 :      105677 :   else if (context)
     842                 :      105675 :     g_main_context_ref (context);
     843                 :             : 
     844                 :      148880 :   stack = g_private_get (&thread_context_stack);
     845                 :      148880 :   if (!stack)
     846                 :             :     {
     847                 :        1431 :       stack = g_queue_new ();
     848                 :        1431 :       g_private_set (&thread_context_stack, stack);
     849                 :          72 :     }
     850                 :             : 
     851                 :      148880 :   g_queue_push_head (stack, context);
     852                 :             : 
     853                 :      144229 :   TRACE (GLIB_MAIN_CONTEXT_PUSH_THREAD_DEFAULT (context));
     854                 :        4651 : }
     855                 :             : 
     856                 :             : /**
     857                 :             :  * g_main_context_pop_thread_default:
     858                 :             :  * @context: (nullable): a main context, or `NULL` for the global-default
     859                 :             :  *   main context
     860                 :             :  *
     861                 :             :  * Pops @context off the thread-default context stack (verifying that
     862                 :             :  * it was on the top of the stack).
     863                 :             :  *
     864                 :             :  * Since: 2.22
     865                 :             :  **/
     866                 :             : void
     867                 :      148772 : g_main_context_pop_thread_default (GMainContext *context)
     868                 :             : {
     869                 :             :   GQueue *stack;
     870                 :             : 
     871                 :      148772 :   if (context == g_main_context_default ())
     872                 :       43203 :     context = NULL;
     873                 :             : 
     874                 :      148772 :   stack = g_private_get (&thread_context_stack);
     875                 :             : 
     876                 :      148772 :   g_return_if_fail (stack != NULL);
     877                 :      148772 :   g_return_if_fail (g_queue_peek_head (stack) == context);
     878                 :             : 
     879                 :      144126 :   TRACE (GLIB_MAIN_CONTEXT_POP_THREAD_DEFAULT (context));
     880                 :             : 
     881                 :      148772 :   g_queue_pop_head (stack);
     882                 :             : 
     883                 :      148772 :   g_main_context_release (context);
     884                 :      148772 :   if (context)
     885                 :      105567 :     g_main_context_unref (context);
     886                 :        4646 : }
     887                 :             : 
     888                 :             : /**
     889                 :             :  * g_main_context_get_thread_default:
     890                 :             :  *
     891                 :             :  * Gets the thread-default main context for this thread.
     892                 :             :  *
     893                 :             :  * Asynchronous operations that want to be able to be run in contexts other than
     894                 :             :  * the default one should call this method or
     895                 :             :  * [func@GLib.MainContext.ref_thread_default] to get a
     896                 :             :  * [struct@GLib.MainContext] to add their [struct@GLib.Source]s to. (Note that
     897                 :             :  * even in single-threaded programs applications may sometimes want to
     898                 :             :  * temporarily push a non-default context, so it is not safe to assume that
     899                 :             :  * this will always return `NULL` if you are running in the default thread.)
     900                 :             :  *
     901                 :             :  * If you need to hold a reference on the context, use
     902                 :             :  * [func@GLib.MainContext.ref_thread_default] instead.
     903                 :             :  *
     904                 :             :  * Returns: (transfer none) (nullable): the thread-default main context, or
     905                 :             :  *   `NULL` if the thread-default context is the global-default main context
     906                 :             :  * Since: 2.22
     907                 :             :  **/
     908                 :             : GMainContext *
     909                 :      454353 : g_main_context_get_thread_default (void)
     910                 :             : {
     911                 :             :   GQueue *stack;
     912                 :             : 
     913                 :      454353 :   stack = g_private_get (&thread_context_stack);
     914                 :      454353 :   if (stack)
     915                 :      352380 :     return g_queue_peek_head (stack);
     916                 :             :   else
     917                 :      101973 :     return NULL;
     918                 :        6216 : }
     919                 :             : 
     920                 :             : /**
     921                 :             :  * g_main_context_ref_thread_default:
     922                 :             :  *
     923                 :             :  * Gets a reference to the thread-default [struct@GLib.MainContext] for this
     924                 :             :  * thread
     925                 :             :  *
     926                 :             :  * This is the same as [func@GLib.MainContext.get_thread_default], but it also
     927                 :             :  * adds a reference to the returned main context with [method@GLib.MainContext.ref].
     928                 :             :  * In addition, unlike
     929                 :             :  * [func@GLib.MainContext.get_thread_default], if the thread-default context
     930                 :             :  * is the global-default context, this will return that
     931                 :             :  * [struct@GLib.MainContext] (with a ref added to it) rather than returning
     932                 :             :  * `NULL`.
     933                 :             :  *
     934                 :             :  * Returns: (transfer full) (not nullable): the thread-default main context
     935                 :             :  * Since: 2.32
     936                 :             :  */
     937                 :             : GMainContext *
     938                 :      450685 : g_main_context_ref_thread_default (void)
     939                 :             : {
     940                 :             :   GMainContext *context;
     941                 :             : 
     942                 :      450685 :   context = g_main_context_get_thread_default ();
     943                 :      450685 :   if (!context)
     944                 :      150544 :     context = g_main_context_default ();
     945                 :      450685 :   return g_main_context_ref (context);
     946                 :             : }
     947                 :             : 
     948                 :             : /* Hooks for adding to the main loop */
     949                 :             : 
     950                 :             : /**
     951                 :             :  * g_source_new:
     952                 :             :  * @source_funcs: structure containing functions that implement
     953                 :             :  *   the source‘s behavior
     954                 :             :  * @struct_size: size of the [struct@GLib.Source] structure to create, in bytes
     955                 :             :  * 
     956                 :             :  * Creates a new [struct@GLib.Source] structure.
     957                 :             :  *
     958                 :             :  * The size is specified to
     959                 :             :  * allow creating structures derived from [struct@GLib.Source] that contain
     960                 :             :  * additional data. The size passed in must be at least
     961                 :             :  * `sizeof (GSource)`.
     962                 :             :  * 
     963                 :             :  * The source will not initially be associated with any [struct@GLib.MainContext]
     964                 :             :  * and must be added to one with [method@GLib.Source.attach] before it will be
     965                 :             :  * executed.
     966                 :             :  * 
     967                 :             :  * Returns: (transfer full): the newly-created source
     968                 :             :  **/
     969                 :             : GSource *
     970                 :     1014580 : g_source_new (GSourceFuncs *source_funcs,
     971                 :             :               guint         struct_size)
     972                 :             : {
     973                 :             :   GSource *source;
     974                 :             : 
     975                 :     1014580 :   g_return_val_if_fail (source_funcs != NULL, NULL);
     976                 :     1014580 :   g_return_val_if_fail (struct_size >= sizeof (GSource), NULL);
     977                 :             :   
     978                 :     1014580 :   source = (GSource*) g_malloc0 (struct_size);
     979                 :     1014580 :   source->priv = g_slice_new0 (GSourcePrivate);
     980                 :     1014580 :   source->source_funcs = source_funcs;
     981                 :     1014580 :   g_atomic_int_set (&source->ref_count, 1);
     982                 :             :   
     983                 :     1014580 :   source->priority = G_PRIORITY_DEFAULT;
     984                 :             : 
     985                 :     1014580 :   g_atomic_int_set (&source->flags, G_HOOK_FLAG_ACTIVE);
     986                 :             : 
     987                 :     1014580 :   source->priv->ready_time = -1;
     988                 :             : 
     989                 :             :   /* NULL/0 initialization for all other fields */
     990                 :             : 
     991                 :      746878 :   TRACE (GLIB_SOURCE_NEW (source, source_funcs->prepare, source_funcs->check,
     992                 :             :                           source_funcs->dispatch, source_funcs->finalize,
     993                 :             :                           struct_size));
     994                 :             : 
     995                 :     1014580 :   return source;
     996                 :      267702 : }
     997                 :             : 
     998                 :             : /**
     999                 :             :  * g_source_set_dispose_function:
    1000                 :             :  * @source: a source to set the dispose function on
    1001                 :             :  * @dispose: dispose function to set on the source
    1002                 :             :  *
    1003                 :             :  * Set @dispose as dispose function on @source.
    1004                 :             :  *
    1005                 :             :  * The @dispose function will be called once the reference count of @source
    1006                 :             :  * reaches zero but before any of the state of the source is freed, especially
    1007                 :             :  * before the finalize function (set as part of the [type@GLib.SourceFuncs]) is
    1008                 :             :  * called.
    1009                 :             :  *
    1010                 :             :  * This means that at this point @source is still a valid [struct@GLib.Source]
    1011                 :             :  * and it is allow for the reference count to increase again until @dispose
    1012                 :             :  * returns.
    1013                 :             :  *
    1014                 :             :  * The dispose function can be used to clear any ‘weak’ references to
    1015                 :             :  * the @source in other data structures in a thread-safe way where it is
    1016                 :             :  * possible for another thread to increase the reference count of @source again
    1017                 :             :  * while it is being freed.
    1018                 :             :  *
    1019                 :             :  * The finalize function can not be used for this purpose as at that
    1020                 :             :  * point @source is already partially freed and not valid any more.
    1021                 :             :  *
    1022                 :             :  * This should only ever be called from [struct@GLib.Source] implementations.
    1023                 :             :  *
    1024                 :             :  * Since: 2.64
    1025                 :             :  **/
    1026                 :             : void
    1027                 :      215135 : g_source_set_dispose_function (GSource            *source,
    1028                 :             :                                GSourceDisposeFunc  dispose)
    1029                 :             : {
    1030                 :             :   gboolean was_unset G_GNUC_UNUSED;
    1031                 :             : 
    1032                 :      215135 :   g_return_if_fail (source != NULL);
    1033                 :      215135 :   g_return_if_fail (g_atomic_int_get (&source->ref_count) > 0);
    1034                 :             : 
    1035                 :      315349 :   was_unset = g_atomic_pointer_compare_and_exchange (&source->priv->dispose,
    1036                 :      100214 :                                                      NULL, dispose);
    1037                 :      215135 :   g_return_if_fail (was_unset);
    1038                 :      100214 : }
    1039                 :             : 
    1040                 :             : /* Holds context's lock */
    1041                 :             : static void
    1042                 :     2230559 : g_source_iter_init (GSourceIter  *iter,
    1043                 :             :                     GMainContext *context,
    1044                 :             :                     gboolean      may_modify)
    1045                 :             : {
    1046                 :     2230559 :   iter->context = context;
    1047                 :     2230559 :   iter->current_list = NULL;
    1048                 :     2230559 :   iter->source = NULL;
    1049                 :     2230559 :   iter->may_modify = may_modify;
    1050                 :     2230559 : }
    1051                 :             : 
    1052                 :             : /* Holds context's lock */
    1053                 :             : static gboolean
    1054                 :     5932815 : g_source_iter_next (GSourceIter *iter, GSource **source)
    1055                 :             : {
    1056                 :             :   GSource *next_source;
    1057                 :             : 
    1058                 :     5932815 :   if (iter->source)
    1059                 :     3702257 :     next_source = iter->source->next;
    1060                 :             :   else
    1061                 :     2230558 :     next_source = NULL;
    1062                 :             : 
    1063                 :     5932815 :   if (!next_source)
    1064                 :             :     {
    1065                 :     4589005 :       if (iter->current_list)
    1066                 :     2358442 :         iter->current_list = iter->current_list->next;
    1067                 :             :       else
    1068                 :     2230563 :         iter->current_list = iter->context->source_lists.head;
    1069                 :             : 
    1070                 :     4589005 :       if (iter->current_list)
    1071                 :             :         {
    1072                 :     2689838 :           GSourceList *source_list = iter->current_list->data;
    1073                 :             : 
    1074                 :     2689838 :           next_source = source_list->head;
    1075                 :      530628 :         }
    1076                 :     1037225 :     }
    1077                 :             : 
    1078                 :             :   /* Note: unreffing iter->source could potentially cause its
    1079                 :             :    * GSourceList to be removed from source_lists (if iter->source is
    1080                 :             :    * the only source in its list, and it is destroyed), so we have to
    1081                 :             :    * keep it reffed until after we advance iter->current_list, above.
    1082                 :             :    *
    1083                 :             :    * Also we first have to ref the next source before unreffing the
    1084                 :             :    * previous one as unreffing the previous source can potentially
    1085                 :             :    * free the next one.
    1086                 :             :    */
    1087                 :     5932815 :   if (next_source && iter->may_modify)
    1088                 :     4033602 :     g_source_ref (next_source);
    1089                 :             : 
    1090                 :     5932815 :   if (iter->source && iter->may_modify)
    1091                 :     3702210 :     g_source_unref_internal (iter->source, iter->context, TRUE);
    1092                 :     5932815 :   iter->source = next_source;
    1093                 :             : 
    1094                 :     5932815 :   *source = iter->source;
    1095                 :     5932815 :   return *source != NULL;
    1096                 :             : }
    1097                 :             : 
    1098                 :             : /* Holds context's lock. Only necessary to call if you broke out of
    1099                 :             :  * the g_source_iter_next() loop early.
    1100                 :             :  */
    1101                 :             : static void
    1102                 :     2230563 : g_source_iter_clear (GSourceIter *iter)
    1103                 :             : {
    1104                 :     2230563 :   if (iter->source && iter->may_modify)
    1105                 :             :     {
    1106                 :      331396 :       g_source_unref_internal (iter->source, iter->context, TRUE);
    1107                 :      331396 :       iter->source = NULL;
    1108                 :          65 :     }
    1109                 :     2230563 : }
    1110                 :             : 
    1111                 :             : /* Holds context's lock
    1112                 :             :  */
    1113                 :             : static GSourceList *
    1114                 :     1627649 : find_source_list_for_priority (GMainContext *context,
    1115                 :             :                                gint          priority,
    1116                 :             :                                gboolean      create)
    1117                 :             : {
    1118                 :             :   GList *iter;
    1119                 :             :   GSourceList *source_list;
    1120                 :             : 
    1121                 :    11618917 :   for (iter = context->source_lists.head; iter; iter = iter->next)
    1122                 :             :     {
    1123                 :    11396538 :       source_list = iter->data;
    1124                 :             : 
    1125                 :    11396538 :       if (source_list->priority == priority)
    1126                 :     1304910 :         return source_list;
    1127                 :             : 
    1128                 :    10091628 :       if (source_list->priority > priority)
    1129                 :             :         {
    1130                 :      100360 :           if (!create)
    1131                 :           0 :             return NULL;
    1132                 :             : 
    1133                 :      100360 :           source_list = g_slice_new0 (GSourceList);
    1134                 :      100360 :           source_list->link.data = source_list;
    1135                 :      100360 :           source_list->priority = priority;
    1136                 :      100616 :           g_queue_insert_before_link (&context->source_lists,
    1137                 :         256 :                                       iter,
    1138                 :         256 :                                       &source_list->link);
    1139                 :      100360 :           return source_list;
    1140                 :             :         }
    1141                 :     4945383 :     }
    1142                 :             : 
    1143                 :      222379 :   if (!create)
    1144                 :           0 :     return NULL;
    1145                 :             : 
    1146                 :      222379 :   source_list = g_slice_new0 (GSourceList);
    1147                 :      222379 :   source_list->link.data = source_list;
    1148                 :      222379 :   source_list->priority = priority;
    1149                 :      222379 :   g_queue_push_tail_link (&context->source_lists, &source_list->link);
    1150                 :             : 
    1151                 :      222379 :   return source_list;
    1152                 :      335249 : }
    1153                 :             : 
    1154                 :             : /* Holds context's lock
    1155                 :             :  */
    1156                 :             : static void
    1157                 :      814580 : source_add_to_context (GSource      *source,
    1158                 :             :                        GMainContext *context)
    1159                 :             : {
    1160                 :             :   GSourceList *source_list;
    1161                 :             :   GSource *prev, *next;
    1162                 :             : 
    1163                 :      814580 :   source_list = find_source_list_for_priority (context, source->priority, TRUE);
    1164                 :             : 
    1165                 :      814580 :   if (source->priv->parent_source)
    1166                 :             :     {
    1167                 :       15743 :       g_assert (source_list->head != NULL);
    1168                 :             : 
    1169                 :             :       /* Put the source immediately before its parent */
    1170                 :       15743 :       prev = source->priv->parent_source->prev;
    1171                 :       15743 :       next = source->priv->parent_source;
    1172                 :         199 :     }
    1173                 :             :   else
    1174                 :             :     {
    1175                 :      798837 :       prev = source_list->tail;
    1176                 :      798837 :       next = NULL;
    1177                 :             :     }
    1178                 :             : 
    1179                 :      814580 :   source->next = next;
    1180                 :      814580 :   if (next)
    1181                 :       15743 :     next->prev = source;
    1182                 :             :   else
    1183                 :      798837 :     source_list->tail = source;
    1184                 :             :   
    1185                 :      814580 :   source->prev = prev;
    1186                 :      814580 :   if (prev)
    1187                 :      491784 :     prev->next = source;
    1188                 :             :   else
    1189                 :      322796 :     source_list->head = source;
    1190                 :      814580 : }
    1191                 :             : 
    1192                 :             : /* Holds context's lock
    1193                 :             :  */
    1194                 :             : static void
    1195                 :      813069 : source_remove_from_context (GSource      *source,
    1196                 :             :                             GMainContext *context)
    1197                 :             : {
    1198                 :             :   GSourceList *source_list;
    1199                 :             : 
    1200                 :      813069 :   source_list = find_source_list_for_priority (context, source->priority, FALSE);
    1201                 :      813069 :   g_return_if_fail (source_list != NULL);
    1202                 :             : 
    1203                 :      813069 :   if (source->prev)
    1204                 :      354844 :     source->prev->next = source->next;
    1205                 :             :   else
    1206                 :      458225 :     source_list->head = source->next;
    1207                 :             : 
    1208                 :      813069 :   if (source->next)
    1209                 :      469610 :     source->next->prev = source->prev;
    1210                 :             :   else
    1211                 :      343459 :     source_list->tail = source->prev;
    1212                 :             : 
    1213                 :      813069 :   source->prev = NULL;
    1214                 :      813069 :   source->next = NULL;
    1215                 :             : 
    1216                 :      813069 :   if (source_list->head == NULL)
    1217                 :             :     {
    1218                 :      322254 :       g_queue_unlink (&context->source_lists, &source_list->link);
    1219                 :      322254 :       g_slice_free (GSourceList, source_list);
    1220                 :       14132 :     }
    1221                 :      167548 : }
    1222                 :             : 
    1223                 :             : static guint
    1224                 :      814569 : g_source_attach_unlocked (GSource      *source,
    1225                 :             :                           GMainContext *context,
    1226                 :             :                           gboolean      do_wakeup)
    1227                 :             : {
    1228                 :             :   GSList *tmp_list;
    1229                 :             :   guint id;
    1230                 :             : 
    1231                 :             :   /* The counter may have wrapped, so we must ensure that we do not
    1232                 :             :    * reuse the source id of an existing source.
    1233                 :             :    */
    1234                 :      167696 :   do
    1235                 :      982268 :     id = context->next_id++;
    1236                 :      814572 :   while (id == 0 || g_hash_table_contains (context->sources, &id));
    1237                 :             : 
    1238                 :      814569 :   source->context = context;
    1239                 :      814569 :   source->source_id = id;
    1240                 :      814569 :   g_source_ref (source);
    1241                 :             : 
    1242                 :      814569 :   g_hash_table_add (context->sources, &source->source_id);
    1243                 :             : 
    1244                 :      814569 :   source_add_to_context (source, context);
    1245                 :             : 
    1246                 :      814569 :   if (!SOURCE_BLOCKED (source))
    1247                 :             :     {
    1248                 :      814566 :       tmp_list = source->poll_fds;
    1249                 :      817102 :       while (tmp_list)
    1250                 :             :         {
    1251                 :        2536 :           g_main_context_add_poll_unlocked (context, source->priority, tmp_list->data);
    1252                 :        2536 :           tmp_list = tmp_list->next;
    1253                 :             :         }
    1254                 :             : 
    1255                 :      829607 :       for (tmp_list = source->priv->fds; tmp_list; tmp_list = tmp_list->next)
    1256                 :       15041 :         g_main_context_add_poll_unlocked (context, source->priority, tmp_list->data);
    1257                 :      167695 :     }
    1258                 :             : 
    1259                 :      814569 :   tmp_list = source->priv->child_sources;
    1260                 :      830298 :   while (tmp_list)
    1261                 :             :     {
    1262                 :       15729 :       g_source_attach_unlocked (tmp_list->data, context, FALSE);
    1263                 :       15729 :       tmp_list = tmp_list->next;
    1264                 :             :     }
    1265                 :             : 
    1266                 :             :   /* If another thread has acquired the context, wake it up since it
    1267                 :             :    * might be in poll() right now.
    1268                 :             :    */
    1269                 :      816770 :   if (do_wakeup &&
    1270                 :      798841 :       (context->flags & G_MAIN_CONTEXT_FLAGS_OWNERLESS_POLLING ||
    1271                 :      798837 :        (context->owner && context->owner != G_THREAD_SELF)))
    1272                 :             :     {
    1273                 :       67118 :       g_wakeup_signal (context->wakeup);
    1274                 :         692 :     }
    1275                 :             : 
    1276                 :     1280221 :   g_trace_mark (G_TRACE_CURRENT_TIME, 0,
    1277                 :             :                 "GLib", "g_source_attach",
    1278                 :             :                 "%s to context %p",
    1279                 :     1280221 :                 (g_source_get_name (source) != NULL) ? g_source_get_name (source) : "(unnamed)",
    1280                 :             :                 context);
    1281                 :             : 
    1282                 :      814569 :   return source->source_id;
    1283                 :             : }
    1284                 :             : 
    1285                 :             : /**
    1286                 :             :  * g_source_attach:
    1287                 :             :  * @source: a source
    1288                 :             :  * @context: (nullable): a main context (if `NULL`, the global-default
    1289                 :             :  *   main context will be used)
    1290                 :             :  * 
    1291                 :             :  * Adds a [struct@GLib.Source] to a @context so that it will be executed within
    1292                 :             :  * that context.
    1293                 :             :  *
    1294                 :             :  * Remove it by calling [method@GLib.Source.destroy].
    1295                 :             :  *
    1296                 :             :  * This function is safe to call from any thread, regardless of which thread
    1297                 :             :  * the @context is running in.
    1298                 :             :  *
    1299                 :             :  * Returns: the ID (greater than 0) for the source within the
    1300                 :             :  *   [struct@GLib.MainContext]
    1301                 :             :  **/
    1302                 :             : guint
    1303                 :      798819 : g_source_attach (GSource      *source,
    1304                 :             :                  GMainContext *context)
    1305                 :             : {
    1306                 :      798819 :   guint result = 0;
    1307                 :             : 
    1308                 :      798819 :   g_return_val_if_fail (source != NULL, 0);
    1309                 :      798819 :   g_return_val_if_fail (g_atomic_int_get (&source->ref_count) > 0, 0);
    1310                 :      798819 :   g_return_val_if_fail (source->context == NULL, 0);
    1311                 :      798819 :   g_return_val_if_fail (!SOURCE_DESTROYED (source), 0);
    1312                 :             :   
    1313                 :      798819 :   if (!context)
    1314                 :        4012 :     context = g_main_context_default ();
    1315                 :             : 
    1316                 :      798819 :   LOCK_CONTEXT (context);
    1317                 :             : 
    1318                 :      798819 :   result = g_source_attach_unlocked (source, context, TRUE);
    1319                 :             : 
    1320                 :      631331 :   TRACE (GLIB_MAIN_SOURCE_ATTACH (g_source_get_name (source), source, context,
    1321                 :             :                                   result));
    1322                 :             : 
    1323                 :      798819 :   UNLOCK_CONTEXT (context);
    1324                 :             : 
    1325                 :      798819 :   return result;
    1326                 :      167488 : }
    1327                 :             : 
    1328                 :             : static void
    1329                 :      829253 : g_source_destroy_internal (GSource      *source,
    1330                 :             :                            GMainContext *context,
    1331                 :             :                            gboolean      have_lock)
    1332                 :             : {
    1333                 :      661459 :   TRACE (GLIB_MAIN_SOURCE_DESTROY (g_source_get_name (source), source,
    1334                 :             :                                    context));
    1335                 :             : 
    1336                 :      829253 :   if (!have_lock)
    1337                 :      449347 :     LOCK_CONTEXT (context);
    1338                 :             :   
    1339                 :      829253 :   if (!SOURCE_DESTROYED (source))
    1340                 :             :     {
    1341                 :             :       GSList *tmp_list;
    1342                 :             :       gpointer old_cb_data;
    1343                 :             :       GSourceCallbackFuncs *old_cb_funcs;
    1344                 :             : 
    1345                 :      813527 :       g_atomic_int_and (&source->flags, ~G_HOOK_FLAG_ACTIVE);
    1346                 :             : 
    1347                 :      813527 :       old_cb_data = source->callback_data;
    1348                 :      813527 :       old_cb_funcs = source->callback_funcs;
    1349                 :             : 
    1350                 :      813527 :       source->callback_data = NULL;
    1351                 :      813527 :       source->callback_funcs = NULL;
    1352                 :             : 
    1353                 :      813527 :       if (old_cb_funcs)
    1354                 :             :         {
    1355                 :      788754 :           UNLOCK_CONTEXT (context);
    1356                 :      788754 :           old_cb_funcs->unref (old_cb_data);
    1357                 :      788754 :           LOCK_CONTEXT (context);
    1358                 :      155422 :         }
    1359                 :             : 
    1360                 :      813527 :       if (!SOURCE_BLOCKED (source))
    1361                 :             :         {
    1362                 :      812422 :           tmp_list = source->poll_fds;
    1363                 :      814900 :           while (tmp_list)
    1364                 :             :             {
    1365                 :        2478 :               g_main_context_remove_poll_unlocked (context, tmp_list->data);
    1366                 :        2478 :               tmp_list = tmp_list->next;
    1367                 :             :             }
    1368                 :             : 
    1369                 :      826999 :           for (tmp_list = source->priv->fds; tmp_list; tmp_list = tmp_list->next)
    1370                 :       14577 :             g_main_context_remove_poll_unlocked (context, tmp_list->data);
    1371                 :      167448 :         }
    1372                 :             : 
    1373                 :      829175 :       while (source->priv->child_sources)
    1374                 :       15648 :         g_child_source_remove_internal (source->priv->child_sources->data, context);
    1375                 :             : 
    1376                 :      813527 :       if (source->priv->parent_source)
    1377                 :           2 :         g_child_source_remove_internal (source, context);
    1378                 :             :           
    1379                 :      813527 :       g_source_unref_internal (source, context, TRUE);
    1380                 :      167578 :     }
    1381                 :             : 
    1382                 :      829253 :   if (!have_lock)
    1383                 :      449348 :     UNLOCK_CONTEXT (context);
    1384                 :      829253 : }
    1385                 :             : 
    1386                 :             : static GMainContext *
    1387                 :     6169361 : source_dup_main_context (GSource *source)
    1388                 :             : {
    1389                 :     6169361 :   GMainContext *ret = NULL;
    1390                 :             : 
    1391                 :     6169361 :   g_rw_lock_reader_lock (&source_destroy_lock);
    1392                 :             : 
    1393                 :     6169361 :   ret = source->context;
    1394                 :     6169361 :   if (ret)
    1395                 :     1840513 :     g_atomic_int_inc (&ret->ref_count);
    1396                 :             : 
    1397                 :     6169361 :   g_rw_lock_reader_unlock (&source_destroy_lock);
    1398                 :             : 
    1399                 :     6169361 :   return ret;
    1400                 :             : }
    1401                 :             : 
    1402                 :             : /**
    1403                 :             :  * g_source_destroy:
    1404                 :             :  * @source: a source
    1405                 :             :  *
    1406                 :             :  * Removes a source from its [struct@GLib.MainContext], if any, and marks it as
    1407                 :             :  * destroyed.
    1408                 :             :  *
    1409                 :             :  * The source cannot be subsequently added to another
    1410                 :             :  * context. It is safe to call this on sources which have already been
    1411                 :             :  * removed from their context.
    1412                 :             :  *
    1413                 :             :  * This does not unref the [struct@GLib.Source]: if you still hold a reference,
    1414                 :             :  * use [method@GLib.Source.unref] to drop it.
    1415                 :             :  *
    1416                 :             :  * This function is safe to call from any thread, regardless of which thread
    1417                 :             :  * the [struct@GLib.MainContext] is running in.
    1418                 :             :  *
    1419                 :             :  * If the source is currently attached to a [struct@GLib.MainContext],
    1420                 :             :  * destroying it will effectively unset the callback similar to calling
    1421                 :             :  * [method@GLib.Source.set_callback]. This can mean, that the data’s
    1422                 :             :  * [callback@GLib.DestroyNotify] gets called right away.
    1423                 :             :  */
    1424                 :             : void
    1425                 :      449364 : g_source_destroy (GSource *source)
    1426                 :             : {
    1427                 :             :   GMainContext *context;
    1428                 :             :   
    1429                 :      449364 :   g_return_if_fail (source != NULL);
    1430                 :      449364 :   g_return_if_fail (g_atomic_int_get (&source->ref_count) > 0);
    1431                 :             :   
    1432                 :      449364 :   context = source_dup_main_context (source);
    1433                 :             : 
    1434                 :      449364 :   if (context)
    1435                 :             :     {
    1436                 :      449348 :       g_source_destroy_internal (source, context, FALSE);
    1437                 :      449348 :       g_main_context_unref (context);
    1438                 :      162587 :     }
    1439                 :             :   else
    1440                 :          16 :     g_atomic_int_and (&source->flags, ~G_HOOK_FLAG_ACTIVE);
    1441                 :      162595 : }
    1442                 :             : 
    1443                 :             : /**
    1444                 :             :  * g_source_get_id:
    1445                 :             :  * @source: a source
    1446                 :             :  *
    1447                 :             :  * Returns the numeric ID for a particular source.
    1448                 :             :  * 
    1449                 :             :  * The ID of a source
    1450                 :             :  * is a positive integer which is unique within a particular main loop 
    1451                 :             :  * context. The reverse mapping from ID to source is done by
    1452                 :             :  * [method@GLib.MainContext.find_source_by_id].
    1453                 :             :  *
    1454                 :             :  * You can only call this function while the source is associated to a
    1455                 :             :  * [struct@GLib.MainContext] instance; calling this function before
    1456                 :             :  * [method@GLib.Source.attach] or after [method@GLib.Source.destroy] yields
    1457                 :             :  * undefined behavior. The ID returned is unique within the
    1458                 :             :  * [struct@GLib.MainContext] instance passed to [method@GLib.Source.attach].
    1459                 :             :  *
    1460                 :             :  * Returns: the ID (greater than 0) for the source
    1461                 :             :  **/
    1462                 :             : guint
    1463                 :      200108 : g_source_get_id (GSource *source)
    1464                 :             : {
    1465                 :             :   guint result;
    1466                 :             :   GMainContext *context;
    1467                 :             :   
    1468                 :      200108 :   g_return_val_if_fail (source != NULL, 0);
    1469                 :      200108 :   g_return_val_if_fail (g_atomic_int_get (&source->ref_count) > 0, 0);
    1470                 :      200108 :   context = source_dup_main_context (source);
    1471                 :      200108 :   g_return_val_if_fail (context != NULL, 0);
    1472                 :             : 
    1473                 :      200108 :   LOCK_CONTEXT (context);
    1474                 :      200108 :   result = source->source_id;
    1475                 :      200108 :   UNLOCK_CONTEXT (context);
    1476                 :             :   
    1477                 :      200108 :   g_main_context_unref (context);
    1478                 :             : 
    1479                 :      200108 :   return result;
    1480                 :      100054 : }
    1481                 :             : 
    1482                 :             : /**
    1483                 :             :  * g_source_get_context:
    1484                 :             :  * @source: a source
    1485                 :             :  *
    1486                 :             :  * Gets the [struct@GLib.MainContext] with which the source is associated.
    1487                 :             :  *
    1488                 :             :  * You can call this on a source that has been destroyed, provided
    1489                 :             :  * that the [struct@GLib.MainContext] it was attached to still exists (in which
    1490                 :             :  * case it will return that [struct@GLib.MainContext]). In particular, you can
    1491                 :             :  * always call this function on the source returned from
    1492                 :             :  * [func@GLib.main_current_source]. But calling this function on a source
    1493                 :             :  * whose [struct@GLib.MainContext] has been destroyed is an error.
    1494                 :             :  *
    1495                 :             :  * If the associated [struct@GLib.MainContext] could be destroy concurrently from
    1496                 :             :  * a different thread, then this function is not safe to call and
    1497                 :             :  * [method@GLib.Source.dup_context] should be used instead.
    1498                 :             :  *
    1499                 :             :  * Returns: (transfer none) (nullable): the main context with which the
    1500                 :             :  *   source is associated, or `NULL` if the context has not yet been added to a
    1501                 :             :  *   source
    1502                 :             :  **/
    1503                 :             : GMainContext *
    1504                 :      136753 : g_source_get_context (GSource *source)
    1505                 :             : {
    1506                 :      136753 :   g_return_val_if_fail (source != NULL, NULL);
    1507                 :      136753 :   g_return_val_if_fail (g_atomic_int_get (&source->ref_count) > 0, NULL);
    1508                 :      136753 :   g_return_val_if_fail (source->context != NULL || !SOURCE_DESTROYED (source), NULL);
    1509                 :             : 
    1510                 :      136751 :   return source->context;
    1511                 :        2546 : }
    1512                 :             : 
    1513                 :             : /**
    1514                 :             :  * g_source_dup_context:
    1515                 :             :  * @source: a source
    1516                 :             :  *
    1517                 :             :  * Gets a reference to the [struct@GLib.MainContext] with which the source is
    1518                 :             :  * associated.
    1519                 :             :  *
    1520                 :             :  * You can call this on a source that has been destroyed. You can
    1521                 :             :  * always call this function on the source returned from
    1522                 :             :  * [func@GLib.main_current_source].
    1523                 :             :  *
    1524                 :             :  * Returns: (transfer full) (nullable): the [struct@GLib.MainContext] with which
    1525                 :             :  *   the source is associated, or `NULL` if the context has not yet been added
    1526                 :             :  *   to a source
    1527                 :             :  * Since: 2.86
    1528                 :             :  **/
    1529                 :             : GMainContext *
    1530                 :           2 : g_source_dup_context (GSource *source)
    1531                 :             : {
    1532                 :           2 :   g_return_val_if_fail (source != NULL, NULL);
    1533                 :           2 :   g_return_val_if_fail (g_atomic_int_get (&source->ref_count) > 0, NULL);
    1534                 :           2 :   g_return_val_if_fail (source->context != NULL || !SOURCE_DESTROYED (source), NULL);
    1535                 :             : 
    1536                 :           2 :   return source_dup_main_context (source);
    1537                 :           1 : }
    1538                 :             : 
    1539                 :             : /**
    1540                 :             :  * g_source_add_poll:
    1541                 :             :  * @source:a source
    1542                 :             :  * @fd: a [struct@GLib.PollFD] structure holding information about a file
    1543                 :             :  *   descriptor to watch
    1544                 :             :  *
    1545                 :             :  * Adds a file descriptor to the set of file descriptors polled for
    1546                 :             :  * this source.
    1547                 :             :  *
    1548                 :             :  * This is usually combined with [ctor@GLib.Source.new] to add an
    1549                 :             :  * event source. The event source’s check function will typically test
    1550                 :             :  * the @revents field in the [struct@GLib.PollFD] struct and return true if
    1551                 :             :  * events need to be processed.
    1552                 :             :  *
    1553                 :             :  * This API is only intended to be used by implementations of [struct@GLib.Source].
    1554                 :             :  * Do not call this API on a [struct@GLib.Source] that you did not create.
    1555                 :             :  *
    1556                 :             :  * Using this API forces the linear scanning of event sources on each
    1557                 :             :  * main loop iteration.  Newly-written event sources should try to use
    1558                 :             :  * `g_source_add_unix_fd()` instead of this API.
    1559                 :             :  **/
    1560                 :             : void
    1561                 :        2538 : g_source_add_poll (GSource *source,
    1562                 :             :                    GPollFD *fd)
    1563                 :             : {
    1564                 :             :   GMainContext *context;
    1565                 :             :   
    1566                 :        2538 :   g_return_if_fail (source != NULL);
    1567                 :        2538 :   g_return_if_fail (g_atomic_int_get (&source->ref_count) > 0);
    1568                 :        2538 :   g_return_if_fail (fd != NULL);
    1569                 :        2538 :   g_return_if_fail (!SOURCE_DESTROYED (source));
    1570                 :             :   
    1571                 :        2538 :   context = source_dup_main_context (source);
    1572                 :             : 
    1573                 :        2538 :   if (context)
    1574                 :           0 :     LOCK_CONTEXT (context);
    1575                 :             :   
    1576                 :        2538 :   source->poll_fds = g_slist_prepend (source->poll_fds, fd);
    1577                 :             : 
    1578                 :        2538 :   if (context)
    1579                 :             :     {
    1580                 :           0 :       if (!SOURCE_BLOCKED (source))
    1581                 :           0 :         g_main_context_add_poll_unlocked (context, source->priority, fd);
    1582                 :           0 :       UNLOCK_CONTEXT (context);
    1583                 :           0 :       g_main_context_unref (context);
    1584                 :           0 :     }
    1585                 :        1097 : }
    1586                 :             : 
    1587                 :             : /**
    1588                 :             :  * g_source_remove_poll:
    1589                 :             :  * @source:a source
    1590                 :             :  * @fd: a [struct@GLib.PollFD] structure previously passed to
    1591                 :             :  *   [method@GLib.Source.add_poll]
    1592                 :             :  *
    1593                 :             :  * Removes a file descriptor from the set of file descriptors polled for
    1594                 :             :  * this source.
    1595                 :             :  *
    1596                 :             :  * This API is only intended to be used by implementations of [struct@GLib.Source].
    1597                 :             :  * Do not call this API on a [struct@GLib.Source] that you did not create.
    1598                 :             :  **/
    1599                 :             : void
    1600                 :           1 : g_source_remove_poll (GSource *source,
    1601                 :             :                       GPollFD *fd)
    1602                 :             : {
    1603                 :             :   GMainContext *context;
    1604                 :             :   
    1605                 :           1 :   g_return_if_fail (source != NULL);
    1606                 :           1 :   g_return_if_fail (g_atomic_int_get (&source->ref_count) > 0);
    1607                 :           1 :   g_return_if_fail (fd != NULL);
    1608                 :           1 :   g_return_if_fail (!SOURCE_DESTROYED (source));
    1609                 :             :   
    1610                 :           1 :   context = source_dup_main_context (source);
    1611                 :             : 
    1612                 :           1 :   if (context)
    1613                 :           1 :     LOCK_CONTEXT (context);
    1614                 :             :   
    1615                 :           1 :   source->poll_fds = g_slist_remove (source->poll_fds, fd);
    1616                 :             : 
    1617                 :           1 :   if (context)
    1618                 :             :     {
    1619                 :           1 :       if (!SOURCE_BLOCKED (source))
    1620                 :           1 :         g_main_context_remove_poll_unlocked (context, fd);
    1621                 :           1 :       UNLOCK_CONTEXT (context);
    1622                 :           1 :       g_main_context_unref (context);
    1623                 :           1 :     }
    1624                 :           1 : }
    1625                 :             : 
    1626                 :             : /**
    1627                 :             :  * g_source_add_child_source:
    1628                 :             :  * @source:a source
    1629                 :             :  * @child_source: a second source that @source should ‘poll’
    1630                 :             :  *
    1631                 :             :  * Adds @child_source to @source as a ‘polled’ source.
    1632                 :             :  *
    1633                 :             :  * When @source is added to a [struct@GLib.MainContext], @child_source will be
    1634                 :             :  * automatically added with the same priority. When @child_source is triggered,
    1635                 :             :  * it will cause @source to dispatch (in addition to calling its own callback),
    1636                 :             :  * and when @source is destroyed, it will destroy @child_source as well.
    1637                 :             :  *
    1638                 :             :  * The @source will also still be dispatched if its own prepare/check functions
    1639                 :             :  * indicate that it is ready.
    1640                 :             :  *
    1641                 :             :  * If you don’t need @child_source to do anything on its own when it
    1642                 :             :  * triggers, you can call `g_source_set_dummy_callback()` on it to set a
    1643                 :             :  * callback that does nothing (except return true if appropriate).
    1644                 :             :  *
    1645                 :             :  * The @source will hold a reference on @child_source while @child_source
    1646                 :             :  * is attached to it.
    1647                 :             :  *
    1648                 :             :  * This API is only intended to be used by implementations of [struct@GLib.Source].
    1649                 :             :  * Do not call this API on a [struct@GLib.Source] that you did not create.
    1650                 :             :  *
    1651                 :             :  * Since: 2.28
    1652                 :             :  **/
    1653                 :             : void
    1654                 :       15739 : g_source_add_child_source (GSource *source,
    1655                 :             :                            GSource *child_source)
    1656                 :             : {
    1657                 :             :   GMainContext *context;
    1658                 :             : 
    1659                 :       15739 :   g_return_if_fail (source != NULL);
    1660                 :       15739 :   g_return_if_fail (g_atomic_int_get (&source->ref_count) > 0);
    1661                 :       15739 :   g_return_if_fail (child_source != NULL);
    1662                 :       15739 :   g_return_if_fail (g_atomic_int_get (&child_source->ref_count) > 0);
    1663                 :       15739 :   g_return_if_fail (!SOURCE_DESTROYED (source));
    1664                 :       15739 :   g_return_if_fail (!SOURCE_DESTROYED (child_source));
    1665                 :       15739 :   g_return_if_fail (child_source->context == NULL);
    1666                 :       15739 :   g_return_if_fail (child_source->priv->parent_source == NULL);
    1667                 :             : 
    1668                 :       15739 :   context = source_dup_main_context (source);
    1669                 :             : 
    1670                 :       15739 :   if (context)
    1671                 :          10 :     LOCK_CONTEXT (context);
    1672                 :             : 
    1673                 :       15542 :   TRACE (GLIB_SOURCE_ADD_CHILD_SOURCE (source, child_source));
    1674                 :             : 
    1675                 :       15936 :   source->priv->child_sources = g_slist_prepend (source->priv->child_sources,
    1676                 :       15739 :                                                  g_source_ref (child_source));
    1677                 :       15739 :   child_source->priv->parent_source = source;
    1678                 :       15739 :   g_source_set_priority_unlocked (child_source, NULL, source->priority);
    1679                 :       15739 :   if (SOURCE_BLOCKED (source))
    1680                 :           4 :     block_source (child_source, NULL);
    1681                 :             : 
    1682                 :       15739 :   if (context)
    1683                 :             :     {
    1684                 :          10 :       g_source_attach_unlocked (child_source, context, TRUE);
    1685                 :          10 :       UNLOCK_CONTEXT (context);
    1686                 :          10 :       g_main_context_unref (context);
    1687                 :           5 :     }
    1688                 :         197 : }
    1689                 :             : 
    1690                 :             : static void
    1691                 :       15652 : g_child_source_remove_internal (GSource *child_source,
    1692                 :             :                                 GMainContext *context)
    1693                 :             : {
    1694                 :       15652 :   GSource *parent_source = child_source->priv->parent_source;
    1695                 :             : 
    1696                 :       31115 :   parent_source->priv->child_sources =
    1697                 :       15652 :     g_slist_remove (parent_source->priv->child_sources, child_source);
    1698                 :       15652 :   child_source->priv->parent_source = NULL;
    1699                 :             : 
    1700                 :       15652 :   g_source_destroy_internal (child_source, context, TRUE);
    1701                 :       15652 :   g_source_unref_internal (child_source, context, TRUE);
    1702                 :       15652 : }
    1703                 :             : 
    1704                 :             : /**
    1705                 :             :  * g_source_remove_child_source:
    1706                 :             :  * @source:a source
    1707                 :             :  * @child_source: a source previously passed to
    1708                 :             :  *   [method@GLib.Source.add_child_source]
    1709                 :             :  *
    1710                 :             :  * Detaches @child_source from @source and destroys it.
    1711                 :             :  *
    1712                 :             :  * This API is only intended to be used by implementations of [struct@GLib.Source].
    1713                 :             :  * Do not call this API on a [struct@GLib.Source] that you did not create.
    1714                 :             :  *
    1715                 :             :  * Since: 2.28
    1716                 :             :  **/
    1717                 :             : void
    1718                 :           2 : g_source_remove_child_source (GSource *source,
    1719                 :             :                               GSource *child_source)
    1720                 :             : {
    1721                 :             :   GMainContext *context;
    1722                 :             : 
    1723                 :           2 :   g_return_if_fail (source != NULL);
    1724                 :           2 :   g_return_if_fail (g_atomic_int_get (&source->ref_count) > 0);
    1725                 :           2 :   g_return_if_fail (child_source != NULL);
    1726                 :           2 :   g_return_if_fail (g_atomic_int_get (&child_source->ref_count) > 0);
    1727                 :           2 :   g_return_if_fail (child_source->priv->parent_source == source);
    1728                 :           2 :   g_return_if_fail (!SOURCE_DESTROYED (source));
    1729                 :           2 :   g_return_if_fail (!SOURCE_DESTROYED (child_source));
    1730                 :             : 
    1731                 :           2 :   context = source_dup_main_context (source);
    1732                 :             : 
    1733                 :           2 :   if (context)
    1734                 :           2 :     LOCK_CONTEXT (context);
    1735                 :             : 
    1736                 :           2 :   g_child_source_remove_internal (child_source, context);
    1737                 :             : 
    1738                 :           2 :   if (context)
    1739                 :             :     {
    1740                 :           2 :       UNLOCK_CONTEXT (context);
    1741                 :           2 :       g_main_context_unref (context);
    1742                 :           1 :     }
    1743                 :           1 : }
    1744                 :             : 
    1745                 :             : static void
    1746                 :      889813 : g_source_callback_ref (gpointer cb_data)
    1747                 :             : {
    1748                 :      889813 :   GSourceCallback *callback = cb_data;
    1749                 :             : 
    1750                 :      889813 :   g_atomic_int_inc (&callback->ref_count);
    1751                 :      889813 : }
    1752                 :             : 
    1753                 :             : static void
    1754                 :     1862892 : g_source_callback_unref (gpointer cb_data)
    1755                 :             : {
    1756                 :     1862892 :   GSourceCallback *callback = cb_data;
    1757                 :             : 
    1758                 :     1862892 :   if (g_atomic_int_dec_and_test (&callback->ref_count))
    1759                 :             :     {
    1760                 :      973097 :       if (callback->notify)
    1761                 :      366975 :         callback->notify (callback->data);
    1762                 :      973097 :       g_free (callback);
    1763                 :      255228 :     }
    1764                 :     1862892 : }
    1765                 :             : 
    1766                 :             : static void
    1767                 :      889819 : g_source_callback_get (gpointer     cb_data,
    1768                 :             :                        GSource     *source, 
    1769                 :             :                        GSourceFunc *func,
    1770                 :             :                        gpointer    *data)
    1771                 :             : {
    1772                 :      889819 :   GSourceCallback *callback = cb_data;
    1773                 :             : 
    1774                 :      889819 :   *func = callback->func;
    1775                 :      889819 :   *data = callback->data;
    1776                 :      889819 : }
    1777                 :             : 
    1778                 :             : static GSourceCallbackFuncs g_source_callback_funcs = {
    1779                 :             :   g_source_callback_ref,
    1780                 :             :   g_source_callback_unref,
    1781                 :             :   g_source_callback_get,
    1782                 :             : };
    1783                 :             : 
    1784                 :             : /**
    1785                 :             :  * g_source_set_callback_indirect:
    1786                 :             :  * @source: the source
    1787                 :             :  * @callback_data: pointer to callback data ‘object’
    1788                 :             :  * @callback_funcs: functions for reference counting @callback_data
    1789                 :             :  *   and getting the callback and data
    1790                 :             :  *
    1791                 :             :  * Sets the callback function storing the data as a reference counted callback
    1792                 :             :  * ‘object’.
    1793                 :             :  *
    1794                 :             :  * This is used internally. Note that calling
    1795                 :             :  * [method@GLib.Source.set_callback_indirect] assumes
    1796                 :             :  * an initial reference count on @callback_data, and thus
    1797                 :             :  * `callback_funcs->unref` will eventually be called once more than
    1798                 :             :  * `callback_funcs->ref`.
    1799                 :             :  *
    1800                 :             :  * It is safe to call this function multiple times on a source which has already
    1801                 :             :  * been attached to a context. The changes will take effect for the next time
    1802                 :             :  * the source is dispatched after this call returns.
    1803                 :             :  **/
    1804                 :             : void
    1805                 :      989564 : g_source_set_callback_indirect (GSource              *source,
    1806                 :             :                                 gpointer              callback_data,
    1807                 :             :                                 GSourceCallbackFuncs *callback_funcs)
    1808                 :             : {
    1809                 :             :   GMainContext *context;
    1810                 :             :   gpointer old_cb_data;
    1811                 :             :   GSourceCallbackFuncs *old_cb_funcs;
    1812                 :             :   
    1813                 :      989564 :   g_return_if_fail (source != NULL);
    1814                 :      989564 :   g_return_if_fail (g_atomic_int_get (&source->ref_count) > 0);
    1815                 :      989564 :   g_return_if_fail (callback_funcs != NULL || callback_data == NULL);
    1816                 :             : 
    1817                 :      989564 :   context = source_dup_main_context (source);
    1818                 :             : 
    1819                 :      989564 :   if (context)
    1820                 :           2 :     LOCK_CONTEXT (context);
    1821                 :             : 
    1822                 :      989564 :   if (callback_funcs != &g_source_callback_funcs)
    1823                 :             :     {
    1824                 :       15542 :       TRACE (GLIB_SOURCE_SET_CALLBACK_INDIRECT (source, callback_data,
    1825                 :             :                                                 callback_funcs->ref,
    1826                 :             :                                                 callback_funcs->unref,
    1827                 :             :                                                 callback_funcs->get));
    1828                 :         195 :     }
    1829                 :             : 
    1830                 :      989564 :   old_cb_data = source->callback_data;
    1831                 :      989564 :   old_cb_funcs = source->callback_funcs;
    1832                 :             : 
    1833                 :      989564 :   source->callback_data = callback_data;
    1834                 :      989564 :   source->callback_funcs = callback_funcs;
    1835                 :             :   
    1836                 :      989564 :   if (context)
    1837                 :             :     {
    1838                 :           2 :       UNLOCK_CONTEXT (context);
    1839                 :           2 :       g_main_context_unref (context);
    1840                 :           1 :     }
    1841                 :             : 
    1842                 :      989564 :   if (old_cb_funcs)
    1843                 :           0 :     old_cb_funcs->unref (old_cb_data);
    1844                 :      255538 : }
    1845                 :             : 
    1846                 :             : /**
    1847                 :             :  * g_source_set_callback:
    1848                 :             :  * @source: the source
    1849                 :             :  * @func: a callback function
    1850                 :             :  * @data: the data to pass to callback function
    1851                 :             :  * @notify: (nullable): a function to call when @data is no longer in use
    1852                 :             :  * 
    1853                 :             :  * Sets the callback function for a source. The callback for a source is
    1854                 :             :  * called from the source’s dispatch function.
    1855                 :             :  *
    1856                 :             :  * The exact type of @func depends on the type of source; ie. you
    1857                 :             :  * should not count on @func being called with @data as its first
    1858                 :             :  * parameter. Cast @func with [func@GLib.SOURCE_FUNC] to avoid warnings about
    1859                 :             :  * incompatible function types.
    1860                 :             :  *
    1861                 :             :  * See [main loop memory management](main-loop.html#memory-management-of-sources) for details
    1862                 :             :  * on how to handle memory management of @data.
    1863                 :             :  * 
    1864                 :             :  * Typically, you won’t use this function. Instead use functions specific
    1865                 :             :  * to the type of source you are using, such as [func@GLib.idle_add] or
    1866                 :             :  * [func@GLib.timeout_add].
    1867                 :             :  *
    1868                 :             :  * It is safe to call this function multiple times on a source which has already
    1869                 :             :  * been attached to a context. The changes will take effect for the next time
    1870                 :             :  * the source is dispatched after this call returns.
    1871                 :             :  *
    1872                 :             :  * Note that [method@GLib.Source.destroy] for a currently attached source has the effect
    1873                 :             :  * of also unsetting the callback.
    1874                 :             :  **/
    1875                 :             : void
    1876                 :      973828 : g_source_set_callback (GSource        *source,
    1877                 :             :                        GSourceFunc     func,
    1878                 :             :                        gpointer        data,
    1879                 :             :                        GDestroyNotify  notify)
    1880                 :             : {
    1881                 :             :   GSourceCallback *new_callback;
    1882                 :             : 
    1883                 :      973828 :   g_return_if_fail (source != NULL);
    1884                 :      973828 :   g_return_if_fail (g_atomic_int_get (&source->ref_count) > 0);
    1885                 :             : 
    1886                 :      718484 :   TRACE (GLIB_SOURCE_SET_CALLBACK (source, func, data, notify));
    1887                 :             : 
    1888                 :      973828 :   new_callback = g_new (GSourceCallback, 1);
    1889                 :             : 
    1890                 :      973828 :   new_callback->ref_count = 1;
    1891                 :      973828 :   new_callback->func = func;
    1892                 :      973828 :   new_callback->data = data;
    1893                 :      973828 :   new_callback->notify = notify;
    1894                 :             : 
    1895                 :      973828 :   g_source_set_callback_indirect (source, new_callback, &g_source_callback_funcs);
    1896                 :      255344 : }
    1897                 :             : 
    1898                 :             : 
    1899                 :             : /**
    1900                 :             :  * g_source_set_funcs:
    1901                 :             :  * @source: a source
    1902                 :             :  * @funcs: the new source functions
    1903                 :             :  * 
    1904                 :             :  * Sets the source functions of an unattached source.
    1905                 :             :  *
    1906                 :             :  * These can be used to override the default implementations for the type
    1907                 :             :  * of @source.
    1908                 :             :  * 
    1909                 :             :  * Since: 2.12
    1910                 :             :  */
    1911                 :             : void
    1912                 :           4 : g_source_set_funcs (GSource     *source,
    1913                 :             :                    GSourceFuncs *funcs)
    1914                 :             : {
    1915                 :           4 :   g_return_if_fail (source != NULL);
    1916                 :           4 :   g_return_if_fail (source->context == NULL);
    1917                 :           4 :   g_return_if_fail (g_atomic_int_get (&source->ref_count) > 0);
    1918                 :           4 :   g_return_if_fail (funcs != NULL);
    1919                 :             : 
    1920                 :           4 :   source->source_funcs = funcs;
    1921                 :           2 : }
    1922                 :             : 
    1923                 :             : static void
    1924                 :     1244703 : g_source_set_priority_unlocked (GSource      *source,
    1925                 :             :                                 GMainContext *context,
    1926                 :             :                                 gint          priority)
    1927                 :             : {
    1928                 :             :   GSList *tmp_list;
    1929                 :             :   
    1930                 :     1244703 :   g_return_if_fail (source->priv->parent_source == NULL ||
    1931                 :         299 :                     source->priv->parent_source->priority == priority);
    1932                 :             : 
    1933                 :     1036713 :   TRACE (GLIB_SOURCE_SET_PRIORITY (source, context, priority));
    1934                 :             : 
    1935                 :     1244703 :   if (context)
    1936                 :             :     {
    1937                 :             :       /* Remove the source from the context's source and then
    1938                 :             :        * add it back after so it is sorted in the correct place
    1939                 :             :        */
    1940                 :          10 :       source_remove_from_context (source, context);
    1941                 :           4 :     }
    1942                 :             : 
    1943                 :     1244703 :   source->priority = priority;
    1944                 :             : 
    1945                 :     1244703 :   if (context)
    1946                 :             :     {
    1947                 :          10 :       source_add_to_context (source, context);
    1948                 :             : 
    1949                 :          10 :       if (!SOURCE_BLOCKED (source))
    1950                 :             :         {
    1951                 :          10 :           tmp_list = source->poll_fds;
    1952                 :          10 :           while (tmp_list)
    1953                 :             :             {
    1954                 :           0 :               g_main_context_remove_poll_unlocked (context, tmp_list->data);
    1955                 :           0 :               g_main_context_add_poll_unlocked (context, priority, tmp_list->data);
    1956                 :             :               
    1957                 :           0 :               tmp_list = tmp_list->next;
    1958                 :             :             }
    1959                 :             : 
    1960                 :          12 :           for (tmp_list = source->priv->fds; tmp_list; tmp_list = tmp_list->next)
    1961                 :             :             {
    1962                 :           2 :               g_main_context_remove_poll_unlocked (context, tmp_list->data);
    1963                 :           2 :               g_main_context_add_poll_unlocked (context, priority, tmp_list->data);
    1964                 :           0 :             }
    1965                 :           4 :         }
    1966                 :           4 :     }
    1967                 :             : 
    1968                 :     1244703 :   if (source->priv->child_sources)
    1969                 :             :     {
    1970                 :       14855 :       tmp_list = source->priv->child_sources;
    1971                 :       30266 :       while (tmp_list)
    1972                 :             :         {
    1973                 :       15411 :           g_source_set_priority_unlocked (tmp_list->data, context, priority);
    1974                 :       15411 :           tmp_list = tmp_list->next;
    1975                 :             :         }
    1976                 :         101 :     }
    1977                 :      207990 : }
    1978                 :             : 
    1979                 :             : /**
    1980                 :             :  * g_source_set_priority:
    1981                 :             :  * @source: a source
    1982                 :             :  * @priority: the new priority
    1983                 :             :  *
    1984                 :             :  * Sets the priority of a source.
    1985                 :             :  *
    1986                 :             :  * While the main loop is being run, a
    1987                 :             :  * source will be dispatched if it is ready to be dispatched and no
    1988                 :             :  * sources at a higher (numerically smaller) priority are ready to be
    1989                 :             :  * dispatched.
    1990                 :             :  *
    1991                 :             :  * A child source always has the same priority as its parent.  It is not
    1992                 :             :  * permitted to change the priority of a source once it has been added
    1993                 :             :  * as a child of another source.
    1994                 :             :  **/
    1995                 :             : void
    1996                 :     1213564 : g_source_set_priority (GSource  *source,
    1997                 :             :                        gint      priority)
    1998                 :             : {
    1999                 :             :   GMainContext *context;
    2000                 :             : 
    2001                 :     1213564 :   g_return_if_fail (source != NULL);
    2002                 :     1213564 :   g_return_if_fail (g_atomic_int_get (&source->ref_count) > 0);
    2003                 :     1213564 :   g_return_if_fail (source->priv->parent_source == NULL);
    2004                 :             : 
    2005                 :     1213564 :   context = source_dup_main_context (source);
    2006                 :             : 
    2007                 :     1213564 :   if (context)
    2008                 :           6 :     LOCK_CONTEXT (context);
    2009                 :     1213564 :   g_source_set_priority_unlocked (source, context, priority);
    2010                 :     1213564 :   if (context)
    2011                 :             :     {
    2012                 :           6 :       UNLOCK_CONTEXT (context);
    2013                 :           6 :       g_main_context_unref (context);
    2014                 :           2 :     }
    2015                 :      207702 : }
    2016                 :             : 
    2017                 :             : /**
    2018                 :             :  * g_source_get_priority:
    2019                 :             :  * @source: a source
    2020                 :             :  * 
    2021                 :             :  * Gets the priority of a source.
    2022                 :             :  * 
    2023                 :             :  * Returns: the priority of the source
    2024                 :             :  **/
    2025                 :             : gint
    2026                 :          16 : g_source_get_priority (GSource *source)
    2027                 :             : {
    2028                 :          16 :   g_return_val_if_fail (source != NULL, 0);
    2029                 :          16 :   g_return_val_if_fail (g_atomic_int_get (&source->ref_count) > 0, 0);
    2030                 :             : 
    2031                 :          16 :   return source->priority;
    2032                 :           8 : }
    2033                 :             : 
    2034                 :             : /**
    2035                 :             :  * g_source_set_ready_time:
    2036                 :             :  * @source: a source
    2037                 :             :  * @ready_time: the monotonic time at which the source will be ready;
    2038                 :             :  *   `0` for ‘immediately’, `-1` for ‘never’
    2039                 :             :  *
    2040                 :             :  * Sets a source to be dispatched when the given monotonic time is
    2041                 :             :  * reached (or passed).
    2042                 :             :  *
    2043                 :             :  * If the monotonic time is in the past (as it
    2044                 :             :  * always will be if @ready_time is `0`) then the source will be
    2045                 :             :  * dispatched immediately.
    2046                 :             :  *
    2047                 :             :  * If @ready_time is `-1` then the source is never woken up on the basis
    2048                 :             :  * of the passage of time.
    2049                 :             :  *
    2050                 :             :  * Dispatching the source does not reset the ready time.  You should do
    2051                 :             :  * so yourself, from the source dispatch function.
    2052                 :             :  *
    2053                 :             :  * Note that if you have a pair of sources where the ready time of one
    2054                 :             :  * suggests that it will be delivered first but the priority for the
    2055                 :             :  * other suggests that it would be delivered first, and the ready time
    2056                 :             :  * for both sources is reached during the same main context iteration,
    2057                 :             :  * then the order of dispatch is undefined.
    2058                 :             :  *
    2059                 :             :  * It is a no-op to call this function on a [struct@GLib.Source] which has
    2060                 :             :  * already been destroyed with [method@GLib.Source.destroy].
    2061                 :             :  *
    2062                 :             :  * This API is only intended to be used by implementations of [struct@GLib.Source].
    2063                 :             :  * Do not call this API on a [struct@GLib.Source] that you did not create.
    2064                 :             :  *
    2065                 :             :  * Since: 2.36
    2066                 :             :  **/
    2067                 :             : void
    2068                 :      357804 : g_source_set_ready_time (GSource *source,
    2069                 :             :                          gint64   ready_time)
    2070                 :             : {
    2071                 :             :   GMainContext *context;
    2072                 :             : 
    2073                 :      357804 :   g_return_if_fail (source != NULL);
    2074                 :      357804 :   g_return_if_fail (g_atomic_int_get (&source->ref_count) > 0);
    2075                 :             : 
    2076                 :      357804 :   context = source_dup_main_context (source);
    2077                 :             : 
    2078                 :      357804 :   if (context)
    2079                 :      111051 :     LOCK_CONTEXT (context);
    2080                 :             : 
    2081                 :      357804 :   if (source->priv->ready_time == ready_time)
    2082                 :             :     {
    2083                 :       36858 :       if (context)
    2084                 :             :         {
    2085                 :       22056 :           UNLOCK_CONTEXT (context);
    2086                 :       22056 :           g_main_context_unref (context);
    2087                 :         695 :         }
    2088                 :       36858 :       return;
    2089                 :             :     }
    2090                 :             : 
    2091                 :      320946 :   source->priv->ready_time = ready_time;
    2092                 :             : 
    2093                 :      164426 :   TRACE (GLIB_SOURCE_SET_READY_TIME (source, ready_time));
    2094                 :             : 
    2095                 :      320946 :   if (context)
    2096                 :             :     {
    2097                 :             :       /* Quite likely that we need to change the timeout on the poll */
    2098                 :       89003 :       if (!SOURCE_BLOCKED (source))
    2099                 :       42091 :         g_wakeup_signal (context->wakeup);
    2100                 :       89003 :       UNLOCK_CONTEXT (context);
    2101                 :       89003 :       g_main_context_unref (context);
    2102                 :       44298 :     }
    2103                 :      157472 : }
    2104                 :             : 
    2105                 :             : /**
    2106                 :             :  * g_source_get_ready_time:
    2107                 :             :  * @source: a source
    2108                 :             :  *
    2109                 :             :  * Gets the ‘ready time’ of @source, as set by
    2110                 :             :  * [method@GLib.Source.set_ready_time].
    2111                 :             :  *
    2112                 :             :  * Any time before or equal to the current monotonic time (including zero)
    2113                 :             :  * is an indication that the source will fire immediately.
    2114                 :             :  *
    2115                 :             :  * Returns: the monotonic ready time, `-1` for ‘never’
    2116                 :             :  **/
    2117                 :             : gint64
    2118                 :       14493 : g_source_get_ready_time (GSource *source)
    2119                 :             : {
    2120                 :       14493 :   g_return_val_if_fail (source != NULL, -1);
    2121                 :       14493 :   g_return_val_if_fail (g_atomic_int_get (&source->ref_count) > 0, -1);
    2122                 :             : 
    2123                 :       14493 :   return source->priv->ready_time;
    2124                 :         200 : }
    2125                 :             : 
    2126                 :             : /**
    2127                 :             :  * g_source_set_can_recurse:
    2128                 :             :  * @source: a source
    2129                 :             :  * @can_recurse: whether recursion is allowed for this source
    2130                 :             :  * 
    2131                 :             :  * Sets whether a source can be called recursively.
    2132                 :             :  *
    2133                 :             :  * If @can_recurse is true, then while the source is being dispatched then this
    2134                 :             :  * source will be processed normally. Otherwise, all processing of this
    2135                 :             :  * source is blocked until the dispatch function returns.
    2136                 :             :  **/
    2137                 :             : void
    2138                 :           2 : g_source_set_can_recurse (GSource  *source,
    2139                 :             :                           gboolean  can_recurse)
    2140                 :             : {
    2141                 :             :   GMainContext *context;
    2142                 :             :   
    2143                 :           2 :   g_return_if_fail (source != NULL);
    2144                 :           2 :   g_return_if_fail (g_atomic_int_get (&source->ref_count) > 0);
    2145                 :             : 
    2146                 :           2 :   context = source_dup_main_context (source);
    2147                 :             : 
    2148                 :           2 :   if (context)
    2149                 :           0 :     LOCK_CONTEXT (context);
    2150                 :             :   
    2151                 :           2 :   if (can_recurse)
    2152                 :           2 :     g_atomic_int_or (&source->flags, G_SOURCE_CAN_RECURSE);
    2153                 :             :   else
    2154                 :           0 :     g_atomic_int_and (&source->flags, ~G_SOURCE_CAN_RECURSE);
    2155                 :             : 
    2156                 :           2 :   if (context)
    2157                 :             :     {
    2158                 :           0 :       UNLOCK_CONTEXT (context);
    2159                 :           0 :       g_main_context_unref (context);
    2160                 :           0 :     }
    2161                 :           1 : }
    2162                 :             : 
    2163                 :             : /**
    2164                 :             :  * g_source_get_can_recurse:
    2165                 :             :  * @source: a source
    2166                 :             :  * 
    2167                 :             :  * Checks whether a source is allowed to be called recursively.
    2168                 :             :  *
    2169                 :             :  * See [method@GLib.Source.set_can_recurse].
    2170                 :             :  * 
    2171                 :             :  * Returns: whether recursion is allowed
    2172                 :             :  **/
    2173                 :             : gboolean
    2174                 :           4 : g_source_get_can_recurse (GSource  *source)
    2175                 :             : {
    2176                 :           4 :   g_return_val_if_fail (source != NULL, FALSE);
    2177                 :           4 :   g_return_val_if_fail (g_atomic_int_get (&source->ref_count) > 0, FALSE);
    2178                 :             : 
    2179                 :           4 :   return (g_atomic_int_get (&source->flags) & G_SOURCE_CAN_RECURSE) != 0;
    2180                 :           2 : }
    2181                 :             : 
    2182                 :             : static void
    2183                 :     1432215 : g_source_set_name_full (GSource    *source,
    2184                 :             :                         const char *name,
    2185                 :             :                         gboolean    is_static)
    2186                 :             : {
    2187                 :             :   GMainContext *context;
    2188                 :             : 
    2189                 :     1432215 :   g_return_if_fail (source != NULL);
    2190                 :     1432215 :   g_return_if_fail (g_atomic_int_get (&source->ref_count) > 0);
    2191                 :             : 
    2192                 :     1432215 :   context = source_dup_main_context (source);
    2193                 :             : 
    2194                 :     1432215 :   if (context)
    2195                 :          12 :     LOCK_CONTEXT (context);
    2196                 :             : 
    2197                 :     1173675 :   TRACE (GLIB_SOURCE_SET_NAME (source, name));
    2198                 :             : 
    2199                 :             :   /* setting back to NULL is allowed, just because it's
    2200                 :             :    * weird if get_name can return NULL but you can't
    2201                 :             :    * set that.
    2202                 :             :    */
    2203                 :             : 
    2204                 :     1432215 :   if (!source->priv->static_name)
    2205                 :      988305 :     g_free (source->name);
    2206                 :             : 
    2207                 :     1432215 :   if (is_static)
    2208                 :     1333245 :     source->name = (char *)name;
    2209                 :             :   else
    2210                 :       98970 :     source->name = g_strdup (name);
    2211                 :             : 
    2212                 :     1432215 :   source->priv->static_name = is_static;
    2213                 :             : 
    2214                 :     1432215 :   if (context)
    2215                 :             :     {
    2216                 :          12 :       UNLOCK_CONTEXT (context);
    2217                 :          12 :       g_main_context_unref (context);
    2218                 :           6 :     }
    2219                 :      258540 : }
    2220                 :             : 
    2221                 :             : /**
    2222                 :             :  * g_source_set_name:
    2223                 :             :  * @source: a source
    2224                 :             :  * @name: debug name for the source
    2225                 :             :  *
    2226                 :             :  * Sets a name for the source, used in debugging and profiling.
    2227                 :             :  *
    2228                 :             :  * The name defaults to `NULL`.
    2229                 :             :  *
    2230                 :             :  * The source name should describe in a human-readable way
    2231                 :             :  * what the source does. For example, ‘X11 event queue’
    2232                 :             :  * or ‘GTK repaint idle handler’.
    2233                 :             :  *
    2234                 :             :  * It is permitted to call this function multiple times, but is not
    2235                 :             :  * recommended due to the potential performance impact.  For example,
    2236                 :             :  * one could change the name in the `check` function of a
    2237                 :             :  * [struct@GLib.SourceFuncs] to include details like the event type in the
    2238                 :             :  * source name.
    2239                 :             :  *
    2240                 :             :  * Use caution if changing the name while another thread may be
    2241                 :             :  * accessing it with [method@GLib.Source.get_name]; that function does not copy
    2242                 :             :  * the value, and changing the value will free it while the other thread
    2243                 :             :  * may be attempting to use it.
    2244                 :             :  *
    2245                 :             :  * Also see [method@GLib.Source.set_static_name].
    2246                 :             :  *
    2247                 :             :  * Since: 2.26
    2248                 :             :  **/
    2249                 :             : void
    2250                 :       98970 : g_source_set_name (GSource    *source,
    2251                 :             :                    const char *name)
    2252                 :             : {
    2253                 :       98970 :   g_source_set_name_full (source, name, FALSE);
    2254                 :       98970 : }
    2255                 :             : 
    2256                 :             : /**
    2257                 :             :  * g_source_set_static_name:
    2258                 :             :  * @source: a source
    2259                 :             :  * @name: debug name for the source
    2260                 :             :  *
    2261                 :             :  * A variant of [method@GLib.Source.set_name] that does not
    2262                 :             :  * duplicate the @name, and can only be used with
    2263                 :             :  * string literals.
    2264                 :             :  *
    2265                 :             :  * Since: 2.70
    2266                 :             :  */
    2267                 :             : void
    2268                 :     1333243 : g_source_set_static_name (GSource    *source,
    2269                 :             :                           const char *name)
    2270                 :             : {
    2271                 :     1333243 :   g_source_set_name_full (source, name, TRUE);
    2272                 :     1333243 : }
    2273                 :             : 
    2274                 :             : /**
    2275                 :             :  * g_source_get_name:
    2276                 :             :  * @source: a source
    2277                 :             :  *
    2278                 :             :  * Gets a name for the source, used in debugging and profiling.
    2279                 :             :  *
    2280                 :             :  * The
    2281                 :             :  * name may be `NULL` if it has never been set with [method@GLib.Source.set_name].
    2282                 :             :  *
    2283                 :             :  * Returns: (nullable): the name of the source
    2284                 :             :  * Since: 2.26
    2285                 :             :  **/
    2286                 :             : const char *
    2287                 :     6263231 : g_source_get_name (GSource *source)
    2288                 :             : {
    2289                 :     6263231 :   g_return_val_if_fail (source != NULL, NULL);
    2290                 :     6263231 :   g_return_val_if_fail (g_atomic_int_get (&source->ref_count) > 0, NULL);
    2291                 :             : 
    2292                 :     6263231 :   return source->name;
    2293                 :        2151 : }
    2294                 :             : 
    2295                 :             : /**
    2296                 :             :  * g_source_set_name_by_id:
    2297                 :             :  * @tag: a source ID
    2298                 :             :  * @name: debug name for the source
    2299                 :             :  *
    2300                 :             :  * Sets the name of a source using its ID.
    2301                 :             :  *
    2302                 :             :  * This is a convenience utility to set source names from the return
    2303                 :             :  * value of [func@GLib.idle_add], [func@GLib.timeout_add], etc.
    2304                 :             :  *
    2305                 :             :  * It is a programmer error to attempt to set the name of a non-existent
    2306                 :             :  * source.
    2307                 :             :  *
    2308                 :             :  * More specifically: source IDs can be reissued after a source has been
    2309                 :             :  * destroyed and therefore it is never valid to use this function with a
    2310                 :             :  * source ID which may have already been removed.  An example is when
    2311                 :             :  * scheduling an idle to run in another thread with [func@GLib.idle_add]: the
    2312                 :             :  * idle may already have run and been removed by the time this function
    2313                 :             :  * is called on its (now invalid) source ID.  This source ID may have
    2314                 :             :  * been reissued, leading to the operation being performed against the
    2315                 :             :  * wrong source.
    2316                 :             :  *
    2317                 :             :  * Since: 2.26
    2318                 :             :  **/
    2319                 :             : void
    2320                 :          12 : g_source_set_name_by_id (guint           tag,
    2321                 :             :                          const char     *name)
    2322                 :             : {
    2323                 :             :   GSource *source;
    2324                 :             : 
    2325                 :          12 :   g_return_if_fail (tag > 0);
    2326                 :             : 
    2327                 :          12 :   source = g_main_context_find_source_by_id (NULL, tag);
    2328                 :          12 :   if (source == NULL)
    2329                 :           0 :     return;
    2330                 :             : 
    2331                 :          12 :   g_source_set_name (source, name);
    2332                 :           6 : }
    2333                 :             : 
    2334                 :             : 
    2335                 :             : /**
    2336                 :             :  * g_source_ref:
    2337                 :             :  * @source: a source
    2338                 :             :  * 
    2339                 :             :  * Increases the reference count on a source by one.
    2340                 :             :  * 
    2341                 :             :  * Returns: @source
    2342                 :             :  **/
    2343                 :             : GSource *
    2344                 :     5999891 : g_source_ref (GSource *source)
    2345                 :             : {
    2346                 :             :   int old_ref G_GNUC_UNUSED;
    2347                 :     5999891 :   g_return_val_if_fail (source != NULL, NULL);
    2348                 :             : 
    2349                 :     5999891 :   old_ref = g_atomic_int_add (&source->ref_count, 1);
    2350                 :             :   /* We allow ref_count == 0 here to allow the dispose function to resurrect
    2351                 :             :    * the GSource if needed */
    2352                 :     5999891 :   g_return_val_if_fail (old_ref >= 0, NULL);
    2353                 :             : 
    2354                 :     5999891 :   return source;
    2355                 :     1074407 : }
    2356                 :             : 
    2357                 :             : /* g_source_unref() but possible to call within context lock
    2358                 :             :  */
    2359                 :             : static void
    2360                 :     7012376 : g_source_unref_internal (GSource      *source,
    2361                 :             :                          GMainContext *context,
    2362                 :             :                          gboolean      have_lock)
    2363                 :             : {
    2364                 :     7012376 :   gpointer old_cb_data = NULL;
    2365                 :     7012376 :   GSourceCallbackFuncs *old_cb_funcs = NULL;
    2366                 :             :   int old_ref;
    2367                 :             : 
    2368                 :    11937428 :   g_return_if_fail (source != NULL);
    2369                 :             : 
    2370                 :     7012376 :   old_ref = g_atomic_int_get (&source->ref_count);
    2371                 :             : 
    2372                 :           9 : retry_beginning:
    2373                 :     7012386 :   if (old_ref > 1)
    2374                 :             :     {
    2375                 :             :       /* We have many references. If we can decrement the ref counter, we are done. */
    2376                 :     7073834 :       if (!g_atomic_int_compare_and_exchange_full ((int *) &source->ref_count,
    2377                 :     2148774 :                                                    old_ref, old_ref - 1,
    2378                 :             :                                                    &old_ref))
    2379                 :           8 :         goto retry_beginning;
    2380                 :             : 
    2381                 :     5999439 :       return;
    2382                 :             :     }
    2383                 :             : 
    2384                 :     1012939 :   g_return_if_fail (old_ref > 0);
    2385                 :             : 
    2386                 :     1012939 :   if (!have_lock && context)
    2387                 :      232786 :     LOCK_CONTEXT (context);
    2388                 :             : 
    2389                 :             :   /* We are about to drop the last reference, there's not guarantee at this
    2390                 :             :    * point that another thread already changed the value at this point or
    2391                 :             :    * that is also entering the disposal phase, but there is no much we can do
    2392                 :             :    * and dropping the reference too early would be still risky since it could
    2393                 :             :    * lead to a preventive finalization.
    2394                 :             :    * So let's just get all the threads that reached this point to get in, while
    2395                 :             :    * the final check on whether is the case or not to continue with the
    2396                 :             :    * finalization will be done by a final unique atomic dec and test.
    2397                 :             :    */
    2398                 :     1012939 :   if (old_ref == 1)
    2399                 :             :     {
    2400                 :             :       /* If there's a dispose function, call this first */
    2401                 :             :       GSourceDisposeFunc dispose_func;
    2402                 :             : 
    2403                 :     1013114 :       if ((dispose_func = g_atomic_pointer_get (&source->priv->dispose)))
    2404                 :             :         {
    2405                 :      215009 :           if (context)
    2406                 :       15003 :             UNLOCK_CONTEXT (context);
    2407                 :      215009 :           dispose_func (source);
    2408                 :      215009 :           if (context)
    2409                 :       15003 :             LOCK_CONTEXT (context);
    2410                 :      100194 :         }
    2411                 :             : 
    2412                 :             :       /* At this point the source can have been revived by any of the threads
    2413                 :             :        * acting on it or it's really ready for being finalized.
    2414                 :             :        */
    2415                 :     1013114 :       if (!g_atomic_int_compare_and_exchange_full ((int *) &source->ref_count,
    2416                 :             :                                                    1, 0, &old_ref))
    2417                 :             :         {
    2418                 :           2 :           if (!have_lock && context)
    2419                 :           0 :             UNLOCK_CONTEXT (context);
    2420                 :             : 
    2421                 :           2 :           goto retry_beginning;
    2422                 :             :         }
    2423                 :             : 
    2424                 :      745542 :       TRACE (GLIB_SOURCE_BEFORE_FREE (source, context,
    2425                 :             :                                       source->source_funcs->finalize));
    2426                 :             : 
    2427                 :     1013112 :       old_cb_data = source->callback_data;
    2428                 :     1013112 :       old_cb_funcs = source->callback_funcs;
    2429                 :             : 
    2430                 :     1013112 :       source->callback_data = NULL;
    2431                 :     1013112 :       source->callback_funcs = NULL;
    2432                 :             : 
    2433                 :     1013112 :       if (context)
    2434                 :             :         {
    2435                 :      813059 :           if (!SOURCE_DESTROYED (source))
    2436                 :           0 :             g_warning (G_STRLOC ": ref_count == 0, but source was still attached to a context!");
    2437                 :      813059 :           source_remove_from_context (source, context);
    2438                 :             : 
    2439                 :      813059 :           g_hash_table_remove (context->sources, &source->source_id);
    2440                 :      167544 :         }
    2441                 :             : 
    2442                 :     1013112 :       if (source->source_funcs->finalize)
    2443                 :             :         {
    2444                 :             :           gint old_ref_count;
    2445                 :             : 
    2446                 :             :           /* Temporarily increase the ref count again so that GSource methods
    2447                 :             :            * can be called from finalize(). */
    2448                 :       18262 :           g_atomic_int_inc (&source->ref_count);
    2449                 :       18262 :           if (context)
    2450                 :       18223 :             UNLOCK_CONTEXT (context);
    2451                 :       18262 :           source->source_funcs->finalize (source);
    2452                 :       18262 :           if (context)
    2453                 :       18223 :             LOCK_CONTEXT (context);
    2454                 :       18262 :           old_ref_count = g_atomic_int_add (&source->ref_count, -1);
    2455                 :       18262 :           g_warn_if_fail (old_ref_count == 1);
    2456                 :        1243 :         }
    2457                 :             : 
    2458                 :     1013112 :       if (old_cb_funcs)
    2459                 :             :         {
    2460                 :             :           gint old_ref_count;
    2461                 :             : 
    2462                 :             :           /* Temporarily increase the ref count again so that GSource methods
    2463                 :             :            * can be called from callback_funcs.unref(). */
    2464                 :      200000 :           g_atomic_int_inc (&source->ref_count);
    2465                 :      200000 :           if (context)
    2466                 :           0 :             UNLOCK_CONTEXT (context);
    2467                 :             : 
    2468                 :      200000 :           old_cb_funcs->unref (old_cb_data);
    2469                 :             : 
    2470                 :      200000 :           if (context)
    2471                 :           0 :             LOCK_CONTEXT (context);
    2472                 :      200000 :           old_ref_count = g_atomic_int_add (&source->ref_count, -1);
    2473                 :      200000 :           g_warn_if_fail (old_ref_count == 1);
    2474                 :      100000 :         }
    2475                 :             : 
    2476                 :     1013112 :       if (!source->priv->static_name)
    2477                 :      124757 :         g_free (source->name);
    2478                 :     1013112 :       source->name = NULL;
    2479                 :             : 
    2480                 :     1013112 :       g_slist_free (source->poll_fds);
    2481                 :     1013112 :       source->poll_fds = NULL;
    2482                 :             : 
    2483                 :     1013112 :       g_slist_free_full (source->priv->fds, g_free);
    2484                 :             : 
    2485                 :     1013112 :       while (source->priv->child_sources)
    2486                 :             :         {
    2487                 :           0 :           GSource *child_source = source->priv->child_sources->data;
    2488                 :             : 
    2489                 :           0 :           source->priv->child_sources =
    2490                 :           0 :             g_slist_remove (source->priv->child_sources, child_source);
    2491                 :           0 :           child_source->priv->parent_source = NULL;
    2492                 :             : 
    2493                 :           0 :           g_source_unref_internal (child_source, context, TRUE);
    2494                 :             :         }
    2495                 :             : 
    2496                 :     1013112 :       g_slice_free (GSourcePrivate, source->priv);
    2497                 :     1013112 :       source->priv = NULL;
    2498                 :             : 
    2499                 :     1013112 :       g_free (source);
    2500                 :      267570 :     }
    2501                 :             : 
    2502                 :     1013287 :   if (!have_lock && context)
    2503                 :      232786 :     UNLOCK_CONTEXT (context);
    2504                 :     1342132 : }
    2505                 :             : 
    2506                 :             : /**
    2507                 :             :  * g_source_unref:
    2508                 :             :  * @source: a source
    2509                 :             :  *
    2510                 :             :  * Decreases the reference count of a source by one.
    2511                 :             :  * 
    2512                 :             :  * If the resulting reference count is zero the source and associated
    2513                 :             :  * memory will be destroyed.
    2514                 :             :  **/
    2515                 :             : void
    2516                 :     1215260 : g_source_unref (GSource *source)
    2517                 :             : {
    2518                 :             :   GMainContext *context;
    2519                 :             : 
    2520                 :     1215260 :   g_return_if_fail (source != NULL);
    2521                 :             :   /* refcount is checked inside g_source_unref_internal() */
    2522                 :             : 
    2523                 :     1215260 :   context = source_dup_main_context (source);
    2524                 :             : 
    2525                 :     1215260 :   g_source_unref_internal (source, context, FALSE);
    2526                 :             : 
    2527                 :     1215260 :   if (context)
    2528                 :      800846 :     g_main_context_unref (context);
    2529                 :      367650 : }
    2530                 :             : 
    2531                 :             : /**
    2532                 :             :  * g_main_context_find_source_by_id:
    2533                 :             :  * @context: (nullable): a main context (if `NULL`, the global-default
    2534                 :             :  *   main context will be used)
    2535                 :             :  * @source_id: the source ID, as returned by [method@GLib.Source.get_id]
    2536                 :             :  *
    2537                 :             :  * Finds a [struct@GLib.Source] given a pair of context and ID.
    2538                 :             :  *
    2539                 :             :  * It is a programmer error to attempt to look up a non-existent source.
    2540                 :             :  *
    2541                 :             :  * More specifically: source IDs can be reissued after a source has been
    2542                 :             :  * destroyed and therefore it is never valid to use this function with a
    2543                 :             :  * source ID which may have already been removed.  An example is when
    2544                 :             :  * scheduling an idle to run in another thread with [func@GLib.idle_add]: the
    2545                 :             :  * idle may already have run and been removed by the time this function
    2546                 :             :  * is called on its (now invalid) source ID.  This source ID may have
    2547                 :             :  * been reissued, leading to the operation being performed against the
    2548                 :             :  * wrong source.
    2549                 :             :  *
    2550                 :             :  * Returns: (transfer none): the source
    2551                 :             :  **/
    2552                 :             : GSource *
    2553                 :      200470 : g_main_context_find_source_by_id (GMainContext *context,
    2554                 :             :                                   guint         source_id)
    2555                 :             : {
    2556                 :      200470 :   GSource *source = NULL;
    2557                 :             :   gconstpointer ptr;
    2558                 :             : 
    2559                 :      200470 :   g_return_val_if_fail (source_id > 0, NULL);
    2560                 :             : 
    2561                 :      200470 :   if (context == NULL)
    2562                 :         254 :     context = g_main_context_default ();
    2563                 :             : 
    2564                 :      200470 :   LOCK_CONTEXT (context);
    2565                 :      200470 :   ptr = g_hash_table_lookup (context->sources, &source_id);
    2566                 :      200470 :   if (ptr)
    2567                 :             :     {
    2568                 :      200460 :       source = G_CONTAINER_OF (ptr, GSource, source_id);
    2569                 :      200460 :       if (SOURCE_DESTROYED (source))
    2570                 :         108 :         source = NULL;
    2571                 :      100139 :     }
    2572                 :      200470 :   UNLOCK_CONTEXT (context);
    2573                 :             : 
    2574                 :      200470 :   return source;
    2575                 :      100144 : }
    2576                 :             : 
    2577                 :             : /**
    2578                 :             :  * g_main_context_find_source_by_funcs_user_data:
    2579                 :             :  * @context: (nullable): a main context (if `NULL`, the global-default
    2580                 :             :  *   main context will be used).
    2581                 :             :  * @funcs: the @source_funcs passed to [ctor@GLib.Source.new]
    2582                 :             :  * @user_data: the user data from the callback
    2583                 :             :  *
    2584                 :             :  * Finds a source with the given source functions and user data.
    2585                 :             :  * 
    2586                 :             :  * If multiple sources exist with the same source function and user data,
    2587                 :             :  * the first one found will be returned.
    2588                 :             :  * 
    2589                 :             :  * Returns: (transfer none) (nullable): the source, if one was found,
    2590                 :             :  *   otherwise `NULL`
    2591                 :             :  **/
    2592                 :             : GSource *
    2593                 :           6 : g_main_context_find_source_by_funcs_user_data (GMainContext *context,
    2594                 :             :                                                GSourceFuncs *funcs,
    2595                 :             :                                                gpointer      user_data)
    2596                 :             : {
    2597                 :             :   GSourceIter iter;
    2598                 :             :   GSource *source;
    2599                 :             :   
    2600                 :           6 :   g_return_val_if_fail (funcs != NULL, NULL);
    2601                 :             : 
    2602                 :           6 :   if (context == NULL)
    2603                 :           4 :     context = g_main_context_default ();
    2604                 :             :   
    2605                 :           6 :   LOCK_CONTEXT (context);
    2606                 :             : 
    2607                 :           6 :   g_source_iter_init (&iter, context, FALSE);
    2608                 :           6 :   while (g_source_iter_next (&iter, &source))
    2609                 :             :     {
    2610                 :           4 :       if (!SOURCE_DESTROYED (source) &&
    2611                 :           4 :           source->source_funcs == funcs &&
    2612                 :           4 :           source->callback_funcs)
    2613                 :             :         {
    2614                 :             :           GSourceFunc callback;
    2615                 :             :           gpointer callback_data;
    2616                 :             : 
    2617                 :           4 :           source->callback_funcs->get (source->callback_data, source, &callback, &callback_data);
    2618                 :             :           
    2619                 :           4 :           if (callback_data == user_data)
    2620                 :           4 :             break;
    2621                 :           0 :         }
    2622                 :             :     }
    2623                 :           6 :   g_source_iter_clear (&iter);
    2624                 :             : 
    2625                 :           6 :   UNLOCK_CONTEXT (context);
    2626                 :             : 
    2627                 :           6 :   return source;
    2628                 :           3 : }
    2629                 :             : 
    2630                 :             : /**
    2631                 :             :  * g_main_context_find_source_by_user_data:
    2632                 :             :  * @context: (nullable): a main context (if `NULL`, the global-default
    2633                 :             :  *   main context will be used)
    2634                 :             :  * @user_data: the user_data for the callback
    2635                 :             :  * 
    2636                 :             :  * Finds a source with the given user data for the callback.
    2637                 :             :  *
    2638                 :             :  * If multiple sources exist with the same user data, the first
    2639                 :             :  * one found will be returned.
    2640                 :             :  * 
    2641                 :             :  * Returns: (transfer none) (nullable): the source, if one was found,
    2642                 :             :  *   otherwise `NULL`
    2643                 :             :  **/
    2644                 :             : GSource *
    2645                 :           6 : g_main_context_find_source_by_user_data (GMainContext *context,
    2646                 :             :                                          gpointer      user_data)
    2647                 :             : {
    2648                 :             :   GSourceIter iter;
    2649                 :             :   GSource *source;
    2650                 :             :   
    2651                 :           6 :   if (context == NULL)
    2652                 :           4 :     context = g_main_context_default ();
    2653                 :             :   
    2654                 :           6 :   LOCK_CONTEXT (context);
    2655                 :             : 
    2656                 :           6 :   g_source_iter_init (&iter, context, FALSE);
    2657                 :           6 :   while (g_source_iter_next (&iter, &source))
    2658                 :             :     {
    2659                 :           2 :       if (!SOURCE_DESTROYED (source) &&
    2660                 :           2 :           source->callback_funcs)
    2661                 :             :         {
    2662                 :             :           GSourceFunc callback;
    2663                 :           2 :           gpointer callback_data = NULL;
    2664                 :             : 
    2665                 :           2 :           source->callback_funcs->get (source->callback_data, source, &callback, &callback_data);
    2666                 :             : 
    2667                 :           2 :           if (callback_data == user_data)
    2668                 :           2 :             break;
    2669                 :           0 :         }
    2670                 :             :     }
    2671                 :           6 :   g_source_iter_clear (&iter);
    2672                 :             : 
    2673                 :           6 :   UNLOCK_CONTEXT (context);
    2674                 :             : 
    2675                 :           6 :   return source;
    2676                 :             : }
    2677                 :             : 
    2678                 :             : /**
    2679                 :             :  * g_source_remove:
    2680                 :             :  * @tag: the ID of the source to remove.
    2681                 :             :  *
    2682                 :             :  * Removes the source with the given ID from the default main context.
    2683                 :             :  *
    2684                 :             :  * You must
    2685                 :             :  * use [method@GLib.Source.destroy] for sources added to a non-default main context.
    2686                 :             :  *
    2687                 :             :  * The ID of a [struct@GLib.Source] is given by [method@GLib.Source.get_id], or will be
    2688                 :             :  * returned by the functions [method@GLib.Source.attach], [func@GLib.idle_add],
    2689                 :             :  * [func@GLib.idle_add_full], [func@GLib.timeout_add],
    2690                 :             :  * [func@GLib.timeout_add_full], [func@GLib.child_watch_add],
    2691                 :             :  * [func@GLib.child_watch_add_full], [func@GLib.io_add_watch], and
    2692                 :             :  * [func@GLib.io_add_watch_full].
    2693                 :             :  *
    2694                 :             :  * It is a programmer error to attempt to remove a non-existent source.
    2695                 :             :  *
    2696                 :             :  * More specifically: source IDs can be reissued after a source has been
    2697                 :             :  * destroyed and therefore it is never valid to use this function with a
    2698                 :             :  * source ID which may have already been removed.  An example is when
    2699                 :             :  * scheduling an idle to run in another thread with [func@GLib.idle_add]: the
    2700                 :             :  * idle may already have run and been removed by the time this function
    2701                 :             :  * is called on its (now invalid) source ID.  This source ID may have
    2702                 :             :  * been reissued, leading to the operation being performed against the
    2703                 :             :  * wrong source.
    2704                 :             :  *
    2705                 :             :  * Returns: true if the source was found and removed, false otherwise
    2706                 :             :  **/
    2707                 :             : gboolean
    2708                 :         236 : g_source_remove (guint tag)
    2709                 :             : {
    2710                 :             :   GSource *source;
    2711                 :             : 
    2712                 :         236 :   g_return_val_if_fail (tag > 0, FALSE);
    2713                 :             : 
    2714                 :         236 :   source = g_main_context_find_source_by_id (NULL, tag);
    2715                 :         236 :   if (source)
    2716                 :         226 :     g_source_destroy (source);
    2717                 :             :   else
    2718                 :          10 :     g_critical ("Source ID %u was not found when attempting to remove it", tag);
    2719                 :             : 
    2720                 :         236 :   return source != NULL;
    2721                 :          28 : }
    2722                 :             : 
    2723                 :             : /**
    2724                 :             :  * g_source_remove_by_user_data:
    2725                 :             :  * @user_data: the user_data for the callback
    2726                 :             :  * 
    2727                 :             :  * Removes a source from the default main loop context given the user
    2728                 :             :  * data for the callback.
    2729                 :             :  * 
    2730                 :             :  * If multiple sources exist with the same user data, only one will be destroyed.
    2731                 :             :  *
    2732                 :             :  * Returns: true if a source was found and removed, false otherwise
    2733                 :             :  **/
    2734                 :             : gboolean
    2735                 :           4 : g_source_remove_by_user_data (gpointer user_data)
    2736                 :             : {
    2737                 :             :   GSource *source;
    2738                 :             :   
    2739                 :           4 :   source = g_main_context_find_source_by_user_data (NULL, user_data);
    2740                 :           4 :   if (source)
    2741                 :             :     {
    2742                 :           2 :       g_source_destroy (source);
    2743                 :           2 :       return TRUE;
    2744                 :             :     }
    2745                 :             :   else
    2746                 :           2 :     return FALSE;
    2747                 :           2 : }
    2748                 :             : 
    2749                 :             : /**
    2750                 :             :  * g_source_remove_by_funcs_user_data:
    2751                 :             :  * @funcs: the @source_funcs passed to [ctor@GLib.Source.new]
    2752                 :             :  * @user_data: the user data for the callback
    2753                 :             :  * 
    2754                 :             :  * Removes a source from the default main loop context given the
    2755                 :             :  * source functions and user data.
    2756                 :             :  * 
    2757                 :             :  * If multiple sources exist with the same source functions and user data, only
    2758                 :             :  * one will be destroyed.
    2759                 :             :  *
    2760                 :             :  * Returns: true if a source was found and removed, false otherwise
    2761                 :             :  **/
    2762                 :             : gboolean
    2763                 :           4 : g_source_remove_by_funcs_user_data (GSourceFuncs *funcs,
    2764                 :             :                                     gpointer      user_data)
    2765                 :             : {
    2766                 :             :   GSource *source;
    2767                 :             : 
    2768                 :           4 :   g_return_val_if_fail (funcs != NULL, FALSE);
    2769                 :             : 
    2770                 :           4 :   source = g_main_context_find_source_by_funcs_user_data (NULL, funcs, user_data);
    2771                 :           4 :   if (source)
    2772                 :             :     {
    2773                 :           4 :       g_source_destroy (source);
    2774                 :           4 :       return TRUE;
    2775                 :             :     }
    2776                 :             :   else
    2777                 :           0 :     return FALSE;
    2778                 :           2 : }
    2779                 :             : 
    2780                 :             : /**
    2781                 :             :  * g_clear_handle_id: (skip)
    2782                 :             :  * @tag_ptr: (not nullable): a pointer to the handler ID
    2783                 :             :  * @clear_func: (not nullable): the function to call to clear the handler
    2784                 :             :  *
    2785                 :             :  * Clears a numeric handler, such as a [struct@GLib.Source] ID.
    2786                 :             :  *
    2787                 :             :  * The @tag_ptr must be a valid pointer to the variable holding the handler.
    2788                 :             :  *
    2789                 :             :  * If the ID is zero then this function does nothing.
    2790                 :             :  * Otherwise, @clear_func is called with the ID as a parameter, and the tag is
    2791                 :             :  * set to zero.
    2792                 :             :  *
    2793                 :             :  * A macro is also included that allows this function to be used without
    2794                 :             :  * pointer casts.
    2795                 :             :  *
    2796                 :             :  * Since: 2.56
    2797                 :             :  */
    2798                 :             : #undef g_clear_handle_id
    2799                 :             : void
    2800                 :           0 : g_clear_handle_id (guint            *tag_ptr,
    2801                 :             :                    GClearHandleFunc  clear_func)
    2802                 :             : {
    2803                 :             :   guint _handle_id;
    2804                 :             : 
    2805                 :           0 :   _handle_id = *tag_ptr;
    2806                 :           0 :   if (_handle_id > 0)
    2807                 :             :     {
    2808                 :           0 :       *tag_ptr = 0;
    2809                 :           0 :       clear_func (_handle_id);
    2810                 :           0 :     }
    2811                 :           0 : }
    2812                 :             : 
    2813                 :             : #ifdef G_OS_UNIX
    2814                 :             : /**
    2815                 :             :  * g_source_add_unix_fd:
    2816                 :             :  * @source: a source
    2817                 :             :  * @fd: the file descriptor to monitor
    2818                 :             :  * @events: an event mask
    2819                 :             :  *
    2820                 :             :  * Monitors @fd for the IO events in @events.
    2821                 :             :  *
    2822                 :             :  * The tag returned by this function can be used to remove or modify the
    2823                 :             :  * monitoring of the @fd using [method@GLib.Source.remove_unix_fd] or
    2824                 :             :  * [method@GLib.Source.modify_unix_fd].
    2825                 :             :  *
    2826                 :             :  * It is not necessary to remove the file descriptor before destroying the
    2827                 :             :  * source; it will be cleaned up automatically.
    2828                 :             :  *
    2829                 :             :  * This API is only intended to be used by implementations of [struct@GLib.Source].
    2830                 :             :  * Do not call this API on a [struct@GLib.Source] that you did not create.
    2831                 :             :  *
    2832                 :             :  * As the name suggests, this function is not available on Windows.
    2833                 :             :  *
    2834                 :             :  * Returns: (not nullable): an opaque tag
    2835                 :             :  * Since: 2.36
    2836                 :             :  **/
    2837                 :             : gpointer
    2838                 :       15043 : g_source_add_unix_fd (GSource      *source,
    2839                 :             :                       gint          fd,
    2840                 :             :                       GIOCondition  events)
    2841                 :             : {
    2842                 :             :   GMainContext *context;
    2843                 :             :   GPollFD *poll_fd;
    2844                 :             : 
    2845                 :       15043 :   g_return_val_if_fail (source != NULL, NULL);
    2846                 :       15043 :   g_return_val_if_fail (g_atomic_int_get (&source->ref_count) > 0, NULL);
    2847                 :       15043 :   g_return_val_if_fail (!SOURCE_DESTROYED (source), NULL);
    2848                 :             : 
    2849                 :       15043 :   poll_fd = g_new (GPollFD, 1);
    2850                 :       15043 :   poll_fd->fd = fd;
    2851                 :       15043 :   poll_fd->events = events;
    2852                 :       15043 :   poll_fd->revents = 0;
    2853                 :             : 
    2854                 :       15043 :   context = source_dup_main_context (source);
    2855                 :             : 
    2856                 :       15043 :   if (context)
    2857                 :           2 :     LOCK_CONTEXT (context);
    2858                 :             : 
    2859                 :       15043 :   source->priv->fds = g_slist_prepend (source->priv->fds, poll_fd);
    2860                 :             : 
    2861                 :       15043 :   if (context)
    2862                 :             :     {
    2863                 :           2 :       if (!SOURCE_BLOCKED (source))
    2864                 :           2 :         g_main_context_add_poll_unlocked (context, source->priority, poll_fd);
    2865                 :           2 :       UNLOCK_CONTEXT (context);
    2866                 :           2 :       g_main_context_unref (context);
    2867                 :             :     }
    2868                 :             : 
    2869                 :       15043 :   return poll_fd;
    2870                 :             : }
    2871                 :             : 
    2872                 :             : /**
    2873                 :             :  * g_source_modify_unix_fd:
    2874                 :             :  * @source: a source
    2875                 :             :  * @tag: (not nullable): the tag from [method@GLib.Source.add_unix_fd]
    2876                 :             :  * @new_events: the new event mask to watch
    2877                 :             :  *
    2878                 :             :  * Updates the event mask to watch for the file descriptor identified by @tag.
    2879                 :             :  *
    2880                 :             :  * The @tag is the tag returned from [method@GLib.Source.add_unix_fd].
    2881                 :             :  *
    2882                 :             :  * If you want to remove a file descriptor, don’t set its event mask to zero.
    2883                 :             :  * Instead, call [method@GLib.Source.remove_unix_fd].
    2884                 :             :  *
    2885                 :             :  * This API is only intended to be used by implementations of [struct@GLib.Source].
    2886                 :             :  * Do not call this API on a [struct@GLib.Source] that you did not create.
    2887                 :             :  *
    2888                 :             :  * As the name suggests, this function is not available on Windows.
    2889                 :             :  *
    2890                 :             :  * Since: 2.36
    2891                 :             :  **/
    2892                 :             : void
    2893                 :          20 : g_source_modify_unix_fd (GSource      *source,
    2894                 :             :                          gpointer      tag,
    2895                 :             :                          GIOCondition  new_events)
    2896                 :             : {
    2897                 :             :   GMainContext *context;
    2898                 :             :   GPollFD *poll_fd;
    2899                 :             : 
    2900                 :          20 :   g_return_if_fail (source != NULL);
    2901                 :          20 :   g_return_if_fail (g_atomic_int_get (&source->ref_count) > 0);
    2902                 :          20 :   g_return_if_fail (g_slist_find (source->priv->fds, tag));
    2903                 :             : 
    2904                 :          20 :   context = source_dup_main_context (source);
    2905                 :          20 :   poll_fd = tag;
    2906                 :             : 
    2907                 :          20 :   poll_fd->events = new_events;
    2908                 :             : 
    2909                 :          20 :   if (context)
    2910                 :             :     {
    2911                 :          20 :       g_main_context_wakeup (context);
    2912                 :          20 :       g_main_context_unref (context);
    2913                 :             :     }
    2914                 :             : }
    2915                 :             : 
    2916                 :             : /**
    2917                 :             :  * g_source_remove_unix_fd:
    2918                 :             :  * @source: a source
    2919                 :             :  * @tag: (not nullable): the tag from [method@GLib.Source.add_unix_fd]
    2920                 :             :  *
    2921                 :             :  * Reverses the effect of a previous call to [method@GLib.Source.add_unix_fd].
    2922                 :             :  *
    2923                 :             :  * You only need to call this if you want to remove a file descriptor from being
    2924                 :             :  * watched while keeping the same source around.  In the normal case you
    2925                 :             :  * will just want to destroy the source.
    2926                 :             :  *
    2927                 :             :  * This API is only intended to be used by implementations of [struct@GLib.Source].
    2928                 :             :  * Do not call this API on a [struct@GLib.Source] that you did not create.
    2929                 :             :  *
    2930                 :             :  * As the name suggests, this function is not available on Windows.
    2931                 :             :  *
    2932                 :             :  * Since: 2.36
    2933                 :             :  **/
    2934                 :             : void
    2935                 :          43 : g_source_remove_unix_fd (GSource  *source,
    2936                 :             :                          gpointer  tag)
    2937                 :             : {
    2938                 :             :   GMainContext *context;
    2939                 :             :   GPollFD *poll_fd;
    2940                 :             : 
    2941                 :          43 :   g_return_if_fail (source != NULL);
    2942                 :          43 :   g_return_if_fail (g_atomic_int_get (&source->ref_count) > 0);
    2943                 :          43 :   g_return_if_fail (g_slist_find (source->priv->fds, tag));
    2944                 :             : 
    2945                 :          43 :   context = source_dup_main_context (source);
    2946                 :          43 :   poll_fd = tag;
    2947                 :             : 
    2948                 :          43 :   if (context)
    2949                 :          43 :     LOCK_CONTEXT (context);
    2950                 :             : 
    2951                 :          43 :   source->priv->fds = g_slist_remove (source->priv->fds, poll_fd);
    2952                 :             : 
    2953                 :          43 :   if (context)
    2954                 :             :     {
    2955                 :          43 :       if (!SOURCE_BLOCKED (source))
    2956                 :           2 :         g_main_context_remove_poll_unlocked (context, poll_fd);
    2957                 :             : 
    2958                 :          43 :       UNLOCK_CONTEXT (context);
    2959                 :          43 :       g_main_context_unref (context);
    2960                 :             :     }
    2961                 :             : 
    2962                 :          43 :   g_free (poll_fd);
    2963                 :             : }
    2964                 :             : 
    2965                 :             : /**
    2966                 :             :  * g_source_query_unix_fd:
    2967                 :             :  * @source: a source
    2968                 :             :  * @tag: (not nullable): the tag from [method@GLib.Source.add_unix_fd]
    2969                 :             :  *
    2970                 :             :  * Queries the events reported for the file descriptor corresponding to @tag
    2971                 :             :  * on @source during the last poll.
    2972                 :             :  *
    2973                 :             :  * The return value of this function is only defined when the function
    2974                 :             :  * is called from the check or dispatch functions for @source.
    2975                 :             :  *
    2976                 :             :  * This API is only intended to be used by implementations of [struct@GLib.Source].
    2977                 :             :  * Do not call this API on a [struct@GLib.Source] that you did not create.
    2978                 :             :  *
    2979                 :             :  * As the name suggests, this function is not available on Windows.
    2980                 :             :  *
    2981                 :             :  * Returns: the conditions reported on the file descriptor
    2982                 :             :  * Since: 2.36
    2983                 :             :  **/
    2984                 :             : GIOCondition
    2985                 :      277306 : g_source_query_unix_fd (GSource  *source,
    2986                 :             :                         gpointer  tag)
    2987                 :             : {
    2988                 :             :   GPollFD *poll_fd;
    2989                 :             : 
    2990                 :      277306 :   g_return_val_if_fail (source != NULL, 0);
    2991                 :      277306 :   g_return_val_if_fail (g_atomic_int_get (&source->ref_count) > 0, 0);
    2992                 :      277306 :   g_return_val_if_fail (g_slist_find (source->priv->fds, tag), 0);
    2993                 :             : 
    2994                 :      277306 :   poll_fd = tag;
    2995                 :             : 
    2996                 :      277306 :   return poll_fd->revents;
    2997                 :             : }
    2998                 :             : #endif /* G_OS_UNIX */
    2999                 :             : 
    3000                 :             : /**
    3001                 :             :  * g_get_current_time:
    3002                 :             :  * @result: [struct@GLib.TimeVal] structure in which to store current time
    3003                 :             :  *
    3004                 :             :  * Queries the system wall-clock time.
    3005                 :             :  *
    3006                 :             :  * This is equivalent to the UNIX [`gettimeofday()`](man:gettimeofday(2))
    3007                 :             :  * function, but portable.
    3008                 :             :  *
    3009                 :             :  * You may find [func@GLib.get_real_time] to be more convenient.
    3010                 :             :  *
    3011                 :             :  * Deprecated: 2.62: [struct@GLib.TimeVal] is not year-2038-safe. Use
    3012                 :             :  *    [func@GLib.get_real_time] instead.
    3013                 :             :  **/
    3014                 :             : G_GNUC_BEGIN_IGNORE_DEPRECATIONS
    3015                 :             : void
    3016                 :          17 : g_get_current_time (GTimeVal *result)
    3017                 :             : {
    3018                 :             :   gint64 tv;
    3019                 :             : 
    3020                 :          17 :   g_return_if_fail (result != NULL);
    3021                 :             : 
    3022                 :          17 :   tv = g_get_real_time ();
    3023                 :             : 
    3024                 :          17 :   result->tv_sec = tv / 1000000;
    3025                 :          17 :   result->tv_usec = tv % 1000000;
    3026                 :           8 : }
    3027                 :             : G_GNUC_END_IGNORE_DEPRECATIONS
    3028                 :             : 
    3029                 :             : /**
    3030                 :             :  * g_get_real_time:
    3031                 :             :  *
    3032                 :             :  * Queries the system wall-clock time.
    3033                 :             :  *
    3034                 :             :  * This is equivalent to the UNIX [`gettimeofday()`](man:gettimeofday(2))
    3035                 :             :  * function, but portable.
    3036                 :             :  *
    3037                 :             :  * You should only use this call if you are actually interested in the real
    3038                 :             :  * wall-clock time. [func@GLib.get_monotonic_time] is probably more useful for
    3039                 :             :  * measuring intervals.
    3040                 :             :  *
    3041                 :             :  * Returns: the number of microseconds since
    3042                 :             :  *   [January 1, 1970 UTC](https://en.wikipedia.org/wiki/Unix_time)
    3043                 :             :  * Since: 2.28
    3044                 :             :  **/
    3045                 :             : gint64
    3046                 :        3287 : g_get_real_time (void)
    3047                 :             : {
    3048                 :             : #ifndef G_OS_WIN32
    3049                 :             :   struct timeval r;
    3050                 :             : 
    3051                 :             :   /* this is required on alpha, there the timeval structs are ints
    3052                 :             :    * not longs and a cast only would fail horribly */
    3053                 :        2190 :   gettimeofday (&r, NULL);
    3054                 :             : 
    3055                 :        2190 :   return (((gint64) r.tv_sec) * 1000000) + r.tv_usec;
    3056                 :             : #else
    3057                 :             :   FILETIME ft;
    3058                 :             :   guint64 time64;
    3059                 :             : 
    3060                 :        1097 :   GetSystemTimeAsFileTime (&ft);
    3061                 :        1097 :   memmove (&time64, &ft, sizeof (FILETIME));
    3062                 :             : 
    3063                 :             :   /* Convert from 100s of nanoseconds since 1601-01-01
    3064                 :             :    * to Unix epoch. This is Y2038 safe.
    3065                 :             :    */
    3066                 :        1097 :   time64 -= G_GINT64_CONSTANT (116444736000000000);
    3067                 :        1097 :   time64 /= 10;
    3068                 :             : 
    3069                 :        1097 :   return time64;
    3070                 :             : #endif
    3071                 :             : }
    3072                 :             : 
    3073                 :             : /**
    3074                 :             :  * g_get_monotonic_time:
    3075                 :             :  *
    3076                 :             :  * Queries the system monotonic time in microseconds.
    3077                 :             :  *
    3078                 :             :  * The monotonic clock will always increase and doesn’t suffer
    3079                 :             :  * discontinuities when the user (or NTP) changes the system time.  It
    3080                 :             :  * may or may not continue to tick during times where the machine is
    3081                 :             :  * suspended.
    3082                 :             :  *
    3083                 :             :  * We try to use the clock that corresponds as closely as possible to
    3084                 :             :  * the passage of time as measured by system calls such as
    3085                 :             :  * [`poll()`](man:poll(2)) but it
    3086                 :             :  * may not always be possible to do this.
    3087                 :             :  *
    3088                 :             :  * A more accurate version of this function exists.
    3089                 :             :  * [func@GLib.get_monotonic_time_ns] returns the time in nanoseconds.
    3090                 :             :  *
    3091                 :             :  * Returns: the monotonic time, in microseconds
    3092                 :             :  * Since: 2.28
    3093                 :             :  **/
    3094                 :             : /**
    3095                 :             :  * g_get_monotonic_time_ns:
    3096                 :             :  *
    3097                 :             :  * Queries the system monotonic time in nanoseconds.
    3098                 :             :  *
    3099                 :             :  * The monotonic clock will always increase and doesn’t suffer
    3100                 :             :  * discontinuities when the user (or NTP) changes the system time.  It
    3101                 :             :  * may or may not continue to tick during times where the machine is
    3102                 :             :  * suspended.
    3103                 :             :  *
    3104                 :             :  * We try to use the clock that corresponds as closely as possible to
    3105                 :             :  * the passage of time as measured by system calls such as
    3106                 :             :  * [`poll()`](man:poll(2)) but it
    3107                 :             :  * may not always be possible to do this.
    3108                 :             :  *
    3109                 :             :  * Another version of this function exists.
    3110                 :             :  * [func@GLib.get_monotonic_time] returns the time in microseconds.
    3111                 :             :  * If you want to support older GLib versions, it is an alternative.
    3112                 :             :  *
    3113                 :             :  * Returns: the monotonic time, in nanoseconds
    3114                 :             :  * Since: 2.88
    3115                 :             :  **/
    3116                 :             : #if defined (G_OS_WIN32)
    3117                 :             : /* NOTE:
    3118                 :             :  * time_usec = ticks_since_boot * nsec_per_sec / ticks_per_sec
    3119                 :             :  *
    3120                 :             :  * Doing (ticks_since_boot * nsec_per_sec) before the division can overflow 64 bits
    3121                 :             :  * (ticks_since_boot  / ticks_per_sec) and then multiply would not be accurate enough.
    3122                 :             :  * So for now we calculate (nsec_per_sec / ticks_per_sec) and use floating point
    3123                 :             :  */
    3124                 :             : static double g_monotonic_nsec_per_tick = 0;
    3125                 :             : 
    3126                 :             : void
    3127                 :        1216 : g_clock_win32_init (void)
    3128                 :             : {
    3129                 :             :   LARGE_INTEGER freq;
    3130                 :             : 
    3131                 :        1216 :   if (!QueryPerformanceFrequency (&freq) || freq.QuadPart == 0)
    3132                 :             :     {
    3133                 :             :       /* The documentation says that this should never happen */
    3134                 :             :       g_assert_not_reached ();
    3135                 :           0 :       return;
    3136                 :             :     }
    3137                 :             : 
    3138                 :        1216 :   g_monotonic_nsec_per_tick = (double) G_NSEC_PER_SEC / freq.QuadPart;
    3139                 :        1216 : }
    3140                 :             : 
    3141                 :             : uint64_t
    3142                 :      284014 : g_get_monotonic_time_ns (void)
    3143                 :             : {
    3144                 :      284014 :   if (G_LIKELY (g_monotonic_nsec_per_tick != 0))
    3145                 :             :     {
    3146                 :             :       LARGE_INTEGER ticks;
    3147                 :             : 
    3148                 :      284014 :       if (QueryPerformanceCounter (&ticks))
    3149                 :      284014 :         return (uint64_t) (ticks.QuadPart * g_monotonic_nsec_per_tick);
    3150                 :             : 
    3151                 :           0 :       g_warning ("QueryPerformanceCounter Failed (%lu)", GetLastError ());
    3152                 :           0 :       g_monotonic_nsec_per_tick = 0;
    3153                 :           0 :     }
    3154                 :             : 
    3155                 :           0 :   return 0;
    3156                 :      284014 : }
    3157                 :             : #elif defined(HAVE_MACH_MACH_TIME_H) /* Mac OS */
    3158                 :             : uint64_t
    3159                 :             : g_get_monotonic_time_ns (void)
    3160                 :             : {
    3161                 :             :   mach_timebase_info_data_t timebase_info;
    3162                 :             :   uint64_t val;
    3163                 :             : 
    3164                 :             :   /* we get nanoseconds from mach_absolute_time() using timebase_info */
    3165                 :             :   mach_timebase_info (&timebase_info);
    3166                 :             :   val = mach_absolute_time ();
    3167                 :             : 
    3168                 :             :   if (timebase_info.numer != timebase_info.denom)
    3169                 :             :     {
    3170                 :             : #ifdef HAVE_UINT128_T
    3171                 :             :       val = ((__uint128_t) val * (__uint128_t) timebase_info.numer) / timebase_info.denom;
    3172                 :             : #else
    3173                 :             :       uint64_t t_high, t_low;
    3174                 :             :       uint64_t result_high, result_low;
    3175                 :             : 
    3176                 :             :       /* 64 bit x 32 bit / 32 bit with 96-bit intermediate 
    3177                 :             :        * algorithm lifted from qemu */
    3178                 :             :       t_low = (val & 0xffffffffLL) * (uint64_t) timebase_info.numer;
    3179                 :             :       t_high = (val >> 32) * (uint64_t) timebase_info.numer;
    3180                 :             :       t_high += (t_low >> 32);
    3181                 :             :       result_high = t_high / (uint64_t) timebase_info.denom;
    3182                 :             :       result_low = (((t_high % (uint64_t) timebase_info.denom) << 32) +
    3183                 :             :                     (t_low & 0xffffffff)) /
    3184                 :             :                    (uint64_t) timebase_info.denom;
    3185                 :             :       val = ((result_high << 32) | result_low);
    3186                 :             : #endif
    3187                 :             :     }
    3188                 :             : 
    3189                 :             :   return val;
    3190                 :             : }
    3191                 :             : #else
    3192                 :             : uint64_t
    3193                 :    16336354 : g_get_monotonic_time_ns (void)
    3194                 :             : {
    3195                 :             :   struct timespec ts;
    3196                 :             :   int result;
    3197                 :             : 
    3198                 :    16336354 :   result = clock_gettime (CLOCK_MONOTONIC, &ts);
    3199                 :             : 
    3200                 :    16336354 :   if G_UNLIKELY (result != 0)
    3201                 :           0 :     g_error ("GLib requires working CLOCK_MONOTONIC");
    3202                 :             : 
    3203                 :    16336354 :   return (((uint64_t) ts.tv_sec) * G_NSEC_PER_SEC) + ts.tv_nsec;
    3204                 :             : }
    3205                 :             : #endif
    3206                 :             : 
    3207                 :             : gint64
    3208                 :    11411839 : g_get_monotonic_time (void)
    3209                 :             : {
    3210                 :    11411839 :   return g_get_monotonic_time_ns () / 1000;
    3211                 :             : }
    3212                 :             : 
    3213                 :             : static void
    3214                 :        1217 : g_main_dispatch_free (gpointer dispatch)
    3215                 :             : {
    3216                 :        1217 :   g_free (dispatch);
    3217                 :        1217 : }
    3218                 :             : 
    3219                 :             : /* Running the main loop */
    3220                 :             : 
    3221                 :             : static GMainDispatch *
    3222                 :     1189717 : get_dispatch (void)
    3223                 :             : {
    3224                 :             :   static GPrivate depth_private = G_PRIVATE_INIT (g_main_dispatch_free);
    3225                 :             :   GMainDispatch *dispatch;
    3226                 :             : 
    3227                 :     1189717 :   dispatch = g_private_get (&depth_private);
    3228                 :             : 
    3229                 :     1189717 :   if (!dispatch)
    3230                 :        1885 :     dispatch = g_private_set_alloc0 (&depth_private, sizeof (GMainDispatch));
    3231                 :             : 
    3232                 :     1189717 :   return dispatch;
    3233                 :             : }
    3234                 :             : 
    3235                 :             : /**
    3236                 :             :  * g_main_depth:
    3237                 :             :  *
    3238                 :             :  * Returns the depth of the stack of calls to
    3239                 :             :  * [method@GLib.MainContext.dispatch] on any #GMainContext in the current thread.
    3240                 :             :  *
    3241                 :             :  * That is, when called from the top level, it gives `0`. When
    3242                 :             :  * called from within a callback from [method@GLib.MainContext.iteration]
    3243                 :             :  * (or [method@GLib.MainLoop.run], etc.) it returns `1`. When called from within
    3244                 :             :  * a callback to a recursive call to [method@GLib.MainContext.iteration],
    3245                 :             :  * it returns `2`. And so forth.
    3246                 :             :  *
    3247                 :             :  * This function is useful in a situation like the following:
    3248                 :             :  * Imagine an extremely simple ‘garbage collected’ system.
    3249                 :             :  *
    3250                 :             :  * ```c
    3251                 :             :  * static GList *free_list;
    3252                 :             :  * 
    3253                 :             :  * gpointer
    3254                 :             :  * allocate_memory (gsize size)
    3255                 :             :  * { 
    3256                 :             :  *   gpointer result = g_malloc (size);
    3257                 :             :  *   free_list = g_list_prepend (free_list, result);
    3258                 :             :  *   return result;
    3259                 :             :  * }
    3260                 :             :  * 
    3261                 :             :  * void
    3262                 :             :  * free_allocated_memory (void)
    3263                 :             :  * {
    3264                 :             :  *   GList *l;
    3265                 :             :  *   for (l = free_list; l; l = l->next);
    3266                 :             :  *     g_free (l->data);
    3267                 :             :  *   g_list_free (free_list);
    3268                 :             :  *   free_list = NULL;
    3269                 :             :  *  }
    3270                 :             :  * 
    3271                 :             :  * [...]
    3272                 :             :  * 
    3273                 :             :  * while (TRUE); 
    3274                 :             :  *  {
    3275                 :             :  *    g_main_context_iteration (NULL, TRUE);
    3276                 :             :  *    free_allocated_memory();
    3277                 :             :  *   }
    3278                 :             :  * ```
    3279                 :             :  *
    3280                 :             :  * This works from an application, however, if you want to do the same
    3281                 :             :  * thing from a library, it gets more difficult, since you no longer
    3282                 :             :  * control the main loop. You might think you can simply use an idle
    3283                 :             :  * function to make the call to `free_allocated_memory()`, but that
    3284                 :             :  * doesn’t work, since the idle function could be called from a
    3285                 :             :  * recursive callback. This can be fixed by using [func@GLib.main_depth]
    3286                 :             :  *
    3287                 :             :  * ```c
    3288                 :             :  * gpointer
    3289                 :             :  * allocate_memory (gsize size)
    3290                 :             :  * { 
    3291                 :             :  *   FreeListBlock *block = g_new (FreeListBlock, 1);
    3292                 :             :  *   block->mem = g_malloc (size);
    3293                 :             :  *   block->depth = g_main_depth ();   
    3294                 :             :  *   free_list = g_list_prepend (free_list, block);
    3295                 :             :  *   return block->mem;
    3296                 :             :  * }
    3297                 :             :  * 
    3298                 :             :  * void
    3299                 :             :  * free_allocated_memory (void)
    3300                 :             :  * {
    3301                 :             :  *   GList *l;
    3302                 :             :  *   
    3303                 :             :  *   int depth = g_main_depth ();
    3304                 :             :  *   for (l = free_list; l; );
    3305                 :             :  *     {
    3306                 :             :  *       GList *next = l->next;
    3307                 :             :  *       FreeListBlock *block = l->data;
    3308                 :             :  *       if (block->depth > depth)
    3309                 :             :  *         {
    3310                 :             :  *           g_free (block->mem);
    3311                 :             :  *           g_free (block);
    3312                 :             :  *           free_list = g_list_delete_link (free_list, l);
    3313                 :             :  *         }
    3314                 :             :  *               
    3315                 :             :  *       l = next;
    3316                 :             :  *     }
    3317                 :             :  *   }
    3318                 :             :  * ```
    3319                 :             :  *
    3320                 :             :  * There is a temptation to use [func@GLib.main_depth] to solve
    3321                 :             :  * problems with reentrancy. For instance, while waiting for data
    3322                 :             :  * to be received from the network in response to a menu item,
    3323                 :             :  * the menu item might be selected again. It might seem that
    3324                 :             :  * one could make the menu item’s callback return immediately
    3325                 :             :  * and do nothing if [func@GLib.main_depth] returns a value greater than 1.
    3326                 :             :  * However, this should be avoided since the user then sees selecting
    3327                 :             :  * the menu item do nothing. Furthermore, you’ll find yourself adding
    3328                 :             :  * these checks all over your code, since there are doubtless many,
    3329                 :             :  * many things that the user could do. Instead, you can use the
    3330                 :             :  * following techniques:
    3331                 :             :  *
    3332                 :             :  * 1. Use `gtk_widget_set_sensitive()` or modal dialogs to prevent
    3333                 :             :  *    the user from interacting with elements while the main
    3334                 :             :  *    loop is recursing.
    3335                 :             :  * 
    3336                 :             :  * 2. Avoid main loop recursion in situations where you can’t handle
    3337                 :             :  *    arbitrary  callbacks. Instead, structure your code so that you
    3338                 :             :  *    simply return to the main loop and then get called again when
    3339                 :             :  *    there is more work to do.
    3340                 :             :  * 
    3341                 :             :  * Returns: the main loop recursion level in the current thread
    3342                 :             :  */
    3343                 :             : int
    3344                 :           2 : g_main_depth (void)
    3345                 :             : {
    3346                 :           2 :   GMainDispatch *dispatch = get_dispatch ();
    3347                 :           2 :   return dispatch->depth;
    3348                 :             : }
    3349                 :             : 
    3350                 :             : /**
    3351                 :             :  * g_main_current_source:
    3352                 :             :  *
    3353                 :             :  * Returns the currently firing source for this thread.
    3354                 :             :  * 
    3355                 :             :  * Returns: (transfer none) (nullable): the currently firing source, or `NULL`
    3356                 :             :  *   if none is firing
    3357                 :             :  * Since: 2.12
    3358                 :             :  */
    3359                 :             : GSource *
    3360                 :      286697 : g_main_current_source (void)
    3361                 :             : {
    3362                 :      286697 :   GMainDispatch *dispatch = get_dispatch ();
    3363                 :      286697 :   return dispatch->source;
    3364                 :             : }
    3365                 :             : 
    3366                 :             : /**
    3367                 :             :  * g_source_is_destroyed:
    3368                 :             :  * @source: a source
    3369                 :             :  *
    3370                 :             :  * Returns whether @source has been destroyed.
    3371                 :             :  *
    3372                 :             :  * This is important when you operate upon your objects 
    3373                 :             :  * from within idle handlers, but may have freed the object 
    3374                 :             :  * before the dispatch of your idle handler.
    3375                 :             :  *
    3376                 :             :  * ```c
    3377                 :             :  * static gboolean 
    3378                 :             :  * idle_callback (gpointer data)
    3379                 :             :  * {
    3380                 :             :  *   SomeWidget *self = data;
    3381                 :             :  *    
    3382                 :             :  *   g_mutex_lock (&self->idle_id_mutex);
    3383                 :             :  *   // do stuff with self
    3384                 :             :  *   self->idle_id = 0;
    3385                 :             :  *   g_mutex_unlock (&self->idle_id_mutex);
    3386                 :             :  *    
    3387                 :             :  *   return G_SOURCE_REMOVE;
    3388                 :             :  * }
    3389                 :             :  *  
    3390                 :             :  * static void 
    3391                 :             :  * some_widget_do_stuff_later (SomeWidget *self)
    3392                 :             :  * {
    3393                 :             :  *   g_mutex_lock (&self->idle_id_mutex);
    3394                 :             :  *   self->idle_id = g_idle_add (idle_callback, self);
    3395                 :             :  *   g_mutex_unlock (&self->idle_id_mutex);
    3396                 :             :  * }
    3397                 :             :  *  
    3398                 :             :  * static void
    3399                 :             :  * some_widget_init (SomeWidget *self)
    3400                 :             :  * {
    3401                 :             :  *   g_mutex_init (&self->idle_id_mutex);
    3402                 :             :  *
    3403                 :             :  *   // ...
    3404                 :             :  * }
    3405                 :             :  *
    3406                 :             :  * static void 
    3407                 :             :  * some_widget_finalize (GObject *object)
    3408                 :             :  * {
    3409                 :             :  *   SomeWidget *self = SOME_WIDGET (object);
    3410                 :             :  *    
    3411                 :             :  *   if (self->idle_id)
    3412                 :             :  *     g_source_remove (self->idle_id);
    3413                 :             :  *    
    3414                 :             :  *   g_mutex_clear (&self->idle_id_mutex);
    3415                 :             :  *
    3416                 :             :  *   G_OBJECT_CLASS (parent_class)->finalize (object);
    3417                 :             :  * }
    3418                 :             :  * ```
    3419                 :             :  *
    3420                 :             :  * This will fail in a multi-threaded application if the 
    3421                 :             :  * widget is destroyed before the idle handler fires due 
    3422                 :             :  * to the use after free in the callback. A solution, to 
    3423                 :             :  * this particular problem, is to check to if the source
    3424                 :             :  * has already been destroy within the callback.
    3425                 :             :  *
    3426                 :             :  * ```c
    3427                 :             :  * static gboolean 
    3428                 :             :  * idle_callback (gpointer data)
    3429                 :             :  * {
    3430                 :             :  *   SomeWidget *self = data;
    3431                 :             :  *   
    3432                 :             :  *   g_mutex_lock (&self->idle_id_mutex);
    3433                 :             :  *   if (!g_source_is_destroyed (g_main_current_source ()))
    3434                 :             :  *     {
    3435                 :             :  *       // do stuff with self
    3436                 :             :  *     }
    3437                 :             :  *   g_mutex_unlock (&self->idle_id_mutex);
    3438                 :             :  *   
    3439                 :             :  *   return FALSE;
    3440                 :             :  * }
    3441                 :             :  * ```
    3442                 :             :  *
    3443                 :             :  * Calls to this function from a thread other than the one acquired by the
    3444                 :             :  * [struct@GLib.MainContext] the [struct@GLib.Source] is attached to are typically
    3445                 :             :  * redundant, as the source could be destroyed immediately after this function
    3446                 :             :  * returns. However, once a source is destroyed it cannot be un-destroyed, so
    3447                 :             :  * this function can be used for opportunistic checks from any thread.
    3448                 :             :  *
    3449                 :             :  * Returns: true if the source has been destroyed, false otherwise
    3450                 :             :  * Since: 2.12
    3451                 :             :  */
    3452                 :             : gboolean
    3453                 :        1710 : g_source_is_destroyed (GSource *source)
    3454                 :             : {
    3455                 :        1710 :   g_return_val_if_fail (source != NULL, TRUE);
    3456                 :        1710 :   g_return_val_if_fail (g_atomic_int_get (&source->ref_count) > 0, TRUE);
    3457                 :        1710 :   return SOURCE_DESTROYED (source);
    3458                 :          76 : }
    3459                 :             : 
    3460                 :             : /* Temporarily remove all this source's file descriptors from the
    3461                 :             :  * poll(), so that if data comes available for one of the file descriptors
    3462                 :             :  * we don't continually spin in the poll()
    3463                 :             :  */
    3464                 :             : /* HOLDS: source->context's lock */
    3465                 :             : static void
    3466                 :      950085 : block_source (GSource      *source,
    3467                 :             :               GMainContext *context)
    3468                 :             : {
    3469                 :             :   GSList *tmp_list;
    3470                 :             : 
    3471                 :      950085 :   g_return_if_fail (!SOURCE_BLOCKED (source));
    3472                 :             : 
    3473                 :      950085 :   g_atomic_int_or (&source->flags, G_SOURCE_BLOCKED);
    3474                 :             : 
    3475                 :      950085 :   if (context)
    3476                 :             :     {
    3477                 :      950080 :       tmp_list = source->poll_fds;
    3478                 :      954145 :       while (tmp_list)
    3479                 :             :         {
    3480                 :        4065 :           g_main_context_remove_poll_unlocked (context, tmp_list->data);
    3481                 :        4065 :           tmp_list = tmp_list->next;
    3482                 :             :         }
    3483                 :             : 
    3484                 :     1228103 :       for (tmp_list = source->priv->fds; tmp_list; tmp_list = tmp_list->next)
    3485                 :      278023 :         g_main_context_remove_poll_unlocked (context, tmp_list->data);
    3486                 :      244494 :     }
    3487                 :             : 
    3488                 :      950085 :   if (source->priv && source->priv->child_sources)
    3489                 :             :     {
    3490                 :       15169 :       tmp_list = source->priv->child_sources;
    3491                 :       30904 :       while (tmp_list)
    3492                 :             :         {
    3493                 :       15735 :           block_source (tmp_list->data, context);
    3494                 :       15735 :           tmp_list = tmp_list->next;
    3495                 :             :         }
    3496                 :         176 :     }
    3497                 :      244497 : }
    3498                 :             : 
    3499                 :             : /* HOLDS: source->context's lock */
    3500                 :             : static void
    3501                 :      948969 : unblock_source (GSource      *source,
    3502                 :             :                 GMainContext *context)
    3503                 :             : {
    3504                 :             :   GSList *tmp_list;
    3505                 :             : 
    3506                 :      948969 :   g_return_if_fail (SOURCE_BLOCKED (source)); /* Source already unblocked */
    3507                 :      948969 :   g_return_if_fail (!SOURCE_DESTROYED (source));
    3508                 :             : 
    3509                 :      948969 :   g_atomic_int_and (&source->flags, ~G_SOURCE_BLOCKED);
    3510                 :             : 
    3511                 :      948969 :   tmp_list = source->poll_fds;
    3512                 :      952990 :   while (tmp_list)
    3513                 :             :     {
    3514                 :        4021 :       g_main_context_add_poll_unlocked (context, source->priority, tmp_list->data);
    3515                 :        4021 :       tmp_list = tmp_list->next;
    3516                 :             :     }
    3517                 :             : 
    3518                 :     1226695 :   for (tmp_list = source->priv->fds; tmp_list; tmp_list = tmp_list->next)
    3519                 :      277726 :     g_main_context_add_poll_unlocked (context, source->priority, tmp_list->data);
    3520                 :             : 
    3521                 :      948969 :   if (source->priv && source->priv->child_sources)
    3522                 :             :     {
    3523                 :       14882 :       tmp_list = source->priv->child_sources;
    3524                 :       30330 :       while (tmp_list)
    3525                 :             :         {
    3526                 :       15448 :           unblock_source (tmp_list->data, context);
    3527                 :       15448 :           tmp_list = tmp_list->next;
    3528                 :             :         }
    3529                 :         141 :     }
    3530                 :      244364 : }
    3531                 :             : 
    3532                 :             : /* HOLDS: context's lock */
    3533                 :             : static void
    3534                 :      903017 : g_main_dispatch (GMainContext *context)
    3535                 :             : {
    3536                 :      903017 :   GMainDispatch *current = get_dispatch ();
    3537                 :             :   guint i;
    3538                 :             : 
    3539                 :     1837380 :   for (i = 0; i < context->pending_dispatches->len; i++)
    3540                 :             :     {
    3541                 :      934377 :       GSource *source = context->pending_dispatches->pdata[i];
    3542                 :             : 
    3543                 :      934377 :       context->pending_dispatches->pdata[i] = NULL;
    3544                 :      934377 :       g_assert (source);
    3545                 :             : 
    3546                 :      934377 :       g_atomic_int_and (&source->flags, ~G_SOURCE_READY);
    3547                 :             : 
    3548                 :      934377 :       if (!SOURCE_DESTROYED (source))
    3549                 :             :         {
    3550                 :             :           gboolean was_in_call;
    3551                 :      934350 :           gpointer user_data = NULL;
    3552                 :      934350 :           GSourceFunc callback = NULL;
    3553                 :             :           GSourceCallbackFuncs *cb_funcs;
    3554                 :             :           gpointer cb_data;
    3555                 :             :           gboolean need_destroy;
    3556                 :             : 
    3557                 :             :           gboolean (*dispatch) (GSource *,
    3558                 :             :                                 GSourceFunc,
    3559                 :             :                                 gpointer);
    3560                 :             :           GSource *prev_source;
    3561                 :             :           gint64 begin_time_nsec G_GNUC_UNUSED;
    3562                 :             : 
    3563                 :      934350 :           dispatch = source->source_funcs->dispatch;
    3564                 :      934350 :           cb_funcs = source->callback_funcs;
    3565                 :      934350 :           cb_data = source->callback_data;
    3566                 :             : 
    3567                 :      934350 :           if (cb_funcs)
    3568                 :      893059 :             cb_funcs->ref (cb_data);
    3569                 :             :           
    3570                 :      934350 :           if ((g_atomic_int_get (&source->flags) & G_SOURCE_CAN_RECURSE) == 0)
    3571                 :      934346 :             block_source (source, context);
    3572                 :             :           
    3573                 :     1178667 :           was_in_call = g_atomic_int_or (&source->flags,
    3574                 :      934350 :                                          (GSourceFlags) G_HOOK_FLAG_IN_CALL) &
    3575                 :             :                                          G_HOOK_FLAG_IN_CALL;
    3576                 :             : 
    3577                 :      934350 :           if (cb_funcs)
    3578                 :      893059 :             cb_funcs->get (cb_data, source, &callback, &user_data);
    3579                 :             : 
    3580                 :      934342 :           UNLOCK_CONTEXT (context);
    3581                 :             : 
    3582                 :             :           /* These operations are safe because 'current' is thread-local
    3583                 :             :            * and not modified from anywhere but this function.
    3584                 :             :            */
    3585                 :      934342 :           prev_source = current->source;
    3586                 :      934342 :           current->source = source;
    3587                 :      934342 :           current->depth++;
    3588                 :             : 
    3589                 :      934342 :           begin_time_nsec = G_TRACE_CURRENT_TIME;
    3590                 :             : 
    3591                 :      690033 :           TRACE (GLIB_MAIN_BEFORE_DISPATCH (g_source_get_name (source), source,
    3592                 :             :                                             dispatch, callback, user_data));
    3593                 :      934342 :           need_destroy = !(* dispatch) (source, callback, user_data);
    3594                 :      690027 :           TRACE (GLIB_MAIN_AFTER_DISPATCH (g_source_get_name (source), source,
    3595                 :             :                                            dispatch, need_destroy));
    3596                 :             : 
    3597                 :     1806371 :           g_trace_mark (begin_time_nsec, G_TRACE_CURRENT_TIME - begin_time_nsec,
    3598                 :             :                         "GLib", "GSource.dispatch",
    3599                 :             :                         "%s ⇒ %s",
    3600                 :     1116344 :                         (g_source_get_name (source) != NULL) ? g_source_get_name (source) : "(unnamed)",
    3601                 :             :                         need_destroy ? "destroy" : "keep");
    3602                 :             : 
    3603                 :      934336 :           current->source = prev_source;
    3604                 :      934336 :           current->depth--;
    3605                 :             : 
    3606                 :      934336 :           if (cb_funcs)
    3607                 :      893049 :             cb_funcs->unref (cb_data);
    3608                 :             : 
    3609                 :      934336 :           LOCK_CONTEXT (context);
    3610                 :             :           
    3611                 :      934336 :           if (!was_in_call)
    3612                 :      934336 :             g_atomic_int_and (&source->flags, ~G_HOOK_FLAG_IN_CALL);
    3613                 :             : 
    3614                 :      934336 :           if (SOURCE_BLOCKED (source) && !SOURCE_DESTROYED (source))
    3615                 :      933521 :             unblock_source (source, context);
    3616                 :             :           
    3617                 :             :           /* Note: this depends on the fact that we can't switch
    3618                 :             :            * sources from one main context to another
    3619                 :             :            */
    3620                 :      934336 :           if (need_destroy && !SOURCE_DESTROYED (source))
    3621                 :             :             {
    3622                 :      364211 :               g_assert (source->context == context);
    3623                 :      364211 :               g_source_destroy_internal (source, context, TRUE);
    3624                 :        4998 :             }
    3625                 :      244309 :         }
    3626                 :             :       
    3627                 :      934363 :       g_source_unref_internal (source, context, TRUE);
    3628                 :      244320 :     }
    3629                 :             : 
    3630                 :      903003 :   g_ptr_array_set_size (context->pending_dispatches, 0);
    3631                 :      903003 : }
    3632                 :             : 
    3633                 :             : /**
    3634                 :             :  * g_main_context_acquire:
    3635                 :             :  * @context: (nullable): a main context (if `NULL`, the global-default
    3636                 :             :  *   main context will be used)
    3637                 :             :  * 
    3638                 :             :  * Tries to become the owner of the specified context.
    3639                 :             :  *
    3640                 :             :  * If some other thread is the owner of the context,
    3641                 :             :  * returns false immediately. Ownership is properly
    3642                 :             :  * recursive: the owner can require ownership again
    3643                 :             :  * and will release ownership when [method@GLib.MainContext.release]
    3644                 :             :  * is called as many times as [method@GLib.MainContext.acquire].
    3645                 :             :  *
    3646                 :             :  * You must be the owner of a context before you
    3647                 :             :  * can call [method@GLib.MainContext.prepare], [method@GLib.MainContext.query],
    3648                 :             :  * [method@GLib.MainContext.check], [method@GLib.MainContext.dispatch],
    3649                 :             :  * [method@GLib.MainContext.release].
    3650                 :             :  *
    3651                 :             :  * Since 2.76 @context can be `NULL` to use the global-default
    3652                 :             :  * main context.
    3653                 :             :  * 
    3654                 :             :  * Returns: true if this thread is now the owner of @context, false otherwise
    3655                 :             :  **/
    3656                 :             : gboolean 
    3657                 :      149244 : g_main_context_acquire (GMainContext *context)
    3658                 :             : {
    3659                 :      149244 :   gboolean result = FALSE;
    3660                 :             : 
    3661                 :      149244 :   if (context == NULL)
    3662                 :           4 :     context = g_main_context_default ();
    3663                 :             :   
    3664                 :      149244 :   LOCK_CONTEXT (context);
    3665                 :             : 
    3666                 :      149244 :   result = g_main_context_acquire_unlocked (context);
    3667                 :             : 
    3668                 :      149244 :   UNLOCK_CONTEXT (context); 
    3669                 :             : 
    3670                 :      149244 :   return result;
    3671                 :             : }
    3672                 :             : 
    3673                 :             : static gboolean
    3674                 :     1288198 : g_main_context_acquire_unlocked (GMainContext *context)
    3675                 :             : {
    3676                 :     1288198 :   GThread *self = G_THREAD_SELF;
    3677                 :             : 
    3678                 :     1288198 :   if (!context->owner)
    3679                 :             :     {
    3680                 :      455247 :       context->owner = self;
    3681                 :      455247 :       g_assert (context->owner_count == 0);
    3682                 :      453053 :       TRACE (GLIB_MAIN_CONTEXT_ACQUIRE (context, TRUE  /* success */));
    3683                 :        2194 :     }
    3684                 :             : 
    3685                 :     1288198 :   if (context->owner == self)
    3686                 :             :     {
    3687                 :     1260297 :       context->owner_count++;
    3688                 :     1260297 :       return TRUE;
    3689                 :             :     }
    3690                 :             :   else
    3691                 :             :     {
    3692                 :       27889 :       TRACE (GLIB_MAIN_CONTEXT_ACQUIRE (context, FALSE  /* failure */));
    3693                 :       27901 :       return FALSE;
    3694                 :             :     }
    3695                 :      253151 : }
    3696                 :             : 
    3697                 :             : /**
    3698                 :             :  * g_main_context_release:
    3699                 :             :  * @context: (nullable): a main context (if `NULL`, the global-default
    3700                 :             :  *   main context will be used)
    3701                 :             :  * 
    3702                 :             :  * Releases ownership of a context previously acquired by this thread
    3703                 :             :  * with [method@GLib.MainContext.acquire].
    3704                 :             :  *
    3705                 :             :  * If the context was acquired multiple
    3706                 :             :  * times, the ownership will be released only when [method@GLib.MainContext.release]
    3707                 :             :  * is called as many times as it was acquired.
    3708                 :             :  *
    3709                 :             :  * You must have successfully acquired the context with
    3710                 :             :  * [method@GLib.MainContext.acquire] before you may call this function.
    3711                 :             :  **/
    3712                 :             : void
    3713                 :      149104 : g_main_context_release (GMainContext *context)
    3714                 :             : {
    3715                 :      149104 :   if (context == NULL)
    3716                 :       43207 :     context = g_main_context_default ();
    3717                 :             : 
    3718                 :      149104 :   LOCK_CONTEXT (context);
    3719                 :      149104 :   g_main_context_release_unlocked (context);
    3720                 :      149104 :   UNLOCK_CONTEXT (context);
    3721                 :      149104 : }
    3722                 :             : 
    3723                 :             : static void
    3724                 :     1259698 : g_main_context_release_unlocked (GMainContext *context)
    3725                 :             : {
    3726                 :             :   /* NOTE: We should also have the following assert here:
    3727                 :             :    * g_return_if_fail (context->owner == G_THREAD_SELF);
    3728                 :             :    * However, this breaks NetworkManager, which has been (non-compliantly but
    3729                 :             :    * apparently safely) releasing a #GMainContext from a thread which didn’t
    3730                 :             :    * acquire it.
    3731                 :             :    * Breaking that would be quite disruptive, so we won’t do that now. However,
    3732                 :             :    * GLib reserves the right to add that assertion in future, if doing so would
    3733                 :             :    * allow for optimisations or refactorings. By that point, NetworkManager will
    3734                 :             :    * have to have reworked its use of #GMainContext.
    3735                 :             :    *
    3736                 :             :    * See: https://gitlab.gnome.org/GNOME/glib/-/merge_requests/3513
    3737                 :             :    */
    3738                 :     1259698 :   g_return_if_fail (context->owner_count > 0);
    3739                 :             : 
    3740                 :     1259698 :   context->owner_count--;
    3741                 :     1259698 :   if (context->owner_count == 0)
    3742                 :             :     {
    3743                 :      452710 :       TRACE (GLIB_MAIN_CONTEXT_RELEASE (context));
    3744                 :             : 
    3745                 :      454863 :       context->owner = NULL;
    3746                 :             : 
    3747                 :      454863 :       if (context->waiters)
    3748                 :             :         {
    3749                 :           1 :           GMainWaiter *waiter = context->waiters->data;
    3750                 :           1 :           gboolean loop_internal_waiter = (waiter->mutex == &context->mutex);
    3751                 :           1 :           context->waiters = g_slist_delete_link (context->waiters,
    3752                 :           0 :                                                   context->waiters);
    3753                 :           1 :           if (!loop_internal_waiter)
    3754                 :           0 :             g_mutex_lock (waiter->mutex);
    3755                 :             :           
    3756                 :           1 :           g_cond_signal (waiter->cond);
    3757                 :             :           
    3758                 :           1 :           if (!loop_internal_waiter)
    3759                 :           0 :             g_mutex_unlock (waiter->mutex);
    3760                 :           0 :         }
    3761                 :        2153 :     }
    3762                 :      253089 : }
    3763                 :             : 
    3764                 :             : static gboolean
    3765                 :           1 : g_main_context_wait_internal (GMainContext *context,
    3766                 :             :                               GCond        *cond,
    3767                 :             :                               GMutex       *mutex)
    3768                 :             : {
    3769                 :           1 :   gboolean result = FALSE;
    3770                 :           1 :   GThread *self = G_THREAD_SELF;
    3771                 :             :   gboolean loop_internal_waiter;
    3772                 :             :   
    3773                 :           1 :   loop_internal_waiter = (mutex == &context->mutex);
    3774                 :             :   
    3775                 :           1 :   if (!loop_internal_waiter)
    3776                 :           0 :     LOCK_CONTEXT (context);
    3777                 :             : 
    3778                 :           1 :   if (context->owner && context->owner != self)
    3779                 :             :     {
    3780                 :             :       GMainWaiter waiter;
    3781                 :             : 
    3782                 :           1 :       waiter.cond = cond;
    3783                 :           1 :       waiter.mutex = mutex;
    3784                 :             : 
    3785                 :           1 :       context->waiters = g_slist_append (context->waiters, &waiter);
    3786                 :             :       
    3787                 :           1 :       if (!loop_internal_waiter)
    3788                 :           0 :         UNLOCK_CONTEXT (context);
    3789                 :           1 :       g_cond_wait (cond, mutex);
    3790                 :           1 :       if (!loop_internal_waiter)
    3791                 :           0 :         LOCK_CONTEXT (context);
    3792                 :             : 
    3793                 :           1 :       context->waiters = g_slist_remove (context->waiters, &waiter);
    3794                 :           0 :     }
    3795                 :             : 
    3796                 :           1 :   if (!context->owner)
    3797                 :             :     {
    3798                 :           1 :       context->owner = self;
    3799                 :           1 :       g_assert (context->owner_count == 0);
    3800                 :           0 :     }
    3801                 :             : 
    3802                 :           1 :   if (context->owner == self)
    3803                 :             :     {
    3804                 :           1 :       context->owner_count++;
    3805                 :           1 :       result = TRUE;
    3806                 :           0 :     }
    3807                 :             : 
    3808                 :           1 :   if (!loop_internal_waiter)
    3809                 :           0 :     UNLOCK_CONTEXT (context); 
    3810                 :             :   
    3811                 :           1 :   return result;
    3812                 :             : }
    3813                 :             : 
    3814                 :             : /**
    3815                 :             :  * g_main_context_wait:
    3816                 :             :  * @context: (nullable): a main context (if `NULL`, the global-default
    3817                 :             :  *   main context will be used)
    3818                 :             :  * @cond: a condition variable
    3819                 :             :  * @mutex: a mutex, currently held
    3820                 :             :  *
    3821                 :             :  * Tries to become the owner of the specified context, and waits on @cond if
    3822                 :             :  * another thread is the owner.
    3823                 :             :  *
    3824                 :             :  * This is the same as [method@GLib.MainContext.acquire], but if another thread
    3825                 :             :  * is the owner, atomically drop @mutex and wait on @cond until
    3826                 :             :  * that owner releases ownership or until @cond is signaled, then
    3827                 :             :  * try again (once) to become the owner.
    3828                 :             :  *
    3829                 :             :  * Returns: true if this thread is now the owner of @context, false otherwise
    3830                 :             :  * Deprecated: 2.58: Use [method@GLib.MainContext.is_owner] and separate
    3831                 :             :  *    locking instead.
    3832                 :             :  */
    3833                 :             : gboolean
    3834                 :           0 : g_main_context_wait (GMainContext *context,
    3835                 :             :                      GCond        *cond,
    3836                 :             :                      GMutex       *mutex)
    3837                 :             : {
    3838                 :           0 :   if (context == NULL)
    3839                 :           0 :     context = g_main_context_default ();
    3840                 :             : 
    3841                 :           0 :   if (G_UNLIKELY (cond != &context->cond || mutex != &context->mutex))
    3842                 :             :     {
    3843                 :             :       static gboolean warned;
    3844                 :             : 
    3845                 :           0 :       if (!warned)
    3846                 :             :         {
    3847                 :           0 :           g_critical ("WARNING!! g_main_context_wait() will be removed in a future release.  "
    3848                 :             :                       "If you see this message, please file a bug immediately.");
    3849                 :           0 :           warned = TRUE;
    3850                 :           0 :         }
    3851                 :           0 :     }
    3852                 :             : 
    3853                 :           0 :   return g_main_context_wait_internal (context, cond, mutex);
    3854                 :             : }
    3855                 :             : 
    3856                 :             : /**
    3857                 :             :  * g_main_context_prepare:
    3858                 :             :  * @context: (nullable): a main context (if `NULL`, the global-default
    3859                 :             :  *   main context will be used)
    3860                 :             :  * @priority: (out) (optional): location to store priority of highest priority
    3861                 :             :  *   source already ready
    3862                 :             :  *
    3863                 :             :  * Prepares to poll sources within a main loop.
    3864                 :             :  *
    3865                 :             :  * The resulting information
    3866                 :             :  * for polling is determined by calling [method@GLib.MainContext.query].
    3867                 :             :  *
    3868                 :             :  * You must have successfully acquired the context with
    3869                 :             :  * [method@GLib.MainContext.acquire] before you may call this function.
    3870                 :             :  *
    3871                 :             :  * Returns: true if some source is ready to be dispatched prior to polling,
    3872                 :             :  *   false otherwise
    3873                 :             :  **/
    3874                 :             : gboolean
    3875                 :          24 : g_main_context_prepare (GMainContext *context,
    3876                 :             :                         gint         *priority)
    3877                 :             : {
    3878                 :             :   gboolean ready;
    3879                 :             : 
    3880                 :          24 :   if (context == NULL)
    3881                 :           2 :     context = g_main_context_default ();
    3882                 :             :   
    3883                 :          24 :   LOCK_CONTEXT (context);
    3884                 :             : 
    3885                 :          24 :   ready = g_main_context_prepare_unlocked (context, priority);
    3886                 :             : 
    3887                 :          24 :   UNLOCK_CONTEXT (context);
    3888                 :             :   
    3889                 :          24 :   return ready;
    3890                 :             : }
    3891                 :             : 
    3892                 :             : static inline int
    3893                 :      247205 : round_timeout_to_msec (gint64 timeout_usec)
    3894                 :             : {
    3895                 :             :   /* We need to round to milliseconds from our internal microseconds for
    3896                 :             :    * various external API and GPollFunc which requires milliseconds.
    3897                 :             :    *
    3898                 :             :    * However, we want to ensure a few invariants for this.
    3899                 :             :    *
    3900                 :             :    *   Return == -1 if we have no timeout specified
    3901                 :             :    *   Return ==  0 if we don't want to block at all
    3902                 :             :    *   Return  >  0 if we have any timeout to avoid spinning the CPU
    3903                 :             :    *
    3904                 :             :    * This does cause jitter if the microsecond timeout is < 1000 usec
    3905                 :             :    * because that is beyond our precision. However, using ppoll() instead
    3906                 :             :    * of poll() (when available) avoids this jitter.
    3907                 :             :    */
    3908                 :             : 
    3909                 :      247205 :   if (timeout_usec == 0)
    3910                 :      218878 :     return 0;
    3911                 :             : 
    3912                 :       28327 :   if (timeout_usec > 0)
    3913                 :             :     {
    3914                 :        3511 :       guint64 timeout_msec = (timeout_usec + 999) / 1000;
    3915                 :             : 
    3916                 :        3511 :       return (int) MIN (timeout_msec, G_MAXINT);
    3917                 :             :     }
    3918                 :             : 
    3919                 :       24816 :   return -1;
    3920                 :      247188 : }
    3921                 :             : 
    3922                 :             : static inline gint64
    3923                 :      726178 : extend_timeout_to_usec (int timeout_msec)
    3924                 :             : {
    3925                 :      726178 :   if (timeout_msec >= 0)
    3926                 :      589019 :     return (gint64) timeout_msec * 1000;
    3927                 :             : 
    3928                 :      137159 :   return -1;
    3929                 :      237478 : }
    3930                 :             : 
    3931                 :             : static gboolean
    3932                 :     1100255 : g_main_context_prepare_unlocked (GMainContext *context,
    3933                 :             :                                  gint         *priority)
    3934                 :             : {
    3935                 :             :   guint i;
    3936                 :     1100255 :   gint n_ready = 0;
    3937                 :     1100255 :   gint current_priority = G_MAXINT;
    3938                 :             :   GSource *source;
    3939                 :             :   GSourceIter iter;
    3940                 :             : 
    3941                 :     1100255 :   context->time_is_fresh = FALSE;
    3942                 :             : 
    3943                 :     1100255 :   if (context->in_check_or_prepare)
    3944                 :             :     {
    3945                 :           0 :       g_warning ("g_main_context_prepare() called recursively from within a source's check() or "
    3946                 :             :                  "prepare() member.");
    3947                 :           0 :       return FALSE;
    3948                 :             :     }
    3949                 :             : 
    3950                 :      853059 :   TRACE (GLIB_MAIN_CONTEXT_BEFORE_PREPARE (context));
    3951                 :             : 
    3952                 :             : #if 0
    3953                 :             :   /* If recursing, finish up current dispatch, before starting over */
    3954                 :             :   if (context->pending_dispatches)
    3955                 :             :     {
    3956                 :             :       if (dispatch)
    3957                 :             :         g_main_dispatch (context, &current_time);
    3958                 :             :       
    3959                 :             :       return TRUE;
    3960                 :             :     }
    3961                 :             : #endif
    3962                 :             : 
    3963                 :             :   /* If recursing, clear list of pending dispatches */
    3964                 :             : 
    3965                 :     1100289 :   for (i = 0; i < context->pending_dispatches->len; i++)
    3966                 :             :     {
    3967                 :          34 :       if (context->pending_dispatches->pdata[i])
    3968                 :           8 :         g_source_unref_internal ((GSource *)context->pending_dispatches->pdata[i], context, TRUE);
    3969                 :          16 :     }
    3970                 :     1100255 :   g_ptr_array_set_size (context->pending_dispatches, 0);
    3971                 :             :   
    3972                 :             :   /* Prepare all sources */
    3973                 :             : 
    3974                 :     1100255 :   context->timeout_usec = -1;
    3975                 :             :   
    3976                 :     1100255 :   g_source_iter_init (&iter, context, TRUE);
    3977                 :     3000883 :   while (g_source_iter_next (&iter, &source))
    3978                 :             :     {
    3979                 :     2000742 :       gint64 source_timeout_usec = -1;
    3980                 :             : 
    3981                 :     2000742 :       if (SOURCE_DESTROYED (source) || SOURCE_BLOCKED (source))
    3982                 :      496871 :         continue;
    3983                 :     1503871 :       if ((n_ready > 0) && (source->priority > current_priority))
    3984                 :      100114 :         break;
    3985                 :             : 
    3986                 :     1403757 :       if (!(g_atomic_int_get (&source->flags) & G_SOURCE_READY))
    3987                 :             :         {
    3988                 :             :           gboolean result;
    3989                 :             :           gboolean (* prepare) (GSource  *source,
    3990                 :             :                                 gint     *timeout);
    3991                 :             : 
    3992                 :     1403335 :           prepare = source->source_funcs->prepare;
    3993                 :             : 
    3994                 :     1403335 :           if (prepare)
    3995                 :             :             {
    3996                 :             :               gint64 begin_time_nsec G_GNUC_UNUSED;
    3997                 :      726178 :               int source_timeout_msec = -1;
    3998                 :             : 
    3999                 :      726178 :               context->in_check_or_prepare++;
    4000                 :      726178 :               UNLOCK_CONTEXT (context);
    4001                 :             : 
    4002                 :      726178 :               begin_time_nsec = G_TRACE_CURRENT_TIME;
    4003                 :             : 
    4004                 :      726178 :               result = (*prepare) (source, &source_timeout_msec);
    4005                 :      488700 :               TRACE (GLIB_MAIN_AFTER_PREPARE (source, prepare, source_timeout_msec));
    4006                 :             : 
    4007                 :      726178 :               source_timeout_usec = extend_timeout_to_usec (source_timeout_msec);
    4008                 :             : 
    4009                 :     1454794 :               g_trace_mark (begin_time_nsec, G_TRACE_CURRENT_TIME - begin_time_nsec,
    4010                 :             :                             "GLib", "GSource.prepare",
    4011                 :             :                             "%s ⇒ %s",
    4012                 :      966094 :                             (g_source_get_name (source) != NULL) ? g_source_get_name (source) : "(unnamed)",
    4013                 :             :                             result ? "ready" : "unready");
    4014                 :             : 
    4015                 :      726178 :               LOCK_CONTEXT (context);
    4016                 :      726178 :               context->in_check_or_prepare--;
    4017                 :      237478 :             }
    4018                 :             :           else
    4019                 :      677157 :             result = FALSE;
    4020                 :             : 
    4021                 :     1403335 :           if (result == FALSE && source->priv->ready_time != -1)
    4022                 :             :             {
    4023                 :      103994 :               if (!context->time_is_fresh)
    4024                 :             :                 {
    4025                 :      101648 :                   context->time = g_get_monotonic_time ();
    4026                 :      101648 :                   context->time_is_fresh = TRUE;
    4027                 :       18917 :                 }
    4028                 :             : 
    4029                 :      103994 :               if (source->priv->ready_time <= context->time)
    4030                 :             :                 {
    4031                 :        3569 :                   source_timeout_usec = 0;
    4032                 :        3569 :                   result = TRUE;
    4033                 :          90 :                 }
    4034                 :      100425 :               else if (source_timeout_usec < 0 ||
    4035                 :           0 :                        (source->priv->ready_time < context->time + source_timeout_usec))
    4036                 :             :                 {
    4037                 :      100425 :                   source_timeout_usec = MAX (0, source->priv->ready_time - context->time);
    4038                 :       18971 :                 }
    4039                 :       19061 :             }
    4040                 :             : 
    4041                 :     1403335 :           if (result)
    4042                 :             :             {
    4043                 :      570177 :               GSource *ready_source = source;
    4044                 :             : 
    4045                 :     1140766 :               while (ready_source)
    4046                 :             :                 {
    4047                 :      570589 :                   g_atomic_int_or (&ready_source->flags, G_SOURCE_READY);
    4048                 :      570589 :                   ready_source = ready_source->priv->parent_source;
    4049                 :             :                 }
    4050                 :      220274 :             }
    4051                 :      278810 :         }
    4052                 :             : 
    4053                 :     1403757 :       if (g_atomic_int_get (&source->flags) & G_SOURCE_READY)
    4054                 :             :         {
    4055                 :      570599 :           n_ready++;
    4056                 :      570599 :           current_priority = source->priority;
    4057                 :      570599 :           context->timeout_usec = 0;
    4058                 :      220314 :         }
    4059                 :             : 
    4060                 :     1403757 :       if (source_timeout_usec >= 0)
    4061                 :             :         {
    4062                 :      693013 :           if (context->timeout_usec < 0)
    4063                 :      104691 :             context->timeout_usec = source_timeout_usec;
    4064                 :             :           else
    4065                 :      588322 :             context->timeout_usec = MIN (context->timeout_usec, source_timeout_usec);
    4066                 :      250380 :         }
    4067                 :             :     }
    4068                 :     1100255 :   g_source_iter_clear (&iter);
    4069                 :             : 
    4070                 :      853059 :   TRACE (GLIB_MAIN_CONTEXT_AFTER_PREPARE (context, current_priority, n_ready));
    4071                 :             :   
    4072                 :     1100255 :   if (priority)
    4073                 :     1100251 :     *priority = current_priority;
    4074                 :             :   
    4075                 :     1100255 :   return (n_ready > 0);
    4076                 :      247196 : }
    4077                 :             : 
    4078                 :             : /**
    4079                 :             :  * g_main_context_query:
    4080                 :             :  * @context: (nullable): a main context (if `NULL`, the global-default
    4081                 :             :  *   main context will be used)
    4082                 :             :  * @max_priority: maximum priority source to check
    4083                 :             :  * @timeout_: (out): location to store timeout to be used in polling
    4084                 :             :  * @fds: (out caller-allocates) (array length=n_fds): location to
    4085                 :             :  *   store [struct@GLib.PollFD] records that need to be polled
    4086                 :             :  * @n_fds: (in): length of @fds
    4087                 :             :  *
    4088                 :             :  * Determines information necessary to poll this main loop.
    4089                 :             :  *
    4090                 :             :  * You should
    4091                 :             :  * be careful to pass the resulting @fds array and its length @n_fds
    4092                 :             :  * as-is when calling [method@GLib.MainContext.check], as this function relies
    4093                 :             :  * on assumptions made when the array is filled.
    4094                 :             :  *
    4095                 :             :  * You must have successfully acquired the context with
    4096                 :             :  * [method@GLib.MainContext.acquire] before you may call this function.
    4097                 :             :  *
    4098                 :             :  * Returns: the number of records actually stored in @fds,
    4099                 :             :  *   or, if more than @n_fds records need to be stored, the number
    4100                 :             :  *   of records that need to be stored
    4101                 :             :  **/
    4102                 :             : gint
    4103                 :          34 : g_main_context_query (GMainContext *context,
    4104                 :             :                       gint          max_priority,
    4105                 :             :                       gint         *timeout_msec,
    4106                 :             :                       GPollFD      *fds,
    4107                 :             :                       gint          n_fds)
    4108                 :             : {
    4109                 :             :   gint64 timeout_usec;
    4110                 :             :   gint n_poll;
    4111                 :             : 
    4112                 :          34 :   if (context == NULL)
    4113                 :           2 :     context = g_main_context_default ();
    4114                 :             : 
    4115                 :          34 :   LOCK_CONTEXT (context);
    4116                 :             : 
    4117                 :          34 :   n_poll = g_main_context_query_unlocked (context, max_priority, &timeout_usec, fds, n_fds);
    4118                 :             : 
    4119                 :          34 :   UNLOCK_CONTEXT (context);
    4120                 :             : 
    4121                 :          34 :   if (timeout_msec != NULL)
    4122                 :          20 :     *timeout_msec = round_timeout_to_msec (timeout_usec);
    4123                 :             : 
    4124                 :          34 :   return n_poll;
    4125                 :             : }
    4126                 :             : 
    4127                 :             : static gint
    4128                 :     1100472 : g_main_context_query_unlocked (GMainContext *context,
    4129                 :             :                                gint          max_priority,
    4130                 :             :                                gint64       *timeout_usec,
    4131                 :             :                                GPollFD      *fds,
    4132                 :             :                                gint          n_fds)
    4133                 :             : {
    4134                 :             :   gint n_poll;
    4135                 :             :   GPollRec *pollrec, *lastpollrec;
    4136                 :             :   gushort events;
    4137                 :             :   
    4138                 :      853254 :   TRACE (GLIB_MAIN_CONTEXT_BEFORE_QUERY (context, max_priority));
    4139                 :             : 
    4140                 :             :   /* fds is filled sequentially from poll_records. Since poll_records
    4141                 :             :    * are incrementally sorted by file descriptor identifier, fds will
    4142                 :             :    * also be incrementally sorted.
    4143                 :             :    */
    4144                 :     1100472 :   n_poll = 0;
    4145                 :     1100472 :   lastpollrec = NULL;
    4146                 :     2806405 :   for (pollrec = context->poll_records; pollrec; pollrec = pollrec->next)
    4147                 :             :     {
    4148                 :     1705933 :       if (pollrec->priority > max_priority)
    4149                 :          18 :         continue;
    4150                 :             : 
    4151                 :             :       /* In direct contradiction to the Unix98 spec, IRIX runs into
    4152                 :             :        * difficulty if you pass in POLLERR, POLLHUP or POLLNVAL
    4153                 :             :        * flags in the events field of the pollfd while it should
    4154                 :             :        * just ignoring them. So we mask them out here.
    4155                 :             :        */
    4156                 :     1705915 :       events = pollrec->fd->events & ~(G_IO_ERR|G_IO_HUP|G_IO_NVAL);
    4157                 :             : 
    4158                 :             :       /* This optimization --using the same GPollFD to poll for more
    4159                 :             :        * than one poll record-- relies on the poll records being
    4160                 :             :        * incrementally sorted.
    4161                 :             :        */
    4162                 :     1705915 :       if (lastpollrec && pollrec->fd->fd == lastpollrec->fd->fd)
    4163                 :             :         {
    4164                 :         186 :           if (n_poll - 1 < n_fds)
    4165                 :         186 :             fds[n_poll - 1].events |= events;
    4166                 :          35 :         }
    4167                 :             :       else
    4168                 :             :         {
    4169                 :     1705729 :           if (n_poll < n_fds)
    4170                 :             :             {
    4171                 :     1705495 :               fds[n_poll].fd = pollrec->fd->fd;
    4172                 :     1705495 :               fds[n_poll].events = events;
    4173                 :     1705495 :               fds[n_poll].revents = 0;
    4174                 :      252658 :             }
    4175                 :             : 
    4176                 :     1705729 :           n_poll++;
    4177                 :             :         }
    4178                 :             : 
    4179                 :     1705915 :       lastpollrec = pollrec;
    4180                 :      252719 :     }
    4181                 :             : 
    4182                 :     1100472 :   context->poll_changed = FALSE;
    4183                 :             : 
    4184                 :     1100472 :   if (timeout_usec)
    4185                 :             :     {
    4186                 :     1100472 :       *timeout_usec = context->timeout_usec;
    4187                 :     1100472 :       if (*timeout_usec != 0)
    4188                 :      547719 :         context->time_is_fresh = FALSE;
    4189                 :      247218 :     }
    4190                 :             : 
    4191                 :      853254 :   TRACE (GLIB_MAIN_CONTEXT_AFTER_QUERY (context, context->timeout_usec,
    4192                 :             :                                         fds, n_poll));
    4193                 :             : 
    4194                 :     1100472 :   return n_poll;
    4195                 :             : }
    4196                 :             : 
    4197                 :             : /**
    4198                 :             :  * g_main_context_check:
    4199                 :             :  * @context: (nullable): a main context (if `NULL`, the global-default
    4200                 :             :  *   main context will be used)
    4201                 :             :  * @max_priority: the maximum numerical priority of sources to check
    4202                 :             :  * @fds: (array length=n_fds): array of [struct@GLib.PollFD]s that was passed to
    4203                 :             :  *   the last call to [method@GLib.MainContext.query]
    4204                 :             :  * @n_fds: return value of [method@GLib.MainContext.query]
    4205                 :             :  *
    4206                 :             :  * Passes the results of polling back to the main loop.
    4207                 :             :  *
    4208                 :             :  * You should be
    4209                 :             :  * careful to pass @fds and its length @n_fds as received from
    4210                 :             :  * [method@GLib.MainContext.query], as this functions relies on assumptions
    4211                 :             :  * on how @fds is filled.
    4212                 :             :  *
    4213                 :             :  * You must have successfully acquired the context with
    4214                 :             :  * [method@GLib.MainContext.acquire] before you may call this function.
    4215                 :             :  *
    4216                 :             :  * Since 2.76 @context can be `NULL` to use the global-default
    4217                 :             :  * main context.
    4218                 :             :  *
    4219                 :             :  * Returns: true if some sources are ready to be dispatched, false otherwise
    4220                 :             :  **/
    4221                 :             : gboolean
    4222                 :          18 : g_main_context_check (GMainContext *context,
    4223                 :             :                       gint          max_priority,
    4224                 :             :                       GPollFD      *fds,
    4225                 :             :                       gint          n_fds)
    4226                 :             : {
    4227                 :             :   gboolean ready;
    4228                 :             : 
    4229                 :          18 :   if (context == NULL)
    4230                 :           2 :     context = g_main_context_default ();
    4231                 :             : 
    4232                 :          18 :   LOCK_CONTEXT (context);
    4233                 :             : 
    4234                 :          18 :   ready = g_main_context_check_unlocked (context, max_priority, fds, n_fds);
    4235                 :             : 
    4236                 :          18 :   UNLOCK_CONTEXT (context);
    4237                 :             : 
    4238                 :          18 :   return ready;
    4239                 :             : }
    4240                 :             : 
    4241                 :             : static gboolean
    4242                 :     1099879 : g_main_context_check_unlocked (GMainContext *context,
    4243                 :             :                                gint          max_priority,
    4244                 :             :                                GPollFD      *fds,
    4245                 :             :                                gint          n_fds)
    4246                 :             : {
    4247                 :             :   GSource *source;
    4248                 :             :   GSourceIter iter;
    4249                 :             :   GPollRec *pollrec;
    4250                 :     1099879 :   gint n_ready = 0;
    4251                 :             :   gint i;
    4252                 :             : 
    4253                 :     1099879 :   if (context->in_check_or_prepare)
    4254                 :             :     {
    4255                 :           0 :       g_warning ("g_main_context_check() called recursively from within a source's check() or "
    4256                 :             :                  "prepare() member.");
    4257                 :           0 :       return FALSE;
    4258                 :             :     }
    4259                 :             : 
    4260                 :      852719 :   TRACE (GLIB_MAIN_CONTEXT_BEFORE_CHECK (context, max_priority, fds, n_fds));
    4261                 :             : 
    4262                 :     1149828 :   for (i = 0; i < n_fds; i++)
    4263                 :             :     {
    4264                 :     1149804 :       if (fds[i].fd == context->wake_up_rec.fd)
    4265                 :             :         {
    4266                 :     1099855 :           if (fds[i].revents)
    4267                 :             :             {
    4268                 :      370592 :               TRACE (GLIB_MAIN_CONTEXT_WAKEUP_ACKNOWLEDGE (context));
    4269                 :      395691 :               g_wakeup_acknowledge (context->wakeup);
    4270                 :       25099 :             }
    4271                 :     1099855 :           break;
    4272                 :             :         }
    4273                 :        2116 :     }
    4274                 :             : 
    4275                 :             :   /* If the set of poll file descriptors changed, bail out
    4276                 :             :    * and let the main loop rerun
    4277                 :             :    */
    4278                 :     1099879 :   if (context->poll_changed)
    4279                 :             :     {
    4280                 :          89 :       TRACE (GLIB_MAIN_CONTEXT_AFTER_CHECK (context, 0));
    4281                 :             : 
    4282                 :         156 :       return FALSE;
    4283                 :             :     }
    4284                 :             : 
    4285                 :             :   /* The linear iteration below relies on the assumption that both
    4286                 :             :    * poll records and the fds array are incrementally sorted by file
    4287                 :             :    * descriptor identifier.
    4288                 :             :    */
    4289                 :     1099723 :   pollrec = context->poll_records;
    4290                 :     1099723 :   i = 0;
    4291                 :     2804158 :   while (pollrec && i < n_fds)
    4292                 :             :     {
    4293                 :             :       /* Make sure that fds is sorted by file descriptor identifier. */
    4294                 :     1704439 :       g_assert (i <= 0 || fds[i - 1].fd < fds[i].fd);
    4295                 :             : 
    4296                 :             :       /* Skip until finding the first GPollRec matching the current GPollFD. */
    4297                 :     1704440 :       while (pollrec && pollrec->fd->fd != fds[i].fd)
    4298                 :           1 :         pollrec = pollrec->next;
    4299                 :             : 
    4300                 :             :       /* Update all consecutive GPollRecs that match. */
    4301                 :     3409058 :       while (pollrec && pollrec->fd->fd == fds[i].fd)
    4302                 :             :         {
    4303                 :     1704619 :           if (pollrec->priority <= max_priority)
    4304                 :             :             {
    4305                 :     1704617 :               pollrec->fd->revents =
    4306                 :     1704617 :                 fds[i].revents & (pollrec->fd->events | G_IO_ERR | G_IO_HUP | G_IO_NVAL);
    4307                 :      252503 :             }
    4308                 :     1704619 :           pollrec = pollrec->next;
    4309                 :             :         }
    4310                 :             : 
    4311                 :             :       /* Iterate to next GPollFD. */
    4312                 :     1704435 :       i++;
    4313                 :             :     }
    4314                 :             : 
    4315                 :     1099719 :   g_source_iter_init (&iter, context, TRUE);
    4316                 :     2901306 :   while (g_source_iter_next (&iter, &source))
    4317                 :             :     {
    4318                 :     2032869 :       if (SOURCE_DESTROYED (source) || SOURCE_BLOCKED (source))
    4319                 :      496474 :         continue;
    4320                 :     1536395 :       if ((n_ready > 0) && (source->priority > max_priority))
    4321                 :      231282 :         break;
    4322                 :             : 
    4323                 :     1305113 :       if (!(g_atomic_int_get (&source->flags) & G_SOURCE_READY))
    4324                 :             :         {
    4325                 :             :           gboolean result;
    4326                 :             :           gboolean (* check) (GSource *source);
    4327                 :             : 
    4328                 :      731654 :           check = source->source_funcs->check;
    4329                 :             : 
    4330                 :      731654 :           if (check)
    4331                 :             :             {
    4332                 :             :               gint64 begin_time_nsec G_GNUC_UNUSED;
    4333                 :             : 
    4334                 :             :               /* If the check function is set, call it. */
    4335                 :       58881 :               context->in_check_or_prepare++;
    4336                 :       58881 :               UNLOCK_CONTEXT (context);
    4337                 :             : 
    4338                 :       58881 :               begin_time_nsec = G_TRACE_CURRENT_TIME;
    4339                 :             : 
    4340                 :       58881 :               result = (* check) (source);
    4341                 :             : 
    4342                 :       53154 :               TRACE (GLIB_MAIN_AFTER_CHECK (source, check, result));
    4343                 :             : 
    4344                 :      159330 :               g_trace_mark (begin_time_nsec, G_TRACE_CURRENT_TIME - begin_time_nsec,
    4345                 :             :                             "GLib", "GSource.check",
    4346                 :             :                             "%s ⇒ %s",
    4347                 :      106176 :                             (g_source_get_name (source) != NULL) ? g_source_get_name (source) : "(unnamed)",
    4348                 :             :                             result ? "dispatch" : "ignore");
    4349                 :             : 
    4350                 :       58881 :               LOCK_CONTEXT (context);
    4351                 :       58881 :               context->in_check_or_prepare--;
    4352                 :        5727 :             }
    4353                 :             :           else
    4354                 :      672773 :             result = FALSE;
    4355                 :             : 
    4356                 :      731654 :           if (result == FALSE)
    4357                 :             :             {
    4358                 :             :               GSList *tmp_list;
    4359                 :             : 
    4360                 :             :               /* If not already explicitly flagged ready by ->check()
    4361                 :             :                * (or if we have no check) then we can still be ready if
    4362                 :             :                * any of our fds poll as ready.
    4363                 :             :                */
    4364                 :      865194 :               for (tmp_list = source->priv->fds; tmp_list; tmp_list = tmp_list->next)
    4365                 :             :                 {
    4366                 :      452762 :                   GPollFD *pollfd = tmp_list->data;
    4367                 :             : 
    4368                 :      452762 :                   if (pollfd->revents)
    4369                 :             :                     {
    4370                 :      274680 :                       result = TRUE;
    4371                 :      274680 :                       break;
    4372                 :             :                     }
    4373                 :           0 :                 }
    4374                 :       57065 :             }
    4375                 :             : 
    4376                 :      731654 :           if (result == FALSE && source->priv->ready_time != -1)
    4377                 :             :             {
    4378                 :      133398 :               if (!context->time_is_fresh)
    4379                 :             :                 {
    4380                 :       51149 :                   context->time = g_get_monotonic_time ();
    4381                 :       51149 :                   context->time_is_fresh = TRUE;
    4382                 :       22421 :                 }
    4383                 :             : 
    4384                 :      133398 :               if (source->priv->ready_time <= context->time)
    4385                 :       41701 :                 result = TRUE;
    4386                 :       41027 :             }
    4387                 :             : 
    4388                 :      731654 :           if (result)
    4389                 :             :             {
    4390                 :      360924 :               GSource *ready_source = source;
    4391                 :             : 
    4392                 :      724712 :               while (ready_source)
    4393                 :             :                 {
    4394                 :      363788 :                   g_atomic_int_or (&ready_source->flags, G_SOURCE_READY);
    4395                 :      363788 :                   ready_source = ready_source->priv->parent_source;
    4396                 :             :                 }
    4397                 :       24003 :             }
    4398                 :       58871 :         }
    4399                 :             : 
    4400                 :     1305113 :       if (g_atomic_int_get (&source->flags) & G_SOURCE_READY)
    4401                 :             :         {
    4402                 :      934383 :           g_source_ref (source);
    4403                 :      934383 :           g_ptr_array_add (context->pending_dispatches, source);
    4404                 :             : 
    4405                 :      934383 :           n_ready++;
    4406                 :             : 
    4407                 :             :           /* never dispatch sources with less priority than the first
    4408                 :             :            * one we choose to dispatch
    4409                 :             :            */
    4410                 :      934383 :           max_priority = source->priority;
    4411                 :      244329 :         }
    4412                 :             :     }
    4413                 :     1099719 :   g_source_iter_clear (&iter);
    4414                 :             : 
    4415                 :      852630 :   TRACE (GLIB_MAIN_CONTEXT_AFTER_CHECK (context, n_ready));
    4416                 :             : 
    4417                 :     1099719 :   return n_ready > 0;
    4418                 :      247156 : }
    4419                 :             : 
    4420                 :             : /**
    4421                 :             :  * g_main_context_dispatch:
    4422                 :             :  * @context: (nullable): a main context (if `NULL`, the global-default
    4423                 :             :  *   main context will be used)
    4424                 :             :  *
    4425                 :             :  * Dispatches all pending sources.
    4426                 :             :  *
    4427                 :             :  * You must have successfully acquired the context with
    4428                 :             :  * [method@GLib.MainContext.acquire] before you may call this function.
    4429                 :             :  *
    4430                 :             :  * Since 2.76 @context can be `NULL` to use the global-default
    4431                 :             :  * main context.
    4432                 :             :  **/
    4433                 :             : void
    4434                 :           9 : g_main_context_dispatch (GMainContext *context)
    4435                 :             : {
    4436                 :           9 :   if (context == NULL)
    4437                 :           2 :     context = g_main_context_default ();
    4438                 :             : 
    4439                 :           9 :   LOCK_CONTEXT (context);
    4440                 :             : 
    4441                 :           9 :   g_main_context_dispatch_unlocked (context);
    4442                 :             : 
    4443                 :           9 :   UNLOCK_CONTEXT (context);
    4444                 :           9 : }
    4445                 :             : 
    4446                 :             : static void
    4447                 :     1099840 : g_main_context_dispatch_unlocked (GMainContext *context)
    4448                 :             : {
    4449                 :      852697 :   TRACE (GLIB_MAIN_CONTEXT_BEFORE_DISPATCH (context));
    4450                 :             : 
    4451                 :     1099840 :   if (context->pending_dispatches->len > 0)
    4452                 :             :     {
    4453                 :      903019 :       g_main_dispatch (context);
    4454                 :      242588 :     }
    4455                 :             : 
    4456                 :      852691 :   TRACE (GLIB_MAIN_CONTEXT_AFTER_DISPATCH (context));
    4457                 :     1099834 : }
    4458                 :             : 
    4459                 :             : /* HOLDS context lock */
    4460                 :             : static gboolean
    4461                 :     1128055 : g_main_context_iterate_unlocked (GMainContext *context,
    4462                 :             :                                  gboolean      block,
    4463                 :             :                                  gboolean      dispatch,
    4464                 :             :                                  GThread      *self)
    4465                 :             : {
    4466                 :     1128055 :   gint max_priority = 0;
    4467                 :             :   gint64 timeout_usec;
    4468                 :             :   gboolean some_ready;
    4469                 :             :   gint nfds, allocated_nfds;
    4470                 :     1128055 :   GPollFD *fds = NULL;
    4471                 :             :   gint64 begin_time_nsec G_GNUC_UNUSED;
    4472                 :             : 
    4473                 :     1128055 :   begin_time_nsec = G_TRACE_CURRENT_TIME;
    4474                 :             : 
    4475                 :     1128055 :   if (!g_main_context_acquire_unlocked (context))
    4476                 :             :     {
    4477                 :             :       gboolean got_ownership;
    4478                 :             : 
    4479                 :       27866 :       if (!block)
    4480                 :       27866 :         return FALSE;
    4481                 :             : 
    4482                 :           0 :       got_ownership = g_main_context_wait_internal (context,
    4483                 :           0 :                                                     &context->cond,
    4484                 :           0 :                                                     &context->mutex);
    4485                 :             : 
    4486                 :           0 :       if (!got_ownership)
    4487                 :           0 :         return FALSE;
    4488                 :           0 :     }
    4489                 :             :   
    4490                 :     1100189 :   if (!context->cached_poll_array)
    4491                 :             :     {
    4492                 :        7133 :       context->cached_poll_array_size = context->n_poll_records;
    4493                 :        7133 :       context->cached_poll_array = g_new (GPollFD, context->n_poll_records);
    4494                 :         463 :     }
    4495                 :             : 
    4496                 :     1100189 :   allocated_nfds = context->cached_poll_array_size;
    4497                 :     1100189 :   fds = context->cached_poll_array;
    4498                 :             :   
    4499                 :     1100189 :   g_main_context_prepare_unlocked (context, &max_priority);
    4500                 :             : 
    4501                 :     1100396 :   while ((nfds = g_main_context_query_unlocked (
    4502                 :      247166 :               context, max_priority, &timeout_usec, fds,
    4503                 :     1347562 :               allocated_nfds)) > allocated_nfds)
    4504                 :             :     {
    4505                 :         207 :       g_free (fds);
    4506                 :         207 :       context->cached_poll_array_size = allocated_nfds = nfds;
    4507                 :         207 :       context->cached_poll_array = fds = g_new (GPollFD, nfds);
    4508                 :             :     }
    4509                 :             : 
    4510                 :     1100189 :   if (!block)
    4511                 :      372515 :     timeout_usec = 0;
    4512                 :             : 
    4513                 :     1100189 :   g_main_context_poll_unlocked (context, timeout_usec, max_priority, fds, nfds);
    4514                 :             : 
    4515                 :     1099852 :   some_ready = g_main_context_check_unlocked (context, max_priority, fds, nfds);
    4516                 :             :   
    4517                 :     1099852 :   if (dispatch)
    4518                 :     1099831 :     g_main_context_dispatch_unlocked (context);
    4519                 :             :   
    4520                 :     1099846 :   g_main_context_release_unlocked (context);
    4521                 :             : 
    4522                 :      852697 :   g_trace_mark (begin_time_nsec, G_TRACE_CURRENT_TIME - begin_time_nsec,
    4523                 :             :                 "GLib", "g_main_context_iterate",
    4524                 :             :                 "Context %p, %s ⇒ %s", context, block ? "blocking" : "non-blocking", some_ready ? "dispatched" : "nothing");
    4525                 :             : 
    4526                 :     1099846 :   return some_ready;
    4527                 :      247149 : }
    4528                 :             : 
    4529                 :             : /**
    4530                 :             :  * g_main_context_pending:
    4531                 :             :  * @context: (nullable): a main context (if `NULL`, the global-default
    4532                 :             :  *   main context will be used)
    4533                 :             :  *
    4534                 :             :  * Checks if any sources have pending events for the given context.
    4535                 :             :  * 
    4536                 :             :  * Returns: true if events are pending, false otherwise
    4537                 :             :  **/
    4538                 :             : gboolean 
    4539                 :          24 : g_main_context_pending (GMainContext *context)
    4540                 :             : {
    4541                 :             :   gboolean retval;
    4542                 :             : 
    4543                 :          24 :   if (!context)
    4544                 :          14 :     context = g_main_context_default();
    4545                 :             : 
    4546                 :          24 :   LOCK_CONTEXT (context);
    4547                 :          24 :   retval = g_main_context_iterate_unlocked (context, FALSE, FALSE, G_THREAD_SELF);
    4548                 :          24 :   UNLOCK_CONTEXT (context);
    4549                 :             :   
    4550                 :          24 :   return retval;
    4551                 :             : }
    4552                 :             : 
    4553                 :             : /**
    4554                 :             :  * g_main_context_iteration:
    4555                 :             :  * @context: (nullable): a main context (if `NULL`, the global-default
    4556                 :             :  *   main context will be used)
    4557                 :             :  * @may_block: whether the call may block
    4558                 :             :  *
    4559                 :             :  * Runs a single iteration for the given main loop.
    4560                 :             :  *
    4561                 :             :  * This involves
    4562                 :             :  * checking to see if any event sources are ready to be processed,
    4563                 :             :  * then if no events sources are ready and @may_block is true, waiting
    4564                 :             :  * for a source to become ready, then dispatching the highest priority
    4565                 :             :  * events sources that are ready. Otherwise, if @may_block is false,
    4566                 :             :  * this function does not wait for sources to become ready, and only the highest
    4567                 :             :  * priority sources which are already ready (if any) will be dispatched.
    4568                 :             :  *
    4569                 :             :  * Note that even when @may_block is true, it is still possible for
    4570                 :             :  * [method@GLib.MainContext.iteration] to return false, since the wait may
    4571                 :             :  * be interrupted for other reasons than an event source becoming ready.
    4572                 :             :  *
    4573                 :             :  * Returns: true if events were dispatched, false otherwise
    4574                 :             :  **/
    4575                 :             : gboolean
    4576                 :      713332 : g_main_context_iteration (GMainContext *context, gboolean may_block)
    4577                 :             : {
    4578                 :             :   gboolean retval;
    4579                 :             : 
    4580                 :      713332 :   if (!context)
    4581                 :      469180 :     context = g_main_context_default();
    4582                 :             :   
    4583                 :      713332 :   LOCK_CONTEXT (context);
    4584                 :      713332 :   retval = g_main_context_iterate_unlocked (context, may_block, TRUE, G_THREAD_SELF);
    4585                 :      713095 :   UNLOCK_CONTEXT (context);
    4586                 :             :   
    4587                 :      713095 :   return retval;
    4588                 :             : }
    4589                 :             : 
    4590                 :             : /**
    4591                 :             :  * g_main_loop_new:
    4592                 :             :  * @context: (nullable): a main context  (if `NULL`, the global-default
    4593                 :             :  *   main context will be used).
    4594                 :             :  * @is_running: set to true to indicate that the loop is running. This
    4595                 :             :  *   is not very important since calling [method@GLib.MainLoop.run] will set this
    4596                 :             :  *   to true anyway.
    4597                 :             :  * 
    4598                 :             :  * Creates a new [struct@GLib.MainLoop] structure.
    4599                 :             :  * 
    4600                 :             :  * Returns: (transfer full): a new main loop
    4601                 :             :  **/
    4602                 :             : GMainLoop *
    4603                 :        7131 : g_main_loop_new (GMainContext *context,
    4604                 :             :                  gboolean      is_running)
    4605                 :             : {
    4606                 :             :   GMainLoop *loop;
    4607                 :             : 
    4608                 :        7131 :   if (!context)
    4609                 :         511 :     context = g_main_context_default();
    4610                 :             :   
    4611                 :        7131 :   g_main_context_ref (context);
    4612                 :             : 
    4613                 :        7131 :   loop = g_new0 (GMainLoop, 1);
    4614                 :        7131 :   loop->context = context;
    4615                 :        7131 :   loop->is_running = is_running != FALSE;
    4616                 :        7131 :   loop->ref_count = 1;
    4617                 :             : 
    4618                 :        6606 :   TRACE (GLIB_MAIN_LOOP_NEW (loop, context));
    4619                 :             : 
    4620                 :        7131 :   return loop;
    4621                 :             : }
    4622                 :             : 
    4623                 :             : /**
    4624                 :             :  * g_main_loop_ref:
    4625                 :             :  * @loop: a main loop
    4626                 :             :  *
    4627                 :             :  * Increases the reference count on a [struct@GLib.MainLoop] object by one.
    4628                 :             :  *
    4629                 :             :  * Returns: @loop
    4630                 :             :  **/
    4631                 :             : GMainLoop *
    4632                 :           4 : g_main_loop_ref (GMainLoop *loop)
    4633                 :             : {
    4634                 :           4 :   g_return_val_if_fail (loop != NULL, NULL);
    4635                 :           4 :   g_return_val_if_fail (g_atomic_int_get (&loop->ref_count) > 0, NULL);
    4636                 :             : 
    4637                 :           4 :   g_atomic_int_inc (&loop->ref_count);
    4638                 :             : 
    4639                 :           4 :   return loop;
    4640                 :           2 : }
    4641                 :             : 
    4642                 :             : /**
    4643                 :             :  * g_main_loop_unref:
    4644                 :             :  * @loop: a main loop
    4645                 :             :  *
    4646                 :             :  * Decreases the reference count on a [struct@GLib.MainLoop] object by one.
    4647                 :             :  *
    4648                 :             :  * If the result is zero, the loop and all associated memory are freed.
    4649                 :             :  **/
    4650                 :             : void
    4651                 :       17759 : g_main_loop_unref (GMainLoop *loop)
    4652                 :             : {
    4653                 :       17759 :   g_return_if_fail (loop != NULL);
    4654                 :       17759 :   g_return_if_fail (g_atomic_int_get (&loop->ref_count) > 0);
    4655                 :             : 
    4656                 :       17759 :   if (!g_atomic_int_dec_and_test (&loop->ref_count))
    4657                 :       10751 :     return;
    4658                 :             : 
    4659                 :        7008 :   g_main_context_unref (loop->context);
    4660                 :        7008 :   g_free (loop);
    4661                 :        1765 : }
    4662                 :             : 
    4663                 :             : /**
    4664                 :             :  * g_main_loop_run:
    4665                 :             :  * @loop: a main loop
    4666                 :             :  * 
    4667                 :             :  * Runs a main loop until [method@GLib.MainLoop.quit] is called on the loop.
    4668                 :             :  *
    4669                 :             :  * If this is called from the thread of the loop’s [struct@GLib.MainContext],
    4670                 :             :  * it will process events from the loop, otherwise it will
    4671                 :             :  * simply wait.
    4672                 :             :  **/
    4673                 :             : void 
    4674                 :       10857 : g_main_loop_run (GMainLoop *loop)
    4675                 :             : {
    4676                 :       10857 :   GThread *self = G_THREAD_SELF;
    4677                 :             : 
    4678                 :       10857 :   g_return_if_fail (loop != NULL);
    4679                 :       10857 :   g_return_if_fail (g_atomic_int_get (&loop->ref_count) > 0);
    4680                 :             : 
    4681                 :             :   /* Hold a reference in case the loop is unreffed from a callback function */
    4682                 :       10857 :   g_atomic_int_inc (&loop->ref_count);
    4683                 :             : 
    4684                 :       10857 :   LOCK_CONTEXT (loop->context);
    4685                 :             : 
    4686                 :       10857 :   if (!g_main_context_acquire_unlocked (loop->context))
    4687                 :             :     {
    4688                 :           1 :       gboolean got_ownership = FALSE;
    4689                 :             :       
    4690                 :             :       /* Another thread owns this context */
    4691                 :           1 :       g_atomic_int_set (&loop->is_running, TRUE);
    4692                 :             : 
    4693                 :           2 :       while (g_atomic_int_get (&loop->is_running) && !got_ownership)
    4694                 :           1 :         got_ownership = g_main_context_wait_internal (loop->context,
    4695                 :           1 :                                                       &loop->context->cond,
    4696                 :           1 :                                                       &loop->context->mutex);
    4697                 :             :       
    4698                 :           1 :       if (!g_atomic_int_get (&loop->is_running))
    4699                 :             :         {
    4700                 :           1 :           if (got_ownership)
    4701                 :           1 :             g_main_context_release_unlocked (loop->context);
    4702                 :             : 
    4703                 :           1 :           UNLOCK_CONTEXT (loop->context);
    4704                 :           1 :           g_main_loop_unref (loop);
    4705                 :           1 :           return;
    4706                 :             :         }
    4707                 :             : 
    4708                 :           0 :       g_assert (got_ownership);
    4709                 :           0 :     }
    4710                 :             : 
    4711                 :       10856 :   if G_UNLIKELY (loop->context->in_check_or_prepare)
    4712                 :             :     {
    4713                 :           4 :       g_warning ("g_main_loop_run(): called recursively from within a source's "
    4714                 :             :                  "check() or prepare() member, iteration not possible.");
    4715                 :           4 :       g_main_context_release_unlocked (loop->context);
    4716                 :           4 :       UNLOCK_CONTEXT (loop->context);
    4717                 :           4 :       g_main_loop_unref (loop);
    4718                 :           4 :       return;
    4719                 :             :     }
    4720                 :             : 
    4721                 :       10852 :   g_atomic_int_set (&loop->is_running, TRUE);
    4722                 :      425487 :   while (g_atomic_int_get (&loop->is_running))
    4723                 :      414741 :     g_main_context_iterate_unlocked (loop->context, TRUE, TRUE, self);
    4724                 :             : 
    4725                 :       10746 :   g_main_context_release_unlocked (loop->context);
    4726                 :             : 
    4727                 :       10746 :   UNLOCK_CONTEXT (loop->context);
    4728                 :             :   
    4729                 :       10746 :   g_main_loop_unref (loop);
    4730                 :        1252 : }
    4731                 :             : 
    4732                 :             : /**
    4733                 :             :  * g_main_loop_quit:
    4734                 :             :  * @loop: a main loop
    4735                 :             :  *
    4736                 :             :  * Stops a [struct@GLib.MainLoop] from running. Any calls to
    4737                 :             :  * [method@GLib.MainLoop.run] for the loop will return.
    4738                 :             :  *
    4739                 :             :  * Note that sources that have already been dispatched when
    4740                 :             :  * [method@GLib.MainLoop.quit] is called will still be executed.
    4741                 :             :  **/
    4742                 :             : void 
    4743                 :       10838 : g_main_loop_quit (GMainLoop *loop)
    4744                 :             : {
    4745                 :       10838 :   g_return_if_fail (loop != NULL);
    4746                 :       10838 :   g_return_if_fail (g_atomic_int_get (&loop->ref_count) > 0);
    4747                 :             : 
    4748                 :       10838 :   LOCK_CONTEXT (loop->context);
    4749                 :       10838 :   g_atomic_int_set (&loop->is_running, FALSE);
    4750                 :       10838 :   g_wakeup_signal (loop->context->wakeup);
    4751                 :             : 
    4752                 :       10838 :   g_cond_broadcast (&loop->context->cond);
    4753                 :             : 
    4754                 :       10838 :   UNLOCK_CONTEXT (loop->context);
    4755                 :             : 
    4756                 :        9564 :   TRACE (GLIB_MAIN_LOOP_QUIT (loop));
    4757                 :        1274 : }
    4758                 :             : 
    4759                 :             : /**
    4760                 :             :  * g_main_loop_is_running:
    4761                 :             :  * @loop: a main loop
    4762                 :             :  *
    4763                 :             :  * Checks to see if the main loop is currently being run via
    4764                 :             :  * [method@GLib.MainLoop.run].
    4765                 :             :  *
    4766                 :             :  * Returns: true if the main loop is currently being run, false otherwise
    4767                 :             :  **/
    4768                 :             : gboolean
    4769                 :         139 : g_main_loop_is_running (GMainLoop *loop)
    4770                 :             : {
    4771                 :         139 :   g_return_val_if_fail (loop != NULL, FALSE);
    4772                 :         139 :   g_return_val_if_fail (g_atomic_int_get (&loop->ref_count) > 0, FALSE);
    4773                 :             : 
    4774                 :         139 :   return g_atomic_int_get (&loop->is_running);
    4775                 :          65 : }
    4776                 :             : 
    4777                 :             : /**
    4778                 :             :  * g_main_loop_get_context:
    4779                 :             :  * @loop: a main loop
    4780                 :             :  * 
    4781                 :             :  * Returns the [struct@GLib.MainContext] of @loop.
    4782                 :             :  * 
    4783                 :             :  * Returns: (transfer none): the [struct@GLib.MainContext] of @loop
    4784                 :             :  **/
    4785                 :             : GMainContext *
    4786                 :           8 : g_main_loop_get_context (GMainLoop *loop)
    4787                 :             : {
    4788                 :           8 :   g_return_val_if_fail (loop != NULL, NULL);
    4789                 :           8 :   g_return_val_if_fail (g_atomic_int_get (&loop->ref_count) > 0, NULL);
    4790                 :             :  
    4791                 :           8 :   return loop->context;
    4792                 :           3 : }
    4793                 :             : 
    4794                 :             : /* HOLDS: context's lock */
    4795                 :             : static void
    4796                 :     1100231 : g_main_context_poll_unlocked (GMainContext *context,
    4797                 :             :                               gint64        timeout_usec,
    4798                 :             :                               int           priority,
    4799                 :             :                               GPollFD      *fds,
    4800                 :             :                               int           n_fds)
    4801                 :             : {
    4802                 :             : #ifdef  G_MAIN_POLL_DEBUG
    4803                 :             :   GTimer *poll_timer;
    4804                 :             :   GPollRec *pollrec;
    4805                 :             :   gint i;
    4806                 :             : #endif
    4807                 :             : 
    4808                 :             :   GPollFunc poll_func;
    4809                 :             : 
    4810                 :     1100231 :   if (n_fds || timeout_usec != 0)
    4811                 :             :     {
    4812                 :             :       int ret, errsv;
    4813                 :             : 
    4814                 :             : #ifdef  G_MAIN_POLL_DEBUG
    4815                 :      247223 :       poll_timer = NULL;
    4816                 :      247223 :       if (_g_main_poll_debug)
    4817                 :             :         {
    4818                 :           0 :           g_print ("polling context=%p n=%d timeout_usec=%"G_GINT64_FORMAT"\n",
    4819                 :           0 :                    context, n_fds, timeout_usec);
    4820                 :           0 :           poll_timer = g_timer_new ();
    4821                 :           0 :         }
    4822                 :             : #endif
    4823                 :     1100178 :       poll_func = context->poll_func;
    4824                 :             : 
    4825                 :             : #if defined(HAVE_PPOLL) && defined(HAVE_POLL)
    4826                 :      853031 :       if (poll_func == g_poll)
    4827                 :             :         {
    4828                 :             :           struct timespec spec;
    4829                 :      853031 :           struct timespec *spec_p = NULL;
    4830                 :             : 
    4831                 :      853031 :           if (timeout_usec > -1)
    4832                 :             :             {
    4833                 :      534162 :               spec.tv_sec = timeout_usec / G_USEC_PER_SEC;
    4834                 :      534162 :               spec.tv_nsec = (timeout_usec % G_USEC_PER_SEC) * 1000L;
    4835                 :      534162 :               spec_p = &spec;
    4836                 :             :             }
    4837                 :             : 
    4838                 :      853031 :           UNLOCK_CONTEXT (context);
    4839                 :      853031 :           ret = ppoll ((struct pollfd *) fds, n_fds, spec_p, NULL);
    4840                 :      852694 :           LOCK_CONTEXT (context);
    4841                 :             :         }
    4842                 :             :       else
    4843                 :             : #endif
    4844                 :             :         {
    4845                 :      247147 :           int timeout_msec = round_timeout_to_msec (timeout_usec);
    4846                 :             : 
    4847                 :      247147 :           UNLOCK_CONTEXT (context);
    4848                 :      247147 :           ret = (*poll_func) (fds, n_fds, timeout_msec);
    4849                 :      247147 :           LOCK_CONTEXT (context);
    4850                 :             :         }
    4851                 :             : 
    4852                 :     1099841 :       errsv = errno;
    4853                 :     1099841 :       if (ret < 0 && errsv != EINTR)
    4854                 :             :         {
    4855                 :             : #ifndef G_OS_WIN32
    4856                 :           0 :           g_warning ("poll(2) failed due to: %s.",
    4857                 :             :                      g_strerror (errsv));
    4858                 :             : #else
    4859                 :             :           /* If g_poll () returns -1, it has already called g_warning() */
    4860                 :             : #endif
    4861                 :           0 :         }
    4862                 :             :       
    4863                 :             : #ifdef  G_MAIN_POLL_DEBUG
    4864                 :      247147 :       if (_g_main_poll_debug)
    4865                 :             :         {
    4866                 :           0 :           g_print ("g_main_poll(%d) timeout_usec: %"G_GINT64_FORMAT" - elapsed %12.10f seconds",
    4867                 :           0 :                    n_fds,
    4868                 :           0 :                    timeout_usec,
    4869                 :           0 :                    g_timer_elapsed (poll_timer, NULL));
    4870                 :           0 :           g_timer_destroy (poll_timer);
    4871                 :           0 :           pollrec = context->poll_records;
    4872                 :             : 
    4873                 :           0 :           while (pollrec != NULL)
    4874                 :             :             {
    4875                 :           0 :               i = 0;
    4876                 :           0 :               while (i < n_fds)
    4877                 :             :                 {
    4878                 :           0 :                   if (fds[i].fd == pollrec->fd->fd &&
    4879                 :           0 :                       pollrec->fd->events &&
    4880                 :           0 :                       fds[i].revents)
    4881                 :             :                     {
    4882                 :           0 :                       g_print (" [" G_POLLFD_FORMAT " :", fds[i].fd);
    4883                 :           0 :                       if (fds[i].revents & G_IO_IN)
    4884                 :           0 :                         g_print ("i");
    4885                 :           0 :                       if (fds[i].revents & G_IO_OUT)
    4886                 :           0 :                         g_print ("o");
    4887                 :           0 :                       if (fds[i].revents & G_IO_PRI)
    4888                 :           0 :                         g_print ("p");
    4889                 :           0 :                       if (fds[i].revents & G_IO_ERR)
    4890                 :           0 :                         g_print ("e");
    4891                 :           0 :                       if (fds[i].revents & G_IO_HUP)
    4892                 :           0 :                         g_print ("h");
    4893                 :           0 :                       if (fds[i].revents & G_IO_NVAL)
    4894                 :           0 :                         g_print ("n");
    4895                 :           0 :                       g_print ("]");
    4896                 :           0 :                     }
    4897                 :           0 :                   i++;
    4898                 :             :                 }
    4899                 :           0 :               pollrec = pollrec->next;
    4900                 :             :             }
    4901                 :           0 :           g_print ("\n");
    4902                 :           0 :         }
    4903                 :             : #endif
    4904                 :      247147 :     } /* if (n_fds || timeout_usec != 0) */
    4905                 :     1099882 : }
    4906                 :             : 
    4907                 :             : /**
    4908                 :             :  * g_main_context_add_poll:
    4909                 :             :  * @context: (nullable): a main context (or `NULL` for the global-default
    4910                 :             :  *   main context)
    4911                 :             :  * @fd: a [struct@GLib.PollFD] structure holding information about a file
    4912                 :             :  *   descriptor to watch.
    4913                 :             :  * @priority: the priority for this file descriptor which should be
    4914                 :             :  *   the same as the priority used for [method@GLib.Source.attach] to ensure
    4915                 :             :  *   that the file descriptor is polled whenever the results may be needed.
    4916                 :             :  *
    4917                 :             :  * Adds a file descriptor to the set of file descriptors polled for
    4918                 :             :  * this context.
    4919                 :             :  *
    4920                 :             :  * This will very seldom be used directly. Instead
    4921                 :             :  * a typical event source will use `g_source_add_unix_fd()` instead.
    4922                 :             :  **/
    4923                 :             : void
    4924                 :           0 : g_main_context_add_poll (GMainContext *context,
    4925                 :             :                          GPollFD      *fd,
    4926                 :             :                          gint          priority)
    4927                 :             : {
    4928                 :           0 :   if (!context)
    4929                 :           0 :     context = g_main_context_default ();
    4930                 :             :   
    4931                 :           0 :   g_return_if_fail (g_atomic_int_get (&context->ref_count) > 0);
    4932                 :           0 :   g_return_if_fail (fd);
    4933                 :             : 
    4934                 :           0 :   LOCK_CONTEXT (context);
    4935                 :           0 :   g_main_context_add_poll_unlocked (context, priority, fd);
    4936                 :           0 :   UNLOCK_CONTEXT (context);
    4937                 :           0 : }
    4938                 :             : 
    4939                 :             : /* HOLDS: main_loop_lock */
    4940                 :             : static void 
    4941                 :      330647 : g_main_context_add_poll_unlocked (GMainContext *context,
    4942                 :             :                                   gint          priority,
    4943                 :             :                                   GPollFD      *fd)
    4944                 :             : {
    4945                 :             :   GPollRec *prevrec, *nextrec;
    4946                 :      330647 :   GPollRec *newrec = g_slice_new (GPollRec);
    4947                 :             : 
    4948                 :             :   /* This file descriptor may be checked before we ever poll */
    4949                 :      330647 :   fd->revents = 0;
    4950                 :      330647 :   newrec->fd = fd;
    4951                 :      330647 :   newrec->priority = priority;
    4952                 :             : 
    4953                 :             :   /* Poll records are incrementally sorted by file descriptor identifier. */
    4954                 :      330647 :   prevrec = NULL;
    4955                 :      330647 :   nextrec = context->poll_records;
    4956                 :      738810 :   while (nextrec)
    4957                 :             :     {
    4958                 :      570073 :       if (nextrec->fd->fd > fd->fd)
    4959                 :      161910 :         break;
    4960                 :      408163 :       prevrec = nextrec;
    4961                 :      408163 :       nextrec = nextrec->next;
    4962                 :             :     }
    4963                 :             : 
    4964                 :      330647 :   if (prevrec)
    4965                 :      271505 :     prevrec->next = newrec;
    4966                 :             :   else
    4967                 :       59142 :     context->poll_records = newrec;
    4968                 :             : 
    4969                 :      330647 :   newrec->prev = prevrec;
    4970                 :      330647 :   newrec->next = nextrec;
    4971                 :             : 
    4972                 :      330647 :   if (nextrec)
    4973                 :      161910 :     nextrec->prev = newrec;
    4974                 :             : 
    4975                 :      330647 :   context->n_poll_records++;
    4976                 :             : 
    4977                 :      330647 :   context->poll_changed = TRUE;
    4978                 :             : 
    4979                 :             :   /* Now wake up the main loop if it is waiting in the poll() */
    4980                 :      330647 :   if (fd != &context->wake_up_rec)
    4981                 :      299328 :     g_wakeup_signal (context->wakeup);
    4982                 :      330647 : }
    4983                 :             : 
    4984                 :             : /**
    4985                 :             :  * g_main_context_remove_poll:
    4986                 :             :  * @context: (nullable): a main context (if `NULL`, the global-default
    4987                 :             :  *   main context will be used)
    4988                 :             :  * @fd: a [struct@GLib.PollFD] descriptor previously added with
    4989                 :             :  *   [method@GLib.MainContext.add_poll]
    4990                 :             :  *
    4991                 :             :  * Removes file descriptor from the set of file descriptors to be
    4992                 :             :  * polled for a particular context.
    4993                 :             :  **/
    4994                 :             : void
    4995                 :           0 : g_main_context_remove_poll (GMainContext *context,
    4996                 :             :                             GPollFD      *fd)
    4997                 :             : {
    4998                 :           0 :   if (!context)
    4999                 :           0 :     context = g_main_context_default ();
    5000                 :             :   
    5001                 :           0 :   g_return_if_fail (g_atomic_int_get (&context->ref_count) > 0);
    5002                 :           0 :   g_return_if_fail (fd);
    5003                 :             : 
    5004                 :           0 :   LOCK_CONTEXT (context);
    5005                 :           0 :   g_main_context_remove_poll_unlocked (context, fd);
    5006                 :           0 :   UNLOCK_CONTEXT (context);
    5007                 :           0 : }
    5008                 :             : 
    5009                 :             : static void
    5010                 :      299148 : g_main_context_remove_poll_unlocked (GMainContext *context,
    5011                 :             :                                      GPollFD      *fd)
    5012                 :             : {
    5013                 :             :   GPollRec *pollrec, *prevrec, *nextrec;
    5014                 :             : 
    5015                 :      299148 :   prevrec = NULL;
    5016                 :      299148 :   pollrec = context->poll_records;
    5017                 :             : 
    5018                 :      706256 :   while (pollrec)
    5019                 :             :     {
    5020                 :      706256 :       nextrec = pollrec->next;
    5021                 :      706256 :       if (pollrec->fd == fd)
    5022                 :             :         {
    5023                 :      299148 :           if (prevrec != NULL)
    5024                 :      271386 :             prevrec->next = nextrec;
    5025                 :             :           else
    5026                 :       27762 :             context->poll_records = nextrec;
    5027                 :             : 
    5028                 :      299148 :           if (nextrec != NULL)
    5029                 :      161814 :             nextrec->prev = prevrec;
    5030                 :             : 
    5031                 :      299148 :           g_slice_free (GPollRec, pollrec);
    5032                 :             : 
    5033                 :      299148 :           context->n_poll_records--;
    5034                 :      299148 :           break;
    5035                 :             :         }
    5036                 :      407108 :       prevrec = pollrec;
    5037                 :      407108 :       pollrec = nextrec;
    5038                 :             :     }
    5039                 :             : 
    5040                 :      299148 :   context->poll_changed = TRUE;
    5041                 :             : 
    5042                 :             :   /* Now wake up the main loop if it is waiting in the poll() */
    5043                 :      299148 :   g_wakeup_signal (context->wakeup);
    5044                 :      299148 : }
    5045                 :             : 
    5046                 :             : /**
    5047                 :             :  * g_source_get_current_time:
    5048                 :             :  * @source:  a source
    5049                 :             :  * @timeval: [struct@GLib.TimeVal] structure in which to store current time
    5050                 :             :  *
    5051                 :             :  * This function ignores @source and is otherwise the same as
    5052                 :             :  * [func@GLib.get_current_time].
    5053                 :             :  *
    5054                 :             :  * Deprecated: 2.28: use [method@GLib.Source.get_time] instead
    5055                 :             :  **/
    5056                 :             : G_GNUC_BEGIN_IGNORE_DEPRECATIONS
    5057                 :             : void
    5058                 :           4 : g_source_get_current_time (GSource  *source,
    5059                 :             :                            GTimeVal *timeval)
    5060                 :             : {
    5061                 :           4 :   g_get_current_time (timeval);
    5062                 :           4 : }
    5063                 :             : G_GNUC_END_IGNORE_DEPRECATIONS
    5064                 :             : 
    5065                 :             : /**
    5066                 :             :  * g_source_get_time:
    5067                 :             :  * @source: a source
    5068                 :             :  *
    5069                 :             :  * Gets the time to be used when checking this source.
    5070                 :             :  *
    5071                 :             :  * The advantage of
    5072                 :             :  * calling this function over calling [func@GLib.get_monotonic_time] directly is
    5073                 :             :  * that when checking multiple sources, GLib can cache a single value
    5074                 :             :  * instead of having to repeatedly get the system monotonic time.
    5075                 :             :  *
    5076                 :             :  * The time here is the system monotonic time, if available, or some
    5077                 :             :  * other reasonable alternative otherwise.  See [func@GLib.get_monotonic_time].
    5078                 :             :  *
    5079                 :             :  * Returns: the monotonic time in microseconds
    5080                 :             :  * Since: 2.28
    5081                 :             :  **/
    5082                 :             : gint64
    5083                 :      279020 : g_source_get_time (GSource *source)
    5084                 :             : {
    5085                 :             :   GMainContext *context;
    5086                 :             :   gint64 result;
    5087                 :             : 
    5088                 :      279020 :   g_return_val_if_fail (source != NULL, 0);
    5089                 :      279020 :   g_return_val_if_fail (g_atomic_int_get (&source->ref_count) > 0, 0);
    5090                 :      279020 :   context = source_dup_main_context (source);
    5091                 :      279020 :   g_return_val_if_fail (context != NULL, 0);
    5092                 :             : 
    5093                 :      279020 :   LOCK_CONTEXT (context);
    5094                 :             : 
    5095                 :      279020 :   if (!context->time_is_fresh)
    5096                 :             :     {
    5097                 :       93042 :       context->time = g_get_monotonic_time ();
    5098                 :       93042 :       context->time_is_fresh = TRUE;
    5099                 :        4767 :     }
    5100                 :             : 
    5101                 :      279020 :   result = context->time;
    5102                 :             : 
    5103                 :      279020 :   UNLOCK_CONTEXT (context);
    5104                 :      279020 :   g_main_context_unref (context);
    5105                 :             : 
    5106                 :      279020 :   return result;
    5107                 :       16180 : }
    5108                 :             : 
    5109                 :             : /**
    5110                 :             :  * g_main_context_set_poll_func:
    5111                 :             :  * @context: (nullable): a main context (if `NULL`, the global-default
    5112                 :             :  *   main context will be used)
    5113                 :             :  * @func: the function to call to poll all file descriptors
    5114                 :             :  * 
    5115                 :             :  * Sets the function to use to handle polling of file descriptors.
    5116                 :             :  *
    5117                 :             :  * It will be used instead of the [`poll()`](man:poll(2)) system call
    5118                 :             :  * (or GLib’s replacement function, which is used where
    5119                 :             :  * `poll()` isn’t available).
    5120                 :             :  *
    5121                 :             :  * This function could possibly be used to integrate the GLib event
    5122                 :             :  * loop with an external event loop.
    5123                 :             :  **/
    5124                 :             : void
    5125                 :           0 : g_main_context_set_poll_func (GMainContext *context,
    5126                 :             :                               GPollFunc     func)
    5127                 :             : {
    5128                 :           0 :   if (!context)
    5129                 :           0 :     context = g_main_context_default ();
    5130                 :             :   
    5131                 :           0 :   g_return_if_fail (g_atomic_int_get (&context->ref_count) > 0);
    5132                 :             : 
    5133                 :           0 :   LOCK_CONTEXT (context);
    5134                 :             :   
    5135                 :           0 :   if (func)
    5136                 :           0 :     context->poll_func = func;
    5137                 :             :   else
    5138                 :           0 :     context->poll_func = g_poll;
    5139                 :             : 
    5140                 :           0 :   UNLOCK_CONTEXT (context);
    5141                 :           0 : }
    5142                 :             : 
    5143                 :             : /**
    5144                 :             :  * g_main_context_get_poll_func:
    5145                 :             :  * @context: (nullable): a main context (if `NULL`, the global-default
    5146                 :             :  *   main context will be used)
    5147                 :             :  * 
    5148                 :             :  * Gets the poll function set by [method@GLib.MainContext.set_poll_func].
    5149                 :             :  * 
    5150                 :             :  * Returns: the poll function
    5151                 :             :  **/
    5152                 :             : GPollFunc
    5153                 :           0 : g_main_context_get_poll_func (GMainContext *context)
    5154                 :             : {
    5155                 :             :   GPollFunc result;
    5156                 :             :   
    5157                 :           0 :   if (!context)
    5158                 :           0 :     context = g_main_context_default ();
    5159                 :             :   
    5160                 :           0 :   g_return_val_if_fail (g_atomic_int_get (&context->ref_count) > 0, NULL);
    5161                 :             : 
    5162                 :           0 :   LOCK_CONTEXT (context);
    5163                 :           0 :   result = context->poll_func;
    5164                 :           0 :   UNLOCK_CONTEXT (context);
    5165                 :             : 
    5166                 :           0 :   return result;
    5167                 :           0 : }
    5168                 :             : 
    5169                 :             : /**
    5170                 :             :  * g_main_context_wakeup:
    5171                 :             :  * @context: (nullable): a main context (if `NULL`, the global-default
    5172                 :             :  *   main context will be used)
    5173                 :             :  * 
    5174                 :             :  * Wake up @context if it’s currently blocking in
    5175                 :             :  * [method@GLib.MainContext.iteration], causing it to stop blocking.
    5176                 :             :  *
    5177                 :             :  * The @context could be blocking waiting for a source to become ready.
    5178                 :             :  * Otherwise, if @context is not currently blocking, this function causes the
    5179                 :             :  * next invocation of [method@GLib.MainContext.iteration] to return without
    5180                 :             :  * blocking.
    5181                 :             :  *
    5182                 :             :  * This API is useful for low-level control over [struct@GLib.MainContext]; for
    5183                 :             :  * example, integrating it with main loop implementations such as
    5184                 :             :  * [struct@GLib.MainLoop].
    5185                 :             :  *
    5186                 :             :  * Another related use for this function is when implementing a main
    5187                 :             :  * loop with a termination condition, computed from multiple threads:
    5188                 :             :  *
    5189                 :             :  * ```c
    5190                 :             :  *   #define NUM_TASKS 10
    5191                 :             :  *   static gint tasks_remaining = NUM_TASKS;  // (atomic)
    5192                 :             :  *   ...
    5193                 :             :  *  
    5194                 :             :  *   while (g_atomic_int_get (&tasks_remaining) != 0)
    5195                 :             :  *     g_main_context_iteration (NULL, TRUE);
    5196                 :             :  * ```
    5197                 :             :  *  
    5198                 :             :  * Then in a thread:
    5199                 :             :  * ```c
    5200                 :             :  *   perform_work ();
    5201                 :             :  *
    5202                 :             :  *   if (g_atomic_int_dec_and_test (&tasks_remaining))
    5203                 :             :  *     g_main_context_wakeup (NULL);
    5204                 :             :  * ```
    5205                 :             :  **/
    5206                 :             : void
    5207                 :        2544 : g_main_context_wakeup (GMainContext *context)
    5208                 :             : {
    5209                 :        2544 :   if (!context)
    5210                 :        2311 :     context = g_main_context_default ();
    5211                 :             : 
    5212                 :        2544 :   g_return_if_fail (g_atomic_int_get (&context->ref_count) > 0);
    5213                 :             : 
    5214                 :        2393 :   TRACE (GLIB_MAIN_CONTEXT_WAKEUP (context));
    5215                 :             : 
    5216                 :        2544 :   g_wakeup_signal (context->wakeup);
    5217                 :         151 : }
    5218                 :             : 
    5219                 :             : /**
    5220                 :             :  * g_main_context_is_owner:
    5221                 :             :  * @context: (nullable): a main context (if `NULL`, the global-default
    5222                 :             :  *   main context will be used)
    5223                 :             :  * 
    5224                 :             :  * Determines whether this thread holds the (recursive)
    5225                 :             :  * ownership of this [struct@GLib.MainContext].
    5226                 :             :  *
    5227                 :             :  * This is useful to
    5228                 :             :  * know before waiting on another thread that may be
    5229                 :             :  * blocking to get ownership of @context.
    5230                 :             :  *
    5231                 :             :  * Returns: true if current thread is owner of @context, false otherwise
    5232                 :             :  * Since: 2.10
    5233                 :             :  **/
    5234                 :             : gboolean
    5235                 :         401 : g_main_context_is_owner (GMainContext *context)
    5236                 :             : {
    5237                 :             :   gboolean is_owner;
    5238                 :             : 
    5239                 :         401 :   if (!context)
    5240                 :           0 :     context = g_main_context_default ();
    5241                 :             : 
    5242                 :         401 :   LOCK_CONTEXT (context);
    5243                 :         401 :   is_owner = context->owner == G_THREAD_SELF;
    5244                 :         401 :   UNLOCK_CONTEXT (context);
    5245                 :             : 
    5246                 :         401 :   return is_owner;
    5247                 :             : }
    5248                 :             : 
    5249                 :             : /* Timeouts */
    5250                 :             : 
    5251                 :             : static void
    5252                 :       33487 : g_timeout_set_expiration (GTimeoutSource *timeout_source,
    5253                 :             :                           gint64          current_time)
    5254                 :             : {
    5255                 :             :   gint64 expiration;
    5256                 :             : 
    5257                 :       33487 :   if (timeout_source->seconds)
    5258                 :             :     {
    5259                 :             :       gint64 remainder;
    5260                 :             :       static gint timer_perturb = -1;
    5261                 :             : 
    5262                 :       24162 :       if (timer_perturb == -1)
    5263                 :             :         {
    5264                 :             :           /*
    5265                 :             :            * we want a per machine/session unique 'random' value; try the dbus
    5266                 :             :            * address first, that has a UUID in it. If there is no dbus, use the
    5267                 :             :            * hostname for hashing.
    5268                 :             :            */
    5269                 :          38 :           const char *session_bus_address = g_getenv ("DBUS_SESSION_BUS_ADDRESS");
    5270                 :          38 :           if (!session_bus_address)
    5271                 :          20 :             session_bus_address = g_getenv ("HOSTNAME");
    5272                 :          38 :           if (session_bus_address)
    5273                 :          38 :             timer_perturb = ABS ((gint) g_str_hash (session_bus_address)) % 1000000;
    5274                 :             :           else
    5275                 :           0 :             timer_perturb = 0;
    5276                 :           6 :         }
    5277                 :             : 
    5278                 :       24162 :       expiration = current_time + (guint64) timeout_source->interval * 1000 * 1000;
    5279                 :             : 
    5280                 :             :       /* We want the microseconds part of the timeout to land on the
    5281                 :             :        * 'timer_perturb' mark, but we need to make sure we don't try to
    5282                 :             :        * set the timeout in the past.  We do this by ensuring that we
    5283                 :             :        * always only *increase* the expiration time by adding a full
    5284                 :             :        * second in the case that the microsecond portion decreases.
    5285                 :             :        */
    5286                 :       24162 :       expiration -= timer_perturb;
    5287                 :             : 
    5288                 :       24162 :       remainder = expiration % 1000000;
    5289                 :       24162 :       if (remainder >= 1000000/4)
    5290                 :       18094 :         expiration += 1000000;
    5291                 :             : 
    5292                 :       24162 :       expiration -= remainder;
    5293                 :       24162 :       expiration += timer_perturb;
    5294                 :       12018 :     }
    5295                 :             :   else
    5296                 :             :     {
    5297                 :        9325 :       expiration = current_time + (guint64) timeout_source->interval * 1000;
    5298                 :             :     }
    5299                 :             : 
    5300                 :       33487 :   g_source_set_ready_time ((GSource *) timeout_source, expiration);
    5301                 :       33487 : }
    5302                 :             : 
    5303                 :             : static gboolean
    5304                 :        1116 : g_timeout_dispatch (GSource     *source,
    5305                 :             :                     GSourceFunc  callback,
    5306                 :             :                     gpointer     user_data)
    5307                 :             : {
    5308                 :        1116 :   GTimeoutSource *timeout_source = (GTimeoutSource *)source;
    5309                 :             :   gboolean again;
    5310                 :             : 
    5311                 :        1116 :   if (!callback)
    5312                 :             :     {
    5313                 :           0 :       g_warning ("Timeout source dispatched without callback. "
    5314                 :             :                  "You must call g_source_set_callback().");
    5315                 :           0 :       return FALSE;
    5316                 :             :     }
    5317                 :             : 
    5318                 :        1116 :   if (timeout_source->one_shot)
    5319                 :             :     {
    5320                 :          17 :       GSourceOnceFunc once_callback = (GSourceOnceFunc) callback;
    5321                 :          17 :       once_callback (user_data);
    5322                 :          17 :       again = G_SOURCE_REMOVE;
    5323                 :           8 :     }
    5324                 :             :   else
    5325                 :             :     {
    5326                 :        1099 :       again = callback (user_data);
    5327                 :             :     }
    5328                 :             : 
    5329                 :         938 :   TRACE (GLIB_TIMEOUT_DISPATCH (source, source->context, callback, user_data, again));
    5330                 :             : 
    5331                 :        1116 :   if (again)
    5332                 :         363 :     g_timeout_set_expiration (timeout_source, g_source_get_time (source));
    5333                 :             : 
    5334                 :        1116 :   return again;
    5335                 :         178 : }
    5336                 :             : 
    5337                 :             : static GSource *
    5338                 :       33124 : timeout_source_new (guint    interval,
    5339                 :             :                     gboolean seconds,
    5340                 :             :                     gboolean one_shot)
    5341                 :             : {
    5342                 :       33124 :   GSource *source = g_source_new (&g_timeout_funcs, sizeof (GTimeoutSource));
    5343                 :       33124 :   GTimeoutSource *timeout_source = (GTimeoutSource *)source;
    5344                 :             : 
    5345                 :       33124 :   timeout_source->interval = interval;
    5346                 :       33124 :   timeout_source->seconds = seconds;
    5347                 :       33124 :   timeout_source->one_shot = one_shot;
    5348                 :             : 
    5349                 :       33124 :   g_timeout_set_expiration (timeout_source, g_get_monotonic_time ());
    5350                 :             : 
    5351                 :       33124 :   return source;
    5352                 :             : }
    5353                 :             : 
    5354                 :             : /**
    5355                 :             :  * g_timeout_source_new:
    5356                 :             :  * @interval: the timeout interval in milliseconds
    5357                 :             :  * 
    5358                 :             :  * Creates a new timeout source.
    5359                 :             :  *
    5360                 :             :  * The source will not initially be associated with any [struct@GLib.MainContext]
    5361                 :             :  * and must be added to one with [method@GLib.Source.attach] before it will be
    5362                 :             :  * executed.
    5363                 :             :  *
    5364                 :             :  * The interval given is in terms of monotonic time, not wall clock
    5365                 :             :  * time.  See [func@GLib.get_monotonic_time].
    5366                 :             :  * 
    5367                 :             :  * Returns: (transfer full): the newly-created timeout source
    5368                 :             :  **/
    5369                 :             : GSource *
    5370                 :        8640 : g_timeout_source_new (guint interval)
    5371                 :             : {
    5372                 :        8640 :   return timeout_source_new (interval, FALSE, FALSE);
    5373                 :             : }
    5374                 :             : 
    5375                 :             : /**
    5376                 :             :  * g_timeout_source_new_seconds:
    5377                 :             :  * @interval: the timeout interval in seconds
    5378                 :             :  *
    5379                 :             :  * Creates a new timeout source.
    5380                 :             :  *
    5381                 :             :  * The source will not initially be associated with any
    5382                 :             :  * [struct@GLib.MainContext] and must be added to one with
    5383                 :             :  * [method@GLib.Source.attach] before it will be executed.
    5384                 :             :  *
    5385                 :             :  * The scheduling granularity/accuracy of this timeout source will be
    5386                 :             :  * in seconds.
    5387                 :             :  *
    5388                 :             :  * The interval given is in terms of monotonic time, not wall clock time.
    5389                 :             :  * See [func@GLib.get_monotonic_time].
    5390                 :             :  *
    5391                 :             :  * Returns: (transfer full): the newly-created timeout source
    5392                 :             :  * Since: 2.14
    5393                 :             :  **/
    5394                 :             : GSource *
    5395                 :       24029 : g_timeout_source_new_seconds (guint interval)
    5396                 :             : {
    5397                 :       24029 :   return timeout_source_new (interval, TRUE, FALSE);
    5398                 :             : }
    5399                 :             : 
    5400                 :             : static guint
    5401                 :         455 : timeout_add_full (gint           priority,
    5402                 :             :                   guint          interval,
    5403                 :             :                   gboolean       seconds,
    5404                 :             :                   gboolean       one_shot,
    5405                 :             :                   GSourceFunc    function,
    5406                 :             :                   gpointer       data,
    5407                 :             :                   GDestroyNotify notify)
    5408                 :             : {
    5409                 :             :   GSource *source;
    5410                 :             :   guint id;
    5411                 :             : 
    5412                 :         455 :   g_return_val_if_fail (function != NULL, 0);
    5413                 :             : 
    5414                 :         455 :   source = timeout_source_new (interval, seconds, one_shot);
    5415                 :             : 
    5416                 :         455 :   if (priority != G_PRIORITY_DEFAULT)
    5417                 :           2 :     g_source_set_priority (source, priority);
    5418                 :             : 
    5419                 :         455 :   g_source_set_callback (source, function, data, notify);
    5420                 :         455 :   id = g_source_attach (source, NULL);
    5421                 :             : 
    5422                 :         364 :   TRACE (GLIB_TIMEOUT_ADD (source, g_main_context_default (), id, priority, interval, function, data));
    5423                 :             : 
    5424                 :         455 :   g_source_unref (source);
    5425                 :             : 
    5426                 :         455 :   return id;
    5427                 :          91 : }
    5428                 :             : 
    5429                 :             : /**
    5430                 :             :  * g_timeout_add_full: (rename-to g_timeout_add)
    5431                 :             :  * @priority: the priority of the timeout source; typically this will be in
    5432                 :             :  *   the range between [const@GLib.PRIORITY_DEFAULT] and
    5433                 :             :  *   [const@GLib.PRIORITY_HIGH]
    5434                 :             :  * @interval: the time between calls to the function, in milliseconds
    5435                 :             :  * @function: function to call
    5436                 :             :  * @data: data to pass to @function
    5437                 :             :  * @notify: (nullable): function to call when the timeout is removed
    5438                 :             :  * 
    5439                 :             :  * Sets a function to be called at regular intervals, with the given
    5440                 :             :  * priority.
    5441                 :             :  *
    5442                 :             :  * The function is called repeatedly until it returns
    5443                 :             :  * [const@GLib.SOURCE_REMOVE], at which point the timeout is automatically
    5444                 :             :  * destroyed and
    5445                 :             :  * the function will not be called again.  The @notify function is
    5446                 :             :  * called when the timeout is destroyed.  The first call to the
    5447                 :             :  * function will be at the end of the first @interval.
    5448                 :             :  *
    5449                 :             :  * Note that timeout functions may be delayed, due to the processing of other
    5450                 :             :  * event sources. Thus they should not be relied on for precise timing.
    5451                 :             :  * After each call to the timeout function, the time of the next
    5452                 :             :  * timeout is recalculated based on the current time and the given interval
    5453                 :             :  * (it does not try to ‘catch up’ time lost in delays).
    5454                 :             :  *
    5455                 :             :  * See [main loop memory management](main-loop.html#memory-management-of-sources) for details
    5456                 :             :  * on how to handle the return value and memory management of @data.
    5457                 :             :  *
    5458                 :             :  * This internally creates a main loop source using
    5459                 :             :  * [func@GLib.timeout_source_new] and attaches it to the global
    5460                 :             :  * [struct@GLib.MainContext] using [method@GLib.Source.attach], so the callback
    5461                 :             :  * will be invoked in whichever thread is running that main context. You can do
    5462                 :             :  * these steps manually if you need greater control or to use a custom main
    5463                 :             :  * context.
    5464                 :             :  *
    5465                 :             :  * The interval given is in terms of monotonic time, not wall clock time.
    5466                 :             :  * See [func@GLib.get_monotonic_time].
    5467                 :             :  * 
    5468                 :             :  * Returns: the ID (greater than 0) of the event source
    5469                 :             :  **/
    5470                 :             : guint
    5471                 :         314 : g_timeout_add_full (gint           priority,
    5472                 :             :                     guint          interval,
    5473                 :             :                     GSourceFunc    function,
    5474                 :             :                     gpointer       data,
    5475                 :             :                     GDestroyNotify notify)
    5476                 :             : {
    5477                 :         314 :   return timeout_add_full (priority, interval, FALSE, FALSE, function, data, notify);
    5478                 :             : }
    5479                 :             : 
    5480                 :             : /**
    5481                 :             :  * g_timeout_add:
    5482                 :             :  * @interval: the time between calls to the function, in milliseconds
    5483                 :             :  * @function: function to call
    5484                 :             :  * @data: data to pass to @function
    5485                 :             :  *
    5486                 :             :  * Sets a function to be called at regular intervals, with the default
    5487                 :             :  * priority, [const@GLib.PRIORITY_DEFAULT].
    5488                 :             :  *
    5489                 :             :  * The given @function is called repeatedly until it returns
    5490                 :             :  * [const@GLib.SOURCE_REMOVE], at which point the timeout is
    5491                 :             :  * automatically destroyed and the function will not be called again. The first
    5492                 :             :  * call to the function will be at the end of the first @interval.
    5493                 :             :  *
    5494                 :             :  * Note that timeout functions may be delayed, due to the processing of other
    5495                 :             :  * event sources. Thus they should not be relied on for precise timing.
    5496                 :             :  * After each call to the timeout function, the time of the next
    5497                 :             :  * timeout is recalculated based on the current time and the given interval
    5498                 :             :  * (it does not try to ‘catch up’ time lost in delays).
    5499                 :             :  *
    5500                 :             :  * See [main loop memory management](main-loop.html#memory-management-of-sources) for details
    5501                 :             :  * on how to handle the return value and memory management of @data.
    5502                 :             :  *
    5503                 :             :  * If you want to have a timer in the ‘seconds’ range and do not care
    5504                 :             :  * about the exact time of the first call of the timer, use the
    5505                 :             :  * [func@GLib.timeout_add_seconds] function; this function allows for more
    5506                 :             :  * optimizations and more efficient system power usage.
    5507                 :             :  *
    5508                 :             :  * This internally creates a main loop source using
    5509                 :             :  * [func@GLib.timeout_source_new] and attaches it to the global
    5510                 :             :  * [struct@GLib.MainContext] using [method@GLib.Source.attach], so the callback
    5511                 :             :  * will be invoked in whichever thread is running that main context. You can do
    5512                 :             :  * these steps manually if you need greater control or to use a custom main
    5513                 :             :  * context.
    5514                 :             :  *
    5515                 :             :  * It is safe to call this function from any thread.
    5516                 :             :  *
    5517                 :             :  * The interval given is in terms of monotonic time, not wall clock
    5518                 :             :  * time. See [func@GLib.get_monotonic_time].
    5519                 :             :  *
    5520                 :             :  * Returns: the ID (greater than 0) of the event source
    5521                 :             :  **/
    5522                 :             : guint
    5523                 :         312 : g_timeout_add (guint32        interval,
    5524                 :             :                GSourceFunc    function,
    5525                 :             :                gpointer       data)
    5526                 :             : {
    5527                 :         312 :   return g_timeout_add_full (G_PRIORITY_DEFAULT, 
    5528                 :          69 :                              interval, function, data, NULL);
    5529                 :             : }
    5530                 :             : 
    5531                 :             : /**
    5532                 :             :  * g_timeout_add_once:
    5533                 :             :  * @interval: the time after which the function will be called, in milliseconds
    5534                 :             :  * @function: function to call
    5535                 :             :  * @data: data to pass to @function
    5536                 :             :  *
    5537                 :             :  * Sets a function to be called after @interval milliseconds have elapsed,
    5538                 :             :  * with the default priority, [const@GLib.PRIORITY_DEFAULT].
    5539                 :             :  *
    5540                 :             :  * The given @function is called once and then the source will be automatically
    5541                 :             :  * removed from the main context.
    5542                 :             :  *
    5543                 :             :  * This function otherwise behaves like [func@GLib.timeout_add].
    5544                 :             :  *
    5545                 :             :  * Returns: the ID (greater than 0) of the event source
    5546                 :             :  * Since: 2.74
    5547                 :             :  */
    5548                 :             : guint
    5549                 :          28 : g_timeout_add_once (guint32         interval,
    5550                 :             :                     GSourceOnceFunc function,
    5551                 :             :                     gpointer        data)
    5552                 :             : {
    5553                 :          28 :   return timeout_add_full (G_PRIORITY_DEFAULT, interval, FALSE, TRUE, (GSourceFunc) function, data, NULL);
    5554                 :             : }
    5555                 :             : 
    5556                 :             : /**
    5557                 :             :  * g_timeout_add_seconds_full: (rename-to g_timeout_add_seconds)
    5558                 :             :  * @priority: the priority of the timeout source; typically this will be in
    5559                 :             :  *   the range between [const@GLib.PRIORITY_DEFAULT] and
    5560                 :             :  *   [const@GLib.PRIORITY_HIGH]
    5561                 :             :  * @interval: the time between calls to the function, in seconds
    5562                 :             :  * @function: function to call
    5563                 :             :  * @data: data to pass to @function
    5564                 :             :  * @notify: (nullable): function to call when the timeout is removed
    5565                 :             :  *
    5566                 :             :  * Sets a function to be called at regular intervals, with @priority.
    5567                 :             :  *
    5568                 :             :  * The function is called repeatedly until it returns [const@GLib.SOURCE_REMOVE],
    5569                 :             :  * at which point the timeout is automatically destroyed and
    5570                 :             :  * the function will not be called again.
    5571                 :             :  *
    5572                 :             :  * Unlike [func@GLib.timeout_add], this function operates at whole second
    5573                 :             :  * granularity. The initial starting point of the timer is determined by the
    5574                 :             :  * implementation and the implementation is expected to group multiple timers
    5575                 :             :  * together so that they fire all at the same time. To allow this grouping,
    5576                 :             :  * the @interval to the first timer is rounded and can deviate up to one second
    5577                 :             :  * from the specified interval. Subsequent timer iterations will generally run
    5578                 :             :  * at the specified interval.
    5579                 :             :  *
    5580                 :             :  * Note that timeout functions may be delayed, due to the processing of other
    5581                 :             :  * event sources. Thus they should not be relied on for precise timing.
    5582                 :             :  * After each call to the timeout function, the time of the next
    5583                 :             :  * timeout is recalculated based on the current time and the given @interval
    5584                 :             :  *
    5585                 :             :  * See [main loop memory management](main-loop.html#memory-management-of-sources) for details
    5586                 :             :  * on how to handle the return value and memory management of @data.
    5587                 :             :  *
    5588                 :             :  * If you want timing more precise than whole seconds, use
    5589                 :             :  * [func@GLib.timeout_add] instead.
    5590                 :             :  *
    5591                 :             :  * The grouping of timers to fire at the same time results in a more power
    5592                 :             :  * and CPU efficient behavior so if your timer is in multiples of seconds
    5593                 :             :  * and you don’t require the first timer exactly one second from now, the
    5594                 :             :  * use of [func@GLib.timeout_add_seconds] is preferred over
    5595                 :             :  * [func@GLib.timeout_add].
    5596                 :             :  *
    5597                 :             :  * This internally creates a main loop source using
    5598                 :             :  * [func@GLib.timeout_source_new_seconds] and attaches it to the main loop
    5599                 :             :  * context using [method@GLib.Source.attach]. You can do these steps manually
    5600                 :             :  * if you need greater control.
    5601                 :             :  *
    5602                 :             :  * It is safe to call this function from any thread.
    5603                 :             :  *
    5604                 :             :  * The interval given is in terms of monotonic time, not wall clock
    5605                 :             :  * time. See [func@GLib.get_monotonic_time].
    5606                 :             :  *
    5607                 :             :  * Returns: the ID (greater than 0) of the event source
    5608                 :             :  * Since: 2.14
    5609                 :             :  **/
    5610                 :             : guint
    5611                 :          78 : g_timeout_add_seconds_full (gint           priority,
    5612                 :             :                             guint32        interval,
    5613                 :             :                             GSourceFunc    function,
    5614                 :             :                             gpointer       data,
    5615                 :             :                             GDestroyNotify notify)
    5616                 :             : {
    5617                 :          78 :   return timeout_add_full (priority, interval, TRUE, FALSE, function, data, notify);
    5618                 :             : }
    5619                 :             : 
    5620                 :             : /**
    5621                 :             :  * g_timeout_add_seconds:
    5622                 :             :  * @interval: the time between calls to the function, in seconds
    5623                 :             :  * @function: function to call
    5624                 :             :  * @data: data to pass to @function
    5625                 :             :  *
    5626                 :             :  * Sets a function to be called at regular intervals with the default
    5627                 :             :  * priority, [const@GLib.PRIORITY_DEFAULT].
    5628                 :             :  *
    5629                 :             :  * The function is called repeatedly until it returns [const@GLib.SOURCE_REMOVE],
    5630                 :             :  * at which point the timeout is automatically destroyed
    5631                 :             :  * and the function will not be called again.
    5632                 :             :  *
    5633                 :             :  * This internally creates a main loop source using
    5634                 :             :  * [func@GLib.timeout_source_new_seconds] and attaches it to the main loop context
    5635                 :             :  * using [method@GLib.Source.attach]. You can do these steps manually if you need
    5636                 :             :  * greater control. Also see [func@GLib.timeout_add_seconds_full].
    5637                 :             :  *
    5638                 :             :  * It is safe to call this function from any thread.
    5639                 :             :  *
    5640                 :             :  * Note that the first call of the timer may not be precise for timeouts
    5641                 :             :  * of one second. If you need finer precision and have such a timeout,
    5642                 :             :  * you may want to use [func@GLib.timeout_add] instead.
    5643                 :             :  *
    5644                 :             :  * See [main loop memory management](main-loop.html#memory-management-of-sources) for details
    5645                 :             :  * on how to handle the return value and memory management of @data.
    5646                 :             :  *
    5647                 :             :  * The interval given is in terms of monotonic time, not wall clock
    5648                 :             :  * time. See [func@GLib.get_monotonic_time].
    5649                 :             :  * 
    5650                 :             :  * Returns: the ID (greater than 0) of the event source
    5651                 :             :  * Since: 2.14
    5652                 :             :  **/
    5653                 :             : guint
    5654                 :          78 : g_timeout_add_seconds (guint       interval,
    5655                 :             :                        GSourceFunc function,
    5656                 :             :                        gpointer    data)
    5657                 :             : {
    5658                 :          78 :   g_return_val_if_fail (function != NULL, 0);
    5659                 :             : 
    5660                 :          78 :   return g_timeout_add_seconds_full (G_PRIORITY_DEFAULT, interval, function, data, NULL);
    5661                 :           5 : }
    5662                 :             : 
    5663                 :             : /**
    5664                 :             :  * g_timeout_add_seconds_once:
    5665                 :             :  * @interval: the time after which the function will be called, in seconds
    5666                 :             :  * @function: function to call
    5667                 :             :  * @data: data to pass to @function
    5668                 :             :  *
    5669                 :             :  * This function behaves like [func@GLib.timeout_add_once] but with a range in
    5670                 :             :  * seconds.
    5671                 :             :  *
    5672                 :             :  * Returns: the ID (greater than 0) of the event source
    5673                 :             :  * Since: 2.78
    5674                 :             :  */
    5675                 :             : guint
    5676                 :          35 : g_timeout_add_seconds_once (guint           interval,
    5677                 :             :                             GSourceOnceFunc function,
    5678                 :             :                             gpointer        data)
    5679                 :             : {
    5680                 :          35 :   return timeout_add_full (G_PRIORITY_DEFAULT, interval, TRUE, TRUE, (GSourceFunc) function, data, NULL);
    5681                 :             : }
    5682                 :             : 
    5683                 :             : /* Child watch functions */
    5684                 :             : 
    5685                 :             : #ifdef HAVE_PIDFD
    5686                 :             : static int
    5687                 :         581 : siginfo_t_to_wait_status (const siginfo_t *info)
    5688                 :             : {
    5689                 :             :   /* Each of these returns is essentially the inverse of WIFEXITED(),
    5690                 :             :    * WIFSIGNALED(), etc. */
    5691                 :         581 :   switch (info->si_code)
    5692                 :             :     {
    5693                 :         574 :     case CLD_EXITED:
    5694                 :         574 :       return W_EXITCODE (info->si_status, 0);
    5695                 :           7 :     case CLD_KILLED:
    5696                 :           7 :       return W_EXITCODE (0, info->si_status);
    5697                 :           0 :     case CLD_DUMPED:
    5698                 :           0 :       return W_EXITCODE (0, info->si_status | WCOREFLAG);
    5699                 :           0 :     case CLD_CONTINUED:
    5700                 :           0 :       return __W_CONTINUED;
    5701                 :           0 :     case CLD_STOPPED:
    5702                 :             :     case CLD_TRAPPED:
    5703                 :             :     default:
    5704                 :           0 :       return W_STOPCODE (info->si_status);
    5705                 :             :     }
    5706                 :             : }
    5707                 :             : #endif /* HAVE_PIDFD */
    5708                 :             : 
    5709                 :             : static gboolean
    5710                 :        6526 : g_child_watch_prepare (GSource *source,
    5711                 :             :                        gint    *timeout)
    5712                 :             : {
    5713                 :             : #ifdef G_OS_WIN32
    5714                 :        2003 :   return FALSE;
    5715                 :             : #else  /* G_OS_WIN32 */
    5716                 :             :   {
    5717                 :             :     GChildWatchSource *child_watch_source;
    5718                 :             : 
    5719                 :        4523 :     child_watch_source = (GChildWatchSource *) source;
    5720                 :             : 
    5721                 :        4523 :     if (child_watch_source->poll.fd >= 0)
    5722                 :        4523 :       return FALSE;
    5723                 :             : 
    5724                 :           0 :     return g_atomic_int_get (&child_watch_source->child_maybe_exited);
    5725                 :             :   }
    5726                 :             : #endif /* G_OS_WIN32 */
    5727                 :             : }
    5728                 :             : 
    5729                 :             : static gboolean
    5730                 :        6485 : g_child_watch_check (GSource *source)
    5731                 :             : {
    5732                 :             :   GChildWatchSource *child_watch_source;
    5733                 :             :   gboolean child_exited;
    5734                 :             : 
    5735                 :        6485 :   child_watch_source = (GChildWatchSource *) source;
    5736                 :             : 
    5737                 :             : #ifdef G_OS_WIN32
    5738                 :        1973 :   child_exited = !!(child_watch_source->poll.revents & G_IO_IN);
    5739                 :             : #else /* G_OS_WIN32 */
    5740                 :             : #ifdef HAVE_PIDFD
    5741                 :        4512 :   if (child_watch_source->poll.fd >= 0)
    5742                 :             :     {
    5743                 :        4512 :       child_exited = !!(child_watch_source->poll.revents & G_IO_IN);
    5744                 :        4512 :       return child_exited;
    5745                 :             :     }
    5746                 :             : #endif /* HAVE_PIDFD */
    5747                 :           0 :   child_exited = g_atomic_int_get (&child_watch_source->child_maybe_exited);
    5748                 :             : #endif /* G_OS_WIN32 */
    5749                 :             : 
    5750                 :        1973 :   return child_exited;
    5751                 :             : }
    5752                 :             : 
    5753                 :             : static void
    5754                 :         927 : g_child_watch_finalize (GSource *source)
    5755                 :             : {
    5756                 :             : #ifndef G_OS_WIN32
    5757                 :         581 :   GChildWatchSource *child_watch_source = (GChildWatchSource *) source;
    5758                 :             : 
    5759                 :         581 :   if (child_watch_source->poll.fd >= 0)
    5760                 :             :     {
    5761                 :         581 :       close (child_watch_source->poll.fd);
    5762                 :         581 :       return;
    5763                 :             :     }
    5764                 :             : 
    5765                 :           0 :   G_LOCK (unix_signal_lock);
    5766                 :           0 :   unix_child_watches = g_slist_remove (unix_child_watches, source);
    5767                 :           0 :   unref_unix_signal_handler_unlocked (SIGCHLD);
    5768                 :           0 :   G_UNLOCK (unix_signal_lock);
    5769                 :             : #endif /* G_OS_WIN32 */
    5770                 :         346 : }
    5771                 :             : 
    5772                 :             : #ifndef G_OS_WIN32
    5773                 :             : 
    5774                 :             : static void
    5775                 :          32 : wake_source (GSource *source)
    5776                 :             : {
    5777                 :             :   GMainContext *context;
    5778                 :             : 
    5779                 :             :   /* This should be thread-safe:
    5780                 :             :    *
    5781                 :             :    *  - if the source is currently being added to a context, that
    5782                 :             :    *    context will be woken up anyway
    5783                 :             :    *
    5784                 :             :    *  - if the source is currently being destroyed, we simply need not
    5785                 :             :    *    to crash:
    5786                 :             :    *
    5787                 :             :    *    - the memory for the source will remain valid until after the
    5788                 :             :    *      source finalize function was called (which would remove the
    5789                 :             :    *      source from the global list which we are currently holding the
    5790                 :             :    *      lock for)
    5791                 :             :    *
    5792                 :             :    *    - the GMainContext will either be NULL or point to a live
    5793                 :             :    *      GMainContext
    5794                 :             :    *
    5795                 :             :    *    - the GMainContext will remain valid since source_dup_main_context()
    5796                 :             :    *      gave us a ref or NULL
    5797                 :             :    *
    5798                 :             :    *  Since we are holding a lot of locks here, don't try to enter any
    5799                 :             :    *  more GMainContext functions for fear of dealock -- just hit the
    5800                 :             :    *  GWakeup and run.  Even if that's safe now, it could easily become
    5801                 :             :    *  unsafe with some very minor changes in the future, and signal
    5802                 :             :    *  handling is not the most well-tested codepath.
    5803                 :             :    */
    5804                 :          32 :   context = source_dup_main_context (source);
    5805                 :          32 :   if (context)
    5806                 :          32 :     g_wakeup_signal (context->wakeup);
    5807                 :             : 
    5808                 :          32 :   if (context)
    5809                 :          32 :     g_main_context_unref (context);
    5810                 :          32 : }
    5811                 :             : 
    5812                 :             : static void
    5813                 :          54 : dispatch_unix_signals_unlocked (void)
    5814                 :             : {
    5815                 :             :   gboolean pending[NSIG];
    5816                 :             :   GSList *node;
    5817                 :             :   gint i;
    5818                 :             : 
    5819                 :             :   /* clear this first in case another one arrives while we're processing */
    5820                 :          54 :   g_atomic_int_set (&any_unix_signal_pending, 0);
    5821                 :             : 
    5822                 :             :   /* We atomically test/clear the bit from the global array in case
    5823                 :             :    * other signals arrive while we are dispatching.
    5824                 :             :    *
    5825                 :             :    * We then can safely use our own array below without worrying about
    5826                 :             :    * races.
    5827                 :             :    */
    5828                 :        3564 :   for (i = 0; i < NSIG; i++)
    5829                 :             :     {
    5830                 :             :       /* Be very careful with (the volatile) unix_signal_pending.
    5831                 :             :        *
    5832                 :             :        * We must ensure that it's not possible that we clear it without
    5833                 :             :        * handling the signal.  We therefore must ensure that our pending
    5834                 :             :        * array has a field set (ie: we will do something about the
    5835                 :             :        * signal) before we clear the item in unix_signal_pending.
    5836                 :             :        *
    5837                 :             :        * Note specifically: we must check _our_ array.
    5838                 :             :        */
    5839                 :        3510 :       pending[i] = g_atomic_int_compare_and_exchange (&unix_signal_pending[i], 1, 0);
    5840                 :             :     }
    5841                 :             : 
    5842                 :             :   /* handle GChildWatchSource instances */
    5843                 :          54 :   if (pending[SIGCHLD])
    5844                 :             :     {
    5845                 :             :       /* The only way we can do this is to scan all of the children.
    5846                 :             :        *
    5847                 :             :        * The docs promise that we will not reap children that we are not
    5848                 :             :        * explicitly watching, so that ties our hands from calling
    5849                 :             :        * waitpid(-1).  We also can't use siginfo's si_pid field since if
    5850                 :             :        * multiple SIGCHLD arrive at the same time, one of them can be
    5851                 :             :        * dropped (since a given UNIX signal can only be pending once).
    5852                 :             :        */
    5853                 :           0 :       for (node = unix_child_watches; node; node = node->next)
    5854                 :             :         {
    5855                 :           0 :           GChildWatchSource *source = node->data;
    5856                 :             : 
    5857                 :           0 :           if (g_atomic_int_compare_and_exchange (&source->child_maybe_exited, FALSE, TRUE))
    5858                 :           0 :             wake_source ((GSource *) source);
    5859                 :             :         }
    5860                 :             :     }
    5861                 :             : 
    5862                 :             :   /* handle GUnixSignalWatchSource instances */
    5863                 :         128 :   for (node = unix_signal_watches; node; node = node->next)
    5864                 :             :     {
    5865                 :          74 :       GUnixSignalWatchSource *source = node->data;
    5866                 :             : 
    5867                 :          74 :       if (pending[source->signum] &&
    5868                 :          32 :           g_atomic_int_compare_and_exchange (&source->pending, FALSE, TRUE))
    5869                 :             :         {
    5870                 :          32 :           wake_source ((GSource *) source);
    5871                 :             :         }
    5872                 :             :     }
    5873                 :             : 
    5874                 :          54 : }
    5875                 :             : 
    5876                 :             : static void
    5877                 :          22 : dispatch_unix_signals (void)
    5878                 :             : {
    5879                 :          22 :   G_LOCK(unix_signal_lock);
    5880                 :          22 :   dispatch_unix_signals_unlocked ();
    5881                 :          22 :   G_UNLOCK(unix_signal_lock);
    5882                 :          22 : }
    5883                 :             : 
    5884                 :             : static gboolean
    5885                 :          57 : g_unix_signal_watch_prepare (GSource *source,
    5886                 :             :                              gint    *timeout)
    5887                 :             : {
    5888                 :             :   GUnixSignalWatchSource *unix_signal_source;
    5889                 :             : 
    5890                 :          57 :   unix_signal_source = (GUnixSignalWatchSource *) source;
    5891                 :             : 
    5892                 :          57 :   return g_atomic_int_get (&unix_signal_source->pending);
    5893                 :             : }
    5894                 :             : 
    5895                 :             : static gboolean
    5896                 :          53 : g_unix_signal_watch_check (GSource  *source)
    5897                 :             : {
    5898                 :             :   GUnixSignalWatchSource *unix_signal_source;
    5899                 :             : 
    5900                 :          53 :   unix_signal_source = (GUnixSignalWatchSource *) source;
    5901                 :             : 
    5902                 :          53 :   return g_atomic_int_get (&unix_signal_source->pending);
    5903                 :             : }
    5904                 :             : 
    5905                 :             : static gboolean
    5906                 :          32 : g_unix_signal_watch_dispatch (GSource    *source, 
    5907                 :             :                               GSourceFunc callback,
    5908                 :             :                               gpointer    user_data)
    5909                 :             : {
    5910                 :             :   GUnixSignalWatchSource *unix_signal_source;
    5911                 :             :   gboolean again;
    5912                 :             : 
    5913                 :          32 :   unix_signal_source = (GUnixSignalWatchSource *) source;
    5914                 :             : 
    5915                 :          32 :   if (!callback)
    5916                 :             :     {
    5917                 :           0 :       g_warning ("Unix signal source dispatched without callback. "
    5918                 :             :                  "You must call g_source_set_callback().");
    5919                 :           0 :       return FALSE;
    5920                 :             :     }
    5921                 :             : 
    5922                 :          32 :   g_atomic_int_set (&unix_signal_source->pending, FALSE);
    5923                 :             : 
    5924                 :          32 :   again = (callback) (user_data);
    5925                 :             : 
    5926                 :          32 :   return again;
    5927                 :             : }
    5928                 :             : 
    5929                 :             : static void
    5930                 :          32 : ref_unix_signal_handler_unlocked (int signum)
    5931                 :             : {
    5932                 :             :   /* Ensure we have the worker context */
    5933                 :          32 :   g_get_worker_context ();
    5934                 :          32 :   unix_signal_refcount[signum]++;
    5935                 :          32 :   if (unix_signal_refcount[signum] == 1)
    5936                 :             :     {
    5937                 :             :       struct sigaction action;
    5938                 :          22 :       action.sa_handler = g_unix_signal_handler;
    5939                 :          22 :       sigemptyset (&action.sa_mask);
    5940                 :             : #ifdef SA_RESTART
    5941                 :          22 :       action.sa_flags = SA_RESTART | SA_NOCLDSTOP;
    5942                 :             : #else
    5943                 :             :       action.sa_flags = SA_NOCLDSTOP;
    5944                 :             : #endif
    5945                 :             : #ifdef SA_ONSTACK
    5946                 :          22 :       action.sa_flags |= SA_ONSTACK;
    5947                 :             : #endif
    5948                 :          22 :       sigaction (signum, &action, NULL);
    5949                 :             :     }
    5950                 :          32 : }
    5951                 :             : 
    5952                 :             : static void
    5953                 :          32 : unref_unix_signal_handler_unlocked (int signum)
    5954                 :             : {
    5955                 :          32 :   unix_signal_refcount[signum]--;
    5956                 :          32 :   if (unix_signal_refcount[signum] == 0)
    5957                 :             :     {
    5958                 :             :       struct sigaction action;
    5959                 :          22 :       memset (&action, 0, sizeof (action));
    5960                 :          22 :       action.sa_handler = SIG_DFL;
    5961                 :          22 :       sigemptyset (&action.sa_mask);
    5962                 :          22 :       sigaction (signum, &action, NULL);
    5963                 :             :     }
    5964                 :          32 : }
    5965                 :             : 
    5966                 :             : /* Return a const string to avoid allocations. We lose precision in the case the
    5967                 :             :  * @signum is unrecognised, but that’ll do. */
    5968                 :             : static const gchar *
    5969                 :          32 : signum_to_string (int signum)
    5970                 :             : {
    5971                 :             :   /* See `man 0P signal.h` */
    5972                 :             : #define SIGNAL(s) \
    5973                 :             :     case (s): \
    5974                 :             :       return ("GUnixSignalSource: " #s);
    5975                 :          32 :   switch (signum)
    5976                 :             :     {
    5977                 :             :     /* These signals are guaranteed to exist by POSIX. */
    5978                 :           0 :     SIGNAL (SIGABRT)
    5979                 :           0 :     SIGNAL (SIGFPE)
    5980                 :           0 :     SIGNAL (SIGILL)
    5981                 :           0 :     SIGNAL (SIGINT)
    5982                 :           0 :     SIGNAL (SIGSEGV)
    5983                 :           9 :     SIGNAL (SIGTERM)
    5984                 :             :     /* Frustratingly, these are not, and hence for brevity the list is
    5985                 :             :      * incomplete. */
    5986                 :             : #ifdef SIGALRM
    5987                 :           0 :     SIGNAL (SIGALRM)
    5988                 :             : #endif
    5989                 :             : #ifdef SIGCHLD
    5990                 :           0 :     SIGNAL (SIGCHLD)
    5991                 :             : #endif
    5992                 :             : #ifdef SIGHUP
    5993                 :          21 :     SIGNAL (SIGHUP)
    5994                 :             : #endif
    5995                 :             : #ifdef SIGKILL
    5996                 :           0 :     SIGNAL (SIGKILL)
    5997                 :             : #endif
    5998                 :             : #ifdef SIGPIPE
    5999                 :           0 :     SIGNAL (SIGPIPE)
    6000                 :             : #endif
    6001                 :             : #ifdef SIGQUIT
    6002                 :           0 :     SIGNAL (SIGQUIT)
    6003                 :             : #endif
    6004                 :             : #ifdef SIGSTOP
    6005                 :           0 :     SIGNAL (SIGSTOP)
    6006                 :             : #endif
    6007                 :             : #ifdef SIGUSR1
    6008                 :           1 :     SIGNAL (SIGUSR1)
    6009                 :             : #endif
    6010                 :             : #ifdef SIGUSR2
    6011                 :           0 :     SIGNAL (SIGUSR2)
    6012                 :             : #endif
    6013                 :             : #ifdef SIGPOLL
    6014                 :           0 :     SIGNAL (SIGPOLL)
    6015                 :             : #endif
    6016                 :             : #ifdef SIGPROF
    6017                 :           0 :     SIGNAL (SIGPROF)
    6018                 :             : #endif
    6019                 :             : #ifdef SIGTRAP
    6020                 :           0 :     SIGNAL (SIGTRAP)
    6021                 :             : #endif
    6022                 :           1 :     default:
    6023                 :           1 :       return "GUnixSignalSource: Unrecognized signal";
    6024                 :             :     }
    6025                 :             : #undef SIGNAL
    6026                 :             : }
    6027                 :             : 
    6028                 :             : GSource *
    6029                 :          32 : _g_main_create_unix_signal_watch (int signum)
    6030                 :             : {
    6031                 :             :   GSource *source;
    6032                 :             :   GUnixSignalWatchSource *unix_signal_source;
    6033                 :             : 
    6034                 :          32 :   source = g_source_new (&g_unix_signal_funcs, sizeof (GUnixSignalWatchSource));
    6035                 :          32 :   unix_signal_source = (GUnixSignalWatchSource *) source;
    6036                 :             : 
    6037                 :          32 :   unix_signal_source->signum = signum;
    6038                 :          32 :   unix_signal_source->pending = FALSE;
    6039                 :             : 
    6040                 :             :   /* Set a default name on the source, just in case the caller does not. */
    6041                 :          32 :   g_source_set_static_name (source, signum_to_string (signum));
    6042                 :             : 
    6043                 :          32 :   G_LOCK (unix_signal_lock);
    6044                 :          32 :   ref_unix_signal_handler_unlocked (signum);
    6045                 :          32 :   unix_signal_watches = g_slist_prepend (unix_signal_watches, unix_signal_source);
    6046                 :          32 :   dispatch_unix_signals_unlocked ();
    6047                 :          32 :   G_UNLOCK (unix_signal_lock);
    6048                 :             : 
    6049                 :          32 :   return source;
    6050                 :             : }
    6051                 :             : 
    6052                 :             : static void
    6053                 :          32 : g_unix_signal_watch_finalize (GSource    *source)
    6054                 :             : {
    6055                 :             :   GUnixSignalWatchSource *unix_signal_source;
    6056                 :             : 
    6057                 :          32 :   unix_signal_source = (GUnixSignalWatchSource *) source;
    6058                 :             : 
    6059                 :          32 :   G_LOCK (unix_signal_lock);
    6060                 :          32 :   unref_unix_signal_handler_unlocked (unix_signal_source->signum);
    6061                 :          32 :   unix_signal_watches = g_slist_remove (unix_signal_watches, source);
    6062                 :          32 :   G_UNLOCK (unix_signal_lock);
    6063                 :          32 : }
    6064                 :             : 
    6065                 :             : #endif /* G_OS_WIN32 */
    6066                 :             : 
    6067                 :             : static gboolean
    6068                 :         928 : g_child_watch_dispatch (GSource    *source, 
    6069                 :             :                         GSourceFunc callback,
    6070                 :             :                         gpointer    user_data)
    6071                 :             : {
    6072                 :             :   GChildWatchSource *child_watch_source;
    6073                 :         928 :   GChildWatchFunc child_watch_callback = (GChildWatchFunc) callback;
    6074                 :             :   int wait_status;
    6075                 :             : 
    6076                 :         928 :   child_watch_source = (GChildWatchSource *) source;
    6077                 :             : 
    6078                 :             :   /* We only (try to) reap the child process right before dispatching the callback.
    6079                 :             :    * That way, the caller can rely that the process is there until the callback
    6080                 :             :    * is invoked; or, if the caller calls g_source_destroy() without the callback
    6081                 :             :    * being dispatched, the process is still not reaped. */
    6082                 :             : 
    6083                 :             : #ifdef G_OS_WIN32
    6084                 :             :   {
    6085                 :             :     DWORD child_status;
    6086                 :             : 
    6087                 :             :     /*
    6088                 :             :      * Note: We do _not_ check for the special value of STILL_ACTIVE
    6089                 :             :      * since we know that the process has exited and doing so runs into
    6090                 :             :      * problems if the child process "happens to return STILL_ACTIVE(259)"
    6091                 :             :      * as Microsoft's Platform SDK puts it.
    6092                 :             :      */
    6093                 :         347 :     if (!GetExitCodeProcess (child_watch_source->pid, &child_status))
    6094                 :             :       {
    6095                 :           0 :         gchar *emsg = g_win32_error_message (GetLastError ());
    6096                 :           0 :         g_warning (G_STRLOC ": GetExitCodeProcess() failed: %s", emsg);
    6097                 :           0 :         g_free (emsg);
    6098                 :             : 
    6099                 :             :         /* Unknown error. We got signaled that the process might be exited,
    6100                 :             :          * but now we failed to reap it? Assume the process is gone and proceed. */
    6101                 :           0 :         wait_status = -1;
    6102                 :           0 :       }
    6103                 :             :     else
    6104                 :         347 :       wait_status = child_status;
    6105                 :             :   }
    6106                 :             : #else /* G_OS_WIN32 */
    6107                 :             :   {
    6108                 :         581 :     gboolean child_exited = FALSE;
    6109                 :             : 
    6110                 :         581 :     wait_status = -1;
    6111                 :             : 
    6112                 :             : #ifdef HAVE_PIDFD
    6113                 :         581 :     if (child_watch_source->poll.fd >= 0)
    6114                 :             :       {
    6115                 :         581 :         siginfo_t child_info = {
    6116                 :             :           0,
    6117                 :             :         };
    6118                 :             : 
    6119                 :             :         /* Get the exit status */
    6120                 :         581 :         if (waitid (P_PIDFD, child_watch_source->poll.fd, &child_info, WEXITED | WNOHANG) >= 0)
    6121                 :             :           {
    6122                 :         581 :             if (child_info.si_pid != 0)
    6123                 :             :               {
    6124                 :             :                 /* waitid() helpfully provides the wait status in a decomposed
    6125                 :             :                  * form which is quite useful. Unfortunately we have to report it
    6126                 :             :                  * to the #GChildWatchFunc as a waitpid()-style platform-specific
    6127                 :             :                  * wait status, so that the user code in #GChildWatchFunc can then
    6128                 :             :                  * call WIFEXITED() (etc.) on it. That means re-composing the
    6129                 :             :                  * status information. */
    6130                 :         581 :                 wait_status = siginfo_t_to_wait_status (&child_info);
    6131                 :         581 :                 child_exited = TRUE;
    6132                 :             :               }
    6133                 :             :             else
    6134                 :             :               {
    6135                 :           0 :                 g_debug (G_STRLOC ": pidfd signaled but pid %" G_PID_FORMAT " didn't exit",
    6136                 :             :                          child_watch_source->pid);
    6137                 :           0 :                 return TRUE;
    6138                 :             :               }
    6139                 :             :           }
    6140                 :             :         else
    6141                 :             :           {
    6142                 :           0 :             int errsv = errno;
    6143                 :             : 
    6144                 :           0 :             g_warning (G_STRLOC ": waitid(pid:%" G_PID_FORMAT ", pidfd=%d) failed: %s (%d). %s",
    6145                 :             :                        child_watch_source->pid, child_watch_source->poll.fd, g_strerror (errsv), errsv,
    6146                 :             :                        "See documentation of g_child_watch_source_new() for possible causes.");
    6147                 :             : 
    6148                 :             :             /* Assume the process is gone and proceed. */
    6149                 :           0 :             child_exited = TRUE;
    6150                 :             :           }
    6151                 :             :       }
    6152                 :             : #endif /* HAVE_PIDFD*/
    6153                 :             : 
    6154                 :         581 :     if (!child_exited)
    6155                 :             :       {
    6156                 :             :         pid_t pid;
    6157                 :             :         int wstatus;
    6158                 :             : 
    6159                 :           0 :       waitpid_again:
    6160                 :             : 
    6161                 :             :         /* We must reset the flag before waitpid(). Otherwise, there would be a
    6162                 :             :          * race. */
    6163                 :           0 :         g_atomic_int_set (&child_watch_source->child_maybe_exited, FALSE);
    6164                 :             : 
    6165                 :           0 :         pid = waitpid (child_watch_source->pid, &wstatus, WNOHANG);
    6166                 :             : 
    6167                 :           0 :         if (G_UNLIKELY (pid < 0 && errno == EINTR))
    6168                 :           0 :           goto waitpid_again;
    6169                 :             : 
    6170                 :           0 :         if (pid == 0)
    6171                 :             :           {
    6172                 :             :             /* Not exited yet. Wait longer. */
    6173                 :           0 :             return TRUE;
    6174                 :             :           }
    6175                 :             : 
    6176                 :           0 :         if (pid > 0)
    6177                 :           0 :           wait_status = wstatus;
    6178                 :             :         else
    6179                 :             :           {
    6180                 :           0 :             int errsv = errno;
    6181                 :             : 
    6182                 :           0 :             g_warning (G_STRLOC ": waitpid(pid:%" G_PID_FORMAT ") failed: %s (%d). %s",
    6183                 :             :                        child_watch_source->pid, g_strerror (errsv), errsv,
    6184                 :             :                        "See documentation of g_child_watch_source_new() for possible causes.");
    6185                 :             : 
    6186                 :             :             /* Assume the process is gone and proceed. */
    6187                 :             :           }
    6188                 :             :       }
    6189                 :             :   }
    6190                 :             : #endif /* G_OS_WIN32 */
    6191                 :             : 
    6192                 :         928 :   if (!callback)
    6193                 :             :     {
    6194                 :           0 :       g_warning ("Child watch source dispatched without callback. "
    6195                 :             :                  "You must call g_source_set_callback().");
    6196                 :           0 :       return FALSE;
    6197                 :             :     }
    6198                 :             : 
    6199                 :         928 :   (child_watch_callback) (child_watch_source->pid, wait_status, user_data);
    6200                 :             : 
    6201                 :             :   /* We never keep a child watch source around as the child is gone */
    6202                 :         928 :   return FALSE;
    6203                 :         347 : }
    6204                 :             : 
    6205                 :             : #ifndef G_OS_WIN32
    6206                 :             : 
    6207                 :             : static void
    6208                 :          22 : g_unix_signal_handler (int signum)
    6209                 :             : {
    6210                 :          22 :   gint saved_errno = errno;
    6211                 :             : 
    6212                 :             : #if defined(G_ATOMIC_LOCK_FREE) && defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4)
    6213                 :          22 :   g_atomic_int_set (&unix_signal_pending[signum], 1);
    6214                 :          22 :   g_atomic_int_set (&any_unix_signal_pending, 1);
    6215                 :             : #else
    6216                 :             : #warning "Can't use atomics in g_unix_signal_handler(): Unix signal handling will be racy"
    6217                 :             :   unix_signal_pending[signum] = 1;
    6218                 :             :   any_unix_signal_pending = 1;
    6219                 :             : #endif
    6220                 :             : 
    6221                 :          22 :   g_wakeup_signal (glib_worker_context->wakeup);
    6222                 :             : 
    6223                 :          22 :   errno = saved_errno;
    6224                 :          22 : }
    6225                 :             : 
    6226                 :             : #endif /* !G_OS_WIN32 */
    6227                 :             : 
    6228                 :             : /**
    6229                 :             :  * g_child_watch_source_new:
    6230                 :             :  * @pid: process to watch — on POSIX systems, this is the positive PID of a
    6231                 :             :  *   child process; on Windows it is a handle for a process (which doesn’t have
    6232                 :             :  *   to be a child)
    6233                 :             :  * 
    6234                 :             :  * Creates a new child watch source.
    6235                 :             :  *
    6236                 :             :  * The source will not initially be associated with any
    6237                 :             :  * [struct@GLib.MainContext] and must be added to one with
    6238                 :             :  * [method@GLib.Source.attach] before it will be executed.
    6239                 :             :  *
    6240                 :             :  * Note that child watch sources can only be used in conjunction with
    6241                 :             :  * `g_spawn...` when the [flags@GLib.SpawnFlags.DO_NOT_REAP_CHILD] flag is used.
    6242                 :             :  *
    6243                 :             :  * Note that on platforms where [type@GLib.Pid] must be explicitly closed
    6244                 :             :  * (see [func@GLib.spawn_close_pid]) @pid must not be closed while the
    6245                 :             :  * source is still active. Typically, you will want to call
    6246                 :             :  * [func@GLib.spawn_close_pid] in the callback function for the source.
    6247                 :             :  *
    6248                 :             :  * On POSIX platforms, the following restrictions apply to this API
    6249                 :             :  * due to limitations in POSIX process interfaces:
    6250                 :             :  *
    6251                 :             :  * * @pid must be a child of this process.
    6252                 :             :  * * @pid must be positive.
    6253                 :             :  * * The application must not call [`waitpid()`](man:waitpid(1)) with a
    6254                 :             :  *   non-positive first argument, for instance in another thread.
    6255                 :             :  * * The application must not wait for @pid to exit by any other
    6256                 :             :  *   mechanism, including `waitpid(pid, ...)` or a second child-watch
    6257                 :             :  *   source for the same @pid.
    6258                 :             :  * * The application must not ignore `SIGCHLD`.
    6259                 :             :  * * Before 2.78, the application could not send a signal ([`kill()`](man:kill(2))) to the
    6260                 :             :  *   watched @pid in a race free manner. Since 2.78, you can do that while the
    6261                 :             :  *   associated [struct@GLib.MainContext] is acquired.
    6262                 :             :  * * Before 2.78, even after destroying the [struct@GLib.Source], you could not
    6263                 :             :  *   be sure that @pid wasn’t already reaped. Hence, it was also not
    6264                 :             :  *   safe to `kill()` or `waitpid()` on the process ID after the child watch
    6265                 :             :  *   source was gone. Destroying the source before it fired made it
    6266                 :             :  *   impossible to reliably reap the process.
    6267                 :             :  *
    6268                 :             :  * If any of those conditions are not met, this and related APIs will
    6269                 :             :  * not work correctly. This can often be diagnosed via a GLib warning
    6270                 :             :  * stating that `ECHILD` was received by `waitpid()`.
    6271                 :             :  *
    6272                 :             :  * Calling [`waitpid()`](man:waitpid(2)) for specific processes other than @pid
    6273                 :             :  * remains a valid thing to do.
    6274                 :             :  *
    6275                 :             :  * Returns: (transfer full): the newly-created child watch source
    6276                 :             :  * Since: 2.4
    6277                 :             :  **/
    6278                 :             : GSource *
    6279                 :         928 : g_child_watch_source_new (GPid pid)
    6280                 :             : {
    6281                 :             :   GSource *source;
    6282                 :             :   GChildWatchSource *child_watch_source;
    6283                 :             : #ifdef HAVE_PIDFD
    6284                 :             :   int errsv;
    6285                 :             : #endif
    6286                 :             : 
    6287                 :             : #ifndef G_OS_WIN32
    6288                 :         581 :   g_return_val_if_fail (pid > 0, NULL);
    6289                 :             : #endif
    6290                 :             : 
    6291                 :         928 :   source = g_source_new (&g_child_watch_funcs, sizeof (GChildWatchSource));
    6292                 :         928 :   child_watch_source = (GChildWatchSource *)source;
    6293                 :             : 
    6294                 :             :   /* Set a default name on the source, just in case the caller does not. */
    6295                 :         928 :   g_source_set_static_name (source, "GChildWatchSource");
    6296                 :             : 
    6297                 :         928 :   child_watch_source->pid = pid;
    6298                 :             : 
    6299                 :             : #ifdef G_OS_WIN32
    6300                 :         347 :   child_watch_source->poll.fd = (gintptr) pid;
    6301                 :         347 :   child_watch_source->poll.events = G_IO_IN;
    6302                 :             : 
    6303                 :         347 :   g_source_add_poll (source, &child_watch_source->poll);
    6304                 :             : #else /* !G_OS_WIN32 */
    6305                 :             : 
    6306                 :             : #ifdef HAVE_PIDFD
    6307                 :             :   /* Use a pidfd, if possible, to avoid having to install a global SIGCHLD
    6308                 :             :    * handler and potentially competing with any other library/code which wants
    6309                 :             :    * to install one.
    6310                 :             :    *
    6311                 :             :    * Unfortunately this use of pidfd isn’t race-free (the PID could be recycled
    6312                 :             :    * between the caller calling g_child_watch_source_new() and here), but it’s
    6313                 :             :    * better than SIGCHLD.
    6314                 :             :    */
    6315                 :         581 :   child_watch_source->poll.fd = (int) syscall (SYS_pidfd_open, pid, 0);
    6316                 :             : 
    6317                 :         581 :   if (child_watch_source->poll.fd >= 0)
    6318                 :             :     {
    6319                 :         581 :       child_watch_source->poll.events = G_IO_IN;
    6320                 :         581 :       g_source_add_poll (source, &child_watch_source->poll);
    6321                 :         581 :       return source;
    6322                 :             :     }
    6323                 :             : 
    6324                 :           0 :   errsv = errno;
    6325                 :           0 :   g_debug ("pidfd_open(%" G_PID_FORMAT ") failed with error: %s",
    6326                 :             :            pid, g_strerror (errsv));
    6327                 :             :   /* Fall through; likely the kernel isn’t new enough to support pidfd_open() */
    6328                 :             : #endif /* HAVE_PIDFD */
    6329                 :             : 
    6330                 :             :   /* We can do that without atomic, as the source is not yet added in
    6331                 :             :    * unix_child_watches (which we do next under a lock). */
    6332                 :           0 :   child_watch_source->child_maybe_exited = TRUE;
    6333                 :           0 :   child_watch_source->poll.fd = -1;
    6334                 :             : 
    6335                 :           0 :   G_LOCK (unix_signal_lock);
    6336                 :           0 :   ref_unix_signal_handler_unlocked (SIGCHLD);
    6337                 :           0 :   unix_child_watches = g_slist_prepend (unix_child_watches, child_watch_source);
    6338                 :           0 :   G_UNLOCK (unix_signal_lock);
    6339                 :             : #endif /* !G_OS_WIN32 */
    6340                 :             : 
    6341                 :         347 :   return source;
    6342                 :             : }
    6343                 :             : 
    6344                 :             : /**
    6345                 :             :  * g_child_watch_add_full: (rename-to g_child_watch_add)
    6346                 :             :  * @priority: the priority of the idle source; typically this will be in the
    6347                 :             :  *   range between [const@GLib.PRIORITY_DEFAULT_IDLE] and
    6348                 :             :  *   [const@GLib.PRIORITY_HIGH_IDLE]
    6349                 :             :  * @pid: process to watch — on POSIX systems, this is the positive PID of a
    6350                 :             :  *   child process; on Windows it is a handle for a process (which doesn’t have
    6351                 :             :  *   to be a child)
    6352                 :             :  * @function: function to call
    6353                 :             :  * @data: data to pass to @function
    6354                 :             :  * @notify: (nullable): function to call when the idle is removed
    6355                 :             :  * 
    6356                 :             :  * Sets a function to be called when the child indicated by @pid 
    6357                 :             :  * exits, at the priority @priority.
    6358                 :             :  *
    6359                 :             :  * If you obtain @pid from [func@GLib.spawn_async] or
    6360                 :             :  * [func@GLib.spawn_async_with_pipes] you will need to pass
    6361                 :             :  * [flags@GLib.SpawnFlags.DO_NOT_REAP_CHILD] as a flag to the spawn function for
    6362                 :             :  * the child watching to work.
    6363                 :             :  *
    6364                 :             :  * In many programs, you will want to call [func@GLib.spawn_check_wait_status]
    6365                 :             :  * in the callback to determine whether or not the child exited
    6366                 :             :  * successfully.
    6367                 :             :  *
    6368                 :             :  * Also, note that on platforms where [type@GLib.Pid] must be explicitly closed
    6369                 :             :  * (see [func@GLib.spawn_close_pid]) @pid must not be closed while the source
    6370                 :             :  * is still active.  Typically, you should invoke [func@GLib.spawn_close_pid]
    6371                 :             :  * in the callback function for the source.
    6372                 :             :  * 
    6373                 :             :  * GLib supports only a single callback per process ID.
    6374                 :             :  * On POSIX platforms, the same restrictions mentioned for
    6375                 :             :  * [func@GLib.child_watch_source_new] apply to this function.
    6376                 :             :  *
    6377                 :             :  * This internally creates a main loop source using 
    6378                 :             :  * [func@GLib.child_watch_source_new] and attaches it to the main loop context
    6379                 :             :  * using [method@GLib.Source.attach]. You can do these steps manually if you
    6380                 :             :  * need greater control.
    6381                 :             :  *
    6382                 :             :  * Returns: the ID (greater than 0) of the event source
    6383                 :             :  * Since: 2.4
    6384                 :             :  **/
    6385                 :             : guint
    6386                 :          40 : g_child_watch_add_full (gint            priority,
    6387                 :             :                         GPid            pid,
    6388                 :             :                         GChildWatchFunc function,
    6389                 :             :                         gpointer        data,
    6390                 :             :                         GDestroyNotify  notify)
    6391                 :             : {
    6392                 :             :   GSource *source;
    6393                 :             :   guint id;
    6394                 :             :   
    6395                 :          40 :   g_return_val_if_fail (function != NULL, 0);
    6396                 :             : #ifndef G_OS_WIN32
    6397                 :          34 :   g_return_val_if_fail (pid > 0, 0);
    6398                 :             : #endif
    6399                 :             : 
    6400                 :          40 :   source = g_child_watch_source_new (pid);
    6401                 :             : 
    6402                 :          40 :   if (priority != G_PRIORITY_DEFAULT)
    6403                 :           1 :     g_source_set_priority (source, priority);
    6404                 :             : 
    6405                 :          40 :   g_source_set_callback (source, (GSourceFunc) function, data, notify);
    6406                 :          40 :   id = g_source_attach (source, NULL);
    6407                 :          40 :   g_source_unref (source);
    6408                 :             : 
    6409                 :          40 :   return id;
    6410                 :           6 : }
    6411                 :             : 
    6412                 :             : /**
    6413                 :             :  * g_child_watch_add:
    6414                 :             :  * @pid: process to watch — on POSIX systems, this is the positive PID of a
    6415                 :             :  *   child process; on Windows it is a handle for a process (which doesn’t have
    6416                 :             :  *   to be a child)
    6417                 :             :  * @function: function to call
    6418                 :             :  * @data: data to pass to @function
    6419                 :             :  *
    6420                 :             :  * Sets a function to be called when the child indicated by @pid 
    6421                 :             :  * exits, at a default priority, [const@GLib.PRIORITY_DEFAULT].
    6422                 :             :  *
    6423                 :             :  * If you obtain @pid from [func@GLib.spawn_async] or
    6424                 :             :  * [func@GLib.spawn_async_with_pipes] you will need to pass
    6425                 :             :  * [flags@GLib.SpawnFlags.DO_NOT_REAP_CHILD] as a flag to the spawn function for
    6426                 :             :  * the child watching to work.
    6427                 :             :  *
    6428                 :             :  * Note that on platforms where [type@GLib.Pid] must be explicitly closed
    6429                 :             :  * (see [func@GLib.spawn_close_pid]) @pid must not be closed while the
    6430                 :             :  * source is still active. Typically, you will want to call
    6431                 :             :  * [func@GLib.spawn_close_pid] in the callback function for the source.
    6432                 :             :  *
    6433                 :             :  * GLib supports only a single callback per process ID.
    6434                 :             :  * On POSIX platforms, the same restrictions mentioned for
    6435                 :             :  * [func@GLib.child_watch_source_new] apply to this function.
    6436                 :             :  *
    6437                 :             :  * This internally creates a main loop source using 
    6438                 :             :  * [func@GLib.child_watch_source_new] and attaches it to the main loop context
    6439                 :             :  * using [method@GLib.Source.attach]. You can do these steps manually if you
    6440                 :             :  * need greater control.
    6441                 :             :  *
    6442                 :             :  * Returns: the ID (greater than 0) of the event source
    6443                 :             :  * Since: 2.4
    6444                 :             :  **/
    6445                 :             : guint 
    6446                 :          39 : g_child_watch_add (GPid            pid,
    6447                 :             :                    GChildWatchFunc function,
    6448                 :             :                    gpointer        data)
    6449                 :             : {
    6450                 :          39 :   return g_child_watch_add_full (G_PRIORITY_DEFAULT, pid, function, data, NULL);
    6451                 :             : }
    6452                 :             : 
    6453                 :             : 
    6454                 :             : /* Idle functions */
    6455                 :             : 
    6456                 :             : static gboolean 
    6457                 :      566407 : g_idle_prepare  (GSource  *source,
    6458                 :             :                  gint     *timeout)
    6459                 :             : {
    6460                 :      566407 :   *timeout = 0;
    6461                 :             : 
    6462                 :      566407 :   return TRUE;
    6463                 :             : }
    6464                 :             : 
    6465                 :             : static gboolean 
    6466                 :       40482 : g_idle_check    (GSource  *source)
    6467                 :             : {
    6468                 :       40482 :   return TRUE;
    6469                 :             : }
    6470                 :             : 
    6471                 :             : static gboolean
    6472                 :      606887 : g_idle_dispatch (GSource    *source, 
    6473                 :             :                  GSourceFunc callback,
    6474                 :             :                  gpointer    user_data)
    6475                 :             : {
    6476                 :      606887 :   GIdleSource *idle_source = (GIdleSource *)source;
    6477                 :             :   gboolean again;
    6478                 :             : 
    6479                 :      606887 :   if (!callback)
    6480                 :             :     {
    6481                 :           0 :       g_warning ("Idle source dispatched without callback. "
    6482                 :             :                  "You must call g_source_set_callback().");
    6483                 :           0 :       return FALSE;
    6484                 :             :     }
    6485                 :             : 
    6486                 :      606887 :   if (idle_source->one_shot)
    6487                 :             :     {
    6488                 :        2042 :       GSourceOnceFunc once_callback = (GSourceOnceFunc) callback;
    6489                 :        2042 :       once_callback (user_data);
    6490                 :        2042 :       again = G_SOURCE_REMOVE;
    6491                 :           2 :     }
    6492                 :             :   else
    6493                 :             :     {
    6494                 :      604845 :       again = callback (user_data);
    6495                 :             :     }
    6496                 :             : 
    6497                 :      386391 :   TRACE (GLIB_IDLE_DISPATCH (source, source->context, callback, user_data, again));
    6498                 :             : 
    6499                 :      606881 :   return again;
    6500                 :      220490 : }
    6501                 :             : 
    6502                 :             : static GSource *
    6503                 :      746788 : idle_source_new (gboolean one_shot)
    6504                 :             : {
    6505                 :             :   GSource *source;
    6506                 :             :   GIdleSource *idle_source;
    6507                 :             : 
    6508                 :      746788 :   source = g_source_new (&g_idle_funcs, sizeof (GIdleSource));
    6509                 :      746788 :   idle_source = (GIdleSource *) source;
    6510                 :             : 
    6511                 :      746788 :   idle_source->one_shot = one_shot;
    6512                 :             : 
    6513                 :      746788 :   g_source_set_priority (source, G_PRIORITY_DEFAULT_IDLE);
    6514                 :             : 
    6515                 :             :   /* Set a default name on the source, just in case the caller does not. */
    6516                 :      746788 :   g_source_set_static_name (source, "GIdleSource");
    6517                 :             : 
    6518                 :      746788 :   return source;
    6519                 :             : }
    6520                 :             : 
    6521                 :             : /**
    6522                 :             :  * g_idle_source_new:
    6523                 :             :  * 
    6524                 :             :  * Creates a new idle source.
    6525                 :             :  *
    6526                 :             :  * The source will not initially be associated with any
    6527                 :             :  * [struct@GLib.MainContext] and must be added to one with
    6528                 :             :  * [method@GLib.Source.attach] before it will be executed. Note that the
    6529                 :             :  * default priority for idle sources is [const@GLib.PRIORITY_DEFAULT_IDLE], as
    6530                 :             :  * compared to other sources which have a default priority of
    6531                 :             :  * [const@GLib.PRIORITY_DEFAULT].
    6532                 :             :  *
    6533                 :             :  * Returns: (transfer full): the newly-created idle source
    6534                 :             :  **/
    6535                 :             : GSource *
    6536                 :      744083 : g_idle_source_new (void)
    6537                 :             : {
    6538                 :      744083 :   return idle_source_new (FALSE);
    6539                 :             : }
    6540                 :             : 
    6541                 :             : static guint
    6542                 :        2705 : idle_add_full (gint           priority,
    6543                 :             :                gboolean       one_shot,
    6544                 :             :                GSourceFunc    function,
    6545                 :             :                gpointer       data,
    6546                 :             :                GDestroyNotify notify)
    6547                 :             : {
    6548                 :             :   GSource *source;
    6549                 :             :   guint id;
    6550                 :             : 
    6551                 :        2705 :   g_return_val_if_fail (function != NULL, 0);
    6552                 :             : 
    6553                 :        2705 :   source = idle_source_new (one_shot);
    6554                 :             : 
    6555                 :        2705 :   if (priority != G_PRIORITY_DEFAULT_IDLE)
    6556                 :          44 :     g_source_set_priority (source, priority);
    6557                 :             : 
    6558                 :        2705 :   g_source_set_callback (source, function, data, notify);
    6559                 :        2705 :   id = g_source_attach (source, NULL);
    6560                 :             : 
    6561                 :        2403 :   TRACE (GLIB_IDLE_ADD (source, g_main_context_default (), id, priority, function, data));
    6562                 :             : 
    6563                 :        2705 :   g_source_unref (source);
    6564                 :             : 
    6565                 :        2705 :   return id;
    6566                 :         302 : }
    6567                 :             : 
    6568                 :             : /**
    6569                 :             :  * g_idle_add_full: (rename-to g_idle_add)
    6570                 :             :  * @priority: the priority of the idle source; typically this will be in the
    6571                 :             :  *   range between [const@GLib.PRIORITY_DEFAULT_IDLE] and
    6572                 :             :  *   [const@GLib.PRIORITY_HIGH_IDLE]
    6573                 :             :  * @function: function to call
    6574                 :             :  * @data: data to pass to @function
    6575                 :             :  * @notify: (nullable): function to call when the idle is removed
    6576                 :             :  * 
    6577                 :             :  * Adds a function to be called whenever there are no higher priority
    6578                 :             :  * events pending.
    6579                 :             :  *
    6580                 :             :  * If the function returns [const@GLib.SOURCE_REMOVE] it is automatically
    6581                 :             :  * removed from the list of event sources and will not be called again.
    6582                 :             :  *
    6583                 :             :  * See [main loop memory management](main-loop.html#memory-management-of-sources) for details
    6584                 :             :  * on how to handle the return value and memory management of @data.
    6585                 :             :  *
    6586                 :             :  * This internally creates a main loop source using [func@GLib.idle_source_new]
    6587                 :             :  * and attaches it to the global [struct@GLib.MainContext] using
    6588                 :             :  * [method@GLib.Source.attach], so the callback will be invoked in whichever
    6589                 :             :  * thread is running that main context. You can do these steps manually if you
    6590                 :             :  * need greater control or to use a custom main context.
    6591                 :             :  *
    6592                 :             :  * Returns: the ID (greater than 0) of the event source
    6593                 :             :  **/
    6594                 :             : guint 
    6595                 :         651 : g_idle_add_full (gint           priority,
    6596                 :             :                  GSourceFunc    function,
    6597                 :             :                  gpointer       data,
    6598                 :             :                  GDestroyNotify notify)
    6599                 :             : {
    6600                 :         651 :   return idle_add_full (priority, FALSE, function, data, notify);
    6601                 :             : }
    6602                 :             : 
    6603                 :             : /**
    6604                 :             :  * g_idle_add:
    6605                 :             :  * @function: function to call
    6606                 :             :  * @data: data to pass to @function
    6607                 :             :  * 
    6608                 :             :  * Adds a function to be called whenever there are no higher priority
    6609                 :             :  * events pending to the default main loop.
    6610                 :             :  *
    6611                 :             :  * The function is given the
    6612                 :             :  * default idle priority, [const@GLib.PRIORITY_DEFAULT_IDLE].  If the function
    6613                 :             :  * returns [const@GLib.SOURCE_REMOVE] it is automatically removed from the list
    6614                 :             :  * of event sources and will not be called again.
    6615                 :             :  *
    6616                 :             :  * See [main loop memory management](main-loop.html#memory-management-of-sources) for details
    6617                 :             :  * on how to handle the return value and memory management of @data.
    6618                 :             :  *
    6619                 :             :  * This internally creates a main loop source using [func@GLib.idle_source_new]
    6620                 :             :  * and attaches it to the global [struct@GLib.MainContext] using
    6621                 :             :  * [method@GLib.Source.attach], so the callback will be invoked in whichever
    6622                 :             :  * thread is running that main context. You can do these steps manually if you
    6623                 :             :  * need greater control or to use a custom main context.
    6624                 :             :  *
    6625                 :             :  * Returns: the ID (greater than 0) of the event source
    6626                 :             :  **/
    6627                 :             : guint 
    6628                 :         607 : g_idle_add (GSourceFunc    function,
    6629                 :             :             gpointer       data)
    6630                 :             : {
    6631                 :         607 :   return g_idle_add_full (G_PRIORITY_DEFAULT_IDLE, function, data, NULL);
    6632                 :             : }
    6633                 :             : 
    6634                 :             : /**
    6635                 :             :  * g_idle_add_once:
    6636                 :             :  * @function: function to call
    6637                 :             :  * @data: data to pass to @function
    6638                 :             :  *
    6639                 :             :  * Adds a function to be called whenever there are no higher priority
    6640                 :             :  * events pending to the default main loop.
    6641                 :             :  *
    6642                 :             :  * The function is given the
    6643                 :             :  * default idle priority, [const@GLib.PRIORITY_DEFAULT_IDLE].
    6644                 :             :  *
    6645                 :             :  * The function will only be called once and then the source will be
    6646                 :             :  * automatically removed from the main context.
    6647                 :             :  *
    6648                 :             :  * This function otherwise behaves like [func@GLib.idle_add].
    6649                 :             :  *
    6650                 :             :  * Returns: the ID (greater than 0) of the event source
    6651                 :             :  * Since: 2.74
    6652                 :             :  */
    6653                 :             : guint
    6654                 :        2054 : g_idle_add_once (GSourceOnceFunc function,
    6655                 :             :                  gpointer        data)
    6656                 :             : {
    6657                 :        2054 :   return idle_add_full (G_PRIORITY_DEFAULT_IDLE, TRUE, (GSourceFunc) function, data, NULL);
    6658                 :             : }
    6659                 :             : 
    6660                 :             : /**
    6661                 :             :  * g_idle_remove_by_data:
    6662                 :             :  * @data: the data for the idle source’s callback.
    6663                 :             :  * 
    6664                 :             :  * Removes the idle function with the given data.
    6665                 :             :  * 
    6666                 :             :  * Returns: true if an idle source was found and removed, false otherwise
    6667                 :             :  **/
    6668                 :             : gboolean
    6669                 :           2 : g_idle_remove_by_data (gpointer data)
    6670                 :             : {
    6671                 :           2 :   return g_source_remove_by_funcs_user_data (&g_idle_funcs, data);
    6672                 :             : }
    6673                 :             : 
    6674                 :             : /**
    6675                 :             :  * g_main_context_invoke:
    6676                 :             :  * @context: (nullable): a main context, or `NULL` for the global-default
    6677                 :             :  *   main context
    6678                 :             :  * @function: function to call
    6679                 :             :  * @data: data to pass to @function
    6680                 :             :  *
    6681                 :             :  * Invokes a function in such a way that @context is owned during the
    6682                 :             :  * invocation of @function.
    6683                 :             :  *
    6684                 :             :  * If @context is `NULL` then the global-default main context — as
    6685                 :             :  * returned by [func@GLib.MainContext.default] — is used.
    6686                 :             :  *
    6687                 :             :  * If @context is owned by the current thread, @function is called
    6688                 :             :  * directly.  Otherwise, if @context is the thread-default main context
    6689                 :             :  * of the current thread and [method@GLib.MainContext.acquire] succeeds,
    6690                 :             :  * then @function is called and [method@GLib.MainContext.release] is called
    6691                 :             :  * afterwards.
    6692                 :             :  *
    6693                 :             :  * In any other case, an idle source is created to call @function and
    6694                 :             :  * that source is attached to @context (presumably to be run in another
    6695                 :             :  * thread).  The idle source is attached with [const@GLib.PRIORITY_DEFAULT]
    6696                 :             :  * priority.  If you want a different priority, use
    6697                 :             :  * [method@GLib.MainContext.invoke_full].
    6698                 :             :  *
    6699                 :             :  * Note that, as with normal idle functions, @function should probably return
    6700                 :             :  * [const@GLib.SOURCE_REMOVE].  If it returns [const@GLib.SOURCE_CONTINUE], it
    6701                 :             :  * will be continuously run in a loop (and may prevent this call from returning).
    6702                 :             :  *
    6703                 :             :  * Since: 2.28
    6704                 :             :  **/
    6705                 :             : void
    6706                 :         246 : g_main_context_invoke (GMainContext *context,
    6707                 :             :                        GSourceFunc   function,
    6708                 :             :                        gpointer      data)
    6709                 :             : {
    6710                 :         278 :   g_main_context_invoke_full (context,
    6711                 :             :                               G_PRIORITY_DEFAULT,
    6712                 :          32 :                               function, data, NULL);
    6713                 :         246 : }
    6714                 :             : 
    6715                 :             : /**
    6716                 :             :  * g_main_context_invoke_full:
    6717                 :             :  * @context: (nullable): a main context, or `NULL` for the global-default
    6718                 :             :  *   main context
    6719                 :             :  * @priority: the priority at which to run @function
    6720                 :             :  * @function: function to call
    6721                 :             :  * @data: data to pass to @function
    6722                 :             :  * @notify: (nullable): a function to call when @data is no longer in use
    6723                 :             :  *
    6724                 :             :  * Invokes a function in such a way that @context is owned during the
    6725                 :             :  * invocation of @function.
    6726                 :             :  *
    6727                 :             :  * This function is the same as [method@GLib.MainContext.invoke] except that it
    6728                 :             :  * lets you specify the priority in case @function ends up being
    6729                 :             :  * scheduled as an idle and also lets you give a [callback@GLib.DestroyNotify]
    6730                 :             :  * for @data.
    6731                 :             :  *
    6732                 :             :  * The @notify function should not assume that it is called from any particular
    6733                 :             :  * thread or with any particular context acquired.
    6734                 :             :  *
    6735                 :             :  * Since: 2.28
    6736                 :             :  **/
    6737                 :             : void
    6738                 :         263 : g_main_context_invoke_full (GMainContext   *context,
    6739                 :             :                             gint            priority,
    6740                 :             :                             GSourceFunc     function,
    6741                 :             :                             gpointer        data,
    6742                 :             :                             GDestroyNotify  notify)
    6743                 :             : {
    6744                 :         263 :   g_return_if_fail (function != NULL);
    6745                 :             : 
    6746                 :         263 :   if (!context)
    6747                 :          10 :     context = g_main_context_default ();
    6748                 :             : 
    6749                 :         263 :   if (g_main_context_is_owner (context))
    6750                 :             :     {
    6751                 :          20 :       while (function (data));
    6752                 :          20 :       if (notify != NULL)
    6753                 :           0 :         notify (data);
    6754                 :           8 :     }
    6755                 :             : 
    6756                 :             :   else
    6757                 :             :     {
    6758                 :             :       GMainContext *thread_default;
    6759                 :             : 
    6760                 :         243 :       thread_default = g_main_context_get_thread_default ();
    6761                 :             : 
    6762                 :         243 :       if (!thread_default)
    6763                 :         235 :         thread_default = g_main_context_default ();
    6764                 :             : 
    6765                 :         243 :       if (thread_default == context && g_main_context_acquire (context))
    6766                 :             :         {
    6767                 :         199 :           while (function (data));
    6768                 :             : 
    6769                 :         199 :           g_main_context_release (context);
    6770                 :             : 
    6771                 :         199 :           if (notify != NULL)
    6772                 :           5 :             notify (data);
    6773                 :           9 :         }
    6774                 :             :       else
    6775                 :             :         {
    6776                 :             :           GSource *source;
    6777                 :             : 
    6778                 :          44 :           source = g_idle_source_new ();
    6779                 :          44 :           g_source_set_priority (source, priority);
    6780                 :          44 :           g_source_set_callback (source, function, data, notify);
    6781                 :          44 :           g_source_attach (source, context);
    6782                 :          44 :           g_source_unref (source);
    6783                 :             :         }
    6784                 :             :     }
    6785                 :          32 : }
    6786                 :             : 
    6787                 :             : static gpointer
    6788                 :         272 : glib_worker_main (gpointer data)
    6789                 :             : {
    6790                 :          35 :   while (TRUE)
    6791                 :             :     {
    6792                 :        2137 :       g_main_context_iteration (glib_worker_context, TRUE);
    6793                 :             : 
    6794                 :             : #ifdef G_OS_UNIX
    6795                 :        1900 :       if (g_atomic_int_get (&any_unix_signal_pending))
    6796                 :          22 :         dispatch_unix_signals ();
    6797                 :             : #endif
    6798                 :             :     }
    6799                 :             : 
    6800                 :             :   return NULL; /* worst GCC warning message ever... */
    6801                 :             : }
    6802                 :             : 
    6803                 :             : GMainContext *
    6804                 :        1195 : g_get_worker_context (void)
    6805                 :             : {
    6806                 :             :   static gsize initialised;
    6807                 :             : 
    6808                 :        1195 :   if (g_once_init_enter (&initialised))
    6809                 :             :     {
    6810                 :             :       /* mask all signals in the worker thread */
    6811                 :             : #ifdef G_OS_UNIX
    6812                 :             :       sigset_t prev_mask;
    6813                 :             :       sigset_t all;
    6814                 :             : 
    6815                 :         237 :       sigfillset (&all);
    6816                 :         237 :       pthread_sigmask (SIG_SETMASK, &all, &prev_mask);
    6817                 :             : #endif
    6818                 :         285 :       glib_worker_context = g_main_context_new ();
    6819                 :         285 :       g_thread_new ("gmain", glib_worker_main, NULL);
    6820                 :             : #ifdef G_OS_UNIX
    6821                 :         237 :       pthread_sigmask (SIG_SETMASK, &prev_mask, NULL);
    6822                 :             : #endif
    6823                 :         285 :       g_once_init_leave (&initialised, TRUE);
    6824                 :          48 :     }
    6825                 :             : 
    6826                 :        1195 :   return glib_worker_context;
    6827                 :             : }
    6828                 :             : 
        

Generated by: LCOV version 2.0-1