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