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