1beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor/* GLIB - Library of useful routines for C programming
2beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
3beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor *
4beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor * gmain.c: Main loop abstraction, timeouts, and idle functions
5beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor * Copyright 1998 Owen Taylor
6beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor *
7beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor * This library is free software; you can redistribute it and/or
8c9bd7542e1a28ba9de60048361c0a97d251833e7Tim Janik * modify it under the terms of the GNU Lesser General Public
9beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor * License as published by the Free Software Foundation; either
10beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor * version 2 of the License, or (at your option) any later version.
11beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor *
12beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor * This library is distributed in the hope that it will be useful,
13beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor * but WITHOUT ANY WARRANTY; without even the implied warranty of
14beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU
15c9bd7542e1a28ba9de60048361c0a97d251833e7Tim Janik * Lesser General Public License for more details.
16beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor *
17c9bd7542e1a28ba9de60048361c0a97d251833e7Tim Janik * You should have received a copy of the GNU Lesser General Public
18beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor * License along with this library; if not, write to the
19beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor * Boston, MA 02111-1307, USA.
21beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor */
22beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
23b9ef2b41db975061960e2217220668c2a5d563daCST/*
24c9bd7542e1a28ba9de60048361c0a97d251833e7Tim Janik * Modified by the GLib Team and others 1997-2000.  See the AUTHORS
25b9ef2b41db975061960e2217220668c2a5d563daCST * file for a list of people on the GLib Team.  See the ChangeLog
26b9ef2b41db975061960e2217220668c2a5d563daCST * files for a list of changes.  These files are distributed with
27b9ef2b41db975061960e2217220668c2a5d563daCST * GLib at ftp://ftp.gtk.org/pub/gtk/.
28b9ef2b41db975061960e2217220668c2a5d563daCST */
29b9ef2b41db975061960e2217220668c2a5d563daCST
30931ea952650b013b834041b91b0c37a748ffd449Owen Taylor/*
31931ea952650b013b834041b91b0c37a748ffd449Owen Taylor * MT safe
32931ea952650b013b834041b91b0c37a748ffd449Owen Taylor */
33931ea952650b013b834041b91b0c37a748ffd449Owen Taylor
34f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist#include "config.h"
35f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist
36ac68024ec1a476871111522e5ce48945b18ce9f7Dan Winship/* Uncomment the next line (and the corresponding line in gpoll.c) to
37ac68024ec1a476871111522e5ce48945b18ce9f7Dan Winship * enable debugging printouts if the environment variable
38ac68024ec1a476871111522e5ce48945b18ce9f7Dan Winship * G_MAIN_POLL_DEBUG is set to some value.
392ded70ee9463ef0a24eeecb85074378c5c896500Tor Lillqvist */
4087c7aeb93bd654776f59805a342ad913031034f3Tim Janik/* #define G_MAIN_POLL_DEBUG */
4187c7aeb93bd654776f59805a342ad913031034f3Tim Janik
422ded70ee9463ef0a24eeecb85074378c5c896500Tor Lillqvist#ifdef _WIN32
432ded70ee9463ef0a24eeecb85074378c5c896500Tor Lillqvist/* Always enable debugging printout on Windows, as it is more often
442ded70ee9463ef0a24eeecb85074378c5c896500Tor Lillqvist * needed there...
452ded70ee9463ef0a24eeecb85074378c5c896500Tor Lillqvist */
462ded70ee9463ef0a24eeecb85074378c5c896500Tor Lillqvist#define G_MAIN_POLL_DEBUG
472ded70ee9463ef0a24eeecb85074378c5c896500Tor Lillqvist#endif
482ded70ee9463ef0a24eeecb85074378c5c896500Tor Lillqvist
49beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor#include "glib.h"
50e4f8f3b95c2a3b4188a38378bd30b548dba505c2Sebastian Wilhelmi#include "gthreadprivate.h"
51e906108048c4fbe7b1525a1ded119376447068cfMatthias Clasen#include <signal.h>
52e0153773a69fe64b2643c0d74c40af2dee7eb38fTim Janik#include <sys/types.h>
53f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist#include <time.h>
54f8c1c1f9e019d8fd2d5e56e3aa44183d0e752130Matthias Clasen#include <stdlib.h>
55f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist#ifdef HAVE_SYS_TIME_H
56beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor#include <sys/time.h>
5708425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik#endif /* HAVE_SYS_TIME_H */
58f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist#ifdef HAVE_UNISTD_H
59beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor#include <unistd.h>
6008425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik#endif /* HAVE_UNISTD_H */
61931ea952650b013b834041b91b0c37a748ffd449Owen Taylor#include <errno.h>
62f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist
637ea73a019935e1118935433c86480acc5eee2e05Manish Singh#ifdef G_OS_WIN32
64f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist#define STRICT
65f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist#include <windows.h>
667ea73a019935e1118935433c86480acc5eee2e05Manish Singh#endif /* G_OS_WIN32 */
67f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist
687ea73a019935e1118935433c86480acc5eee2e05Manish Singh#ifdef G_OS_BEOS
69b78a0792a46cad24fb67abed406f5d6c8add26c1Matthias Clasen#include <sys/socket.h>
70b78a0792a46cad24fb67abed406f5d6c8add26c1Matthias Clasen#include <sys/wait.h>
717ea73a019935e1118935433c86480acc5eee2e05Manish Singh#endif /* G_OS_BEOS */
72499c9786d1316bc72c539d55786bb3a65d95a83aCDT
73540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen#ifdef G_OS_UNIX
74540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen#include <fcntl.h>
75540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen#include <sys/wait.h>
76540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen#endif
77608a31b98e1420f487190871ee7312db2643d93dMatthias Clasen
78608a31b98e1420f487190871ee7312db2643d93dMatthias Clasen#include "galias.h"
79608a31b98e1420f487190871ee7312db2643d93dMatthias Clasen
80beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor/* Types */
81beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
82e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylortypedef struct _GTimeoutSource GTimeoutSource;
83540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasentypedef struct _GChildWatchSource GChildWatchSource;
84beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylortypedef struct _GPollRec GPollRec;
85e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylortypedef struct _GSourceCallback GSourceCallback;
86beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
87a62ebb0e757c972ef4bc5892d7e3e673c6426015Tim Janiktypedef enum
88a62ebb0e757c972ef4bc5892d7e3e673c6426015Tim Janik{
89beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  G_SOURCE_READY = 1 << G_HOOK_FLAG_USER_SHIFT,
90beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  G_SOURCE_CAN_RECURSE = 1 << (G_HOOK_FLAG_USER_SHIFT + 1)
91beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor} GSourceFlags;
92beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
938951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor#ifdef G_THREADS_ENABLED
948951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylortypedef struct _GMainWaiter GMainWaiter;
958951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor
968951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylorstruct _GMainWaiter
978951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor{
988951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  GCond *cond;
998951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  GMutex *mutex;
1008951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor};
1018951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor#endif
1028951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor
103bef319723baaeb219d94b37727de7e499cb71fdfMatthias Clasentypedef struct _GMainDispatch GMainDispatch;
104bef319723baaeb219d94b37727de7e499cb71fdfMatthias Clasen
105bef319723baaeb219d94b37727de7e499cb71fdfMatthias Clasenstruct _GMainDispatch
106bef319723baaeb219d94b37727de7e499cb71fdfMatthias Clasen{
107bef319723baaeb219d94b37727de7e499cb71fdfMatthias Clasen  gint depth;
108bef319723baaeb219d94b37727de7e499cb71fdfMatthias Clasen  GSList *dispatching_sources; /* stack of current sources */
109bef319723baaeb219d94b37727de7e499cb71fdfMatthias Clasen};
1102ded70ee9463ef0a24eeecb85074378c5c896500Tor Lillqvist
111fc542a462a750f19b8fb06fcecc6f2034ec86d59Tor Lillqvist#ifdef G_MAIN_POLL_DEBUG
1122ded70ee9463ef0a24eeecb85074378c5c896500Tor Lillqvistgboolean _g_main_poll_debug = FALSE;
1132ded70ee9463ef0a24eeecb85074378c5c896500Tor Lillqvist#endif
114e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
115a62ebb0e757c972ef4bc5892d7e3e673c6426015Tim Janikstruct _GMainContext
116e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor{
117e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor#ifdef G_THREADS_ENABLED
118e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  /* The following lock is used for both the list of sources
119e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor   * and the list of poll records
1208951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor   */
1218951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  GStaticMutex mutex;
1228951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  GCond *cond;
1238951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  GThread *owner;
1248951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  guint owner_count;
125e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  GSList *waiters;
126e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor#endif
127c40b15fc6b37d152d67c2d2ec18d0e635ea70f90Sebastian Wilhelmi
1288951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  gint ref_count;
129e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
130e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  GPtrArray *pending_dispatches;
131e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  gint timeout;			/* Timeout for current iteration */
132e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
133e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  guint next_id;
134e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  GSource *source_list;
135e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  gint in_check_or_prepare;
136e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
137e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  GPollRec *poll_records;
138e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  guint n_poll_records;
139f5c28ce4ab8e8015a1432060b6cfe547183b2f9eOwen Taylor  GPollFD *cached_poll_array;
140e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  guint cached_poll_array_size;
141e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
142e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor#ifdef G_THREADS_ENABLED
143e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor#ifndef G_OS_WIN32
144e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor/* this pipe is used to wake up the main loop when a source is added.
145e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor */
146e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  gint wake_up_pipe[2];
147e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor#else /* G_OS_WIN32 */
148e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  HANDLE wake_up_semaphore;
149e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor#endif /* G_OS_WIN32 */
150e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
151e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  GPollFD wake_up_rec;
152e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  gboolean poll_waiting;
153e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
154e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor/* Flag indicating whether the set of fd's changed during a poll */
155e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  gboolean poll_changed;
156e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor#endif /* G_THREADS_ENABLED */
157e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
158e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  GPollFunc poll_func;
159e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
160e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  GTimeVal current_time;
161e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  gboolean time_is_current;
162e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor};
163e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
164e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorstruct _GSourceCallback
165e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor{
166e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  guint ref_count;
167e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  GSourceFunc func;
168e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  gpointer    data;
169beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  GDestroyNotify notify;
170beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor};
171a62ebb0e757c972ef4bc5892d7e3e673c6426015Tim Janik
172a62ebb0e757c972ef4bc5892d7e3e673c6426015Tim Janikstruct _GMainLoop
173e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor{
1748be41eae4d0077069ecf77a8904b5f624d5ea5ffTim Janik  GMainContext *context;
175c40b15fc6b37d152d67c2d2ec18d0e635ea70f90Sebastian Wilhelmi  gboolean is_running;
176beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  gint ref_count;
177beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor};
178e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
179a62ebb0e757c972ef4bc5892d7e3e673c6426015Tim Janikstruct _GTimeoutSource
180e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor{
181beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  GSource     source;
18252644b08e77ddb3c146556451982dd3ff53bc1efOwen Taylor  GTimeVal    expiration;
183f8c1c1f9e019d8fd2d5e56e3aa44183d0e752130Matthias Clasen  guint       interval;
184beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  guint	      granularity;
185beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor};
186540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen
187540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasenstruct _GChildWatchSource
188540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen{
189540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  GSource     source;
190540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  GPid        pid;
1914d470362b20627044ed9e56fa47ba012cb9b4c54Hans Breuer  gint        child_status;
1924d470362b20627044ed9e56fa47ba012cb9b4c54Hans Breuer#ifdef G_OS_WIN32
1934d470362b20627044ed9e56fa47ba012cb9b4c54Hans Breuer  GPollFD     poll;
194c40b15fc6b37d152d67c2d2ec18d0e635ea70f90Sebastian Wilhelmi#else /* G_OS_WIN32 */
195c40b15fc6b37d152d67c2d2ec18d0e635ea70f90Sebastian Wilhelmi  gint        count;
1964d470362b20627044ed9e56fa47ba012cb9b4c54Hans Breuer  gboolean    child_exited;
197540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen#endif /* G_OS_WIN32 */
198540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen};
199a62ebb0e757c972ef4bc5892d7e3e673c6426015Tim Janik
200a62ebb0e757c972ef4bc5892d7e3e673c6426015Tim Janikstruct _GPollRec
201beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor{
2026ed79b115c311323be086e2581650c33366c6f37Tim Janik  GPollFD *fd;
2030cba1b531d5d28890fa4f48359d4e7adacf2a603Tim Janik  GPollRec *next;
204beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  gint priority;
205beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor};
206e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2078951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor#ifdef G_THREADS_ENABLED
2088951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor#define LOCK_CONTEXT(context) g_static_mutex_lock (&context->mutex)
2098951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor#define UNLOCK_CONTEXT(context) g_static_mutex_unlock (&context->mutex)
210e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor#define G_THREAD_SELF g_thread_self ()
211e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor#else
212e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor#define LOCK_CONTEXT(context) (void)0
2138951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor#define UNLOCK_CONTEXT(context) (void)0
214e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor#define G_THREAD_SELF NULL
215e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor#endif
216e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2179753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor#define SOURCE_DESTROYED(source) (((source)->flags & G_HOOK_FLAG_ACTIVE) == 0)
2189753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor#define SOURCE_BLOCKED(source) (((source)->flags & G_HOOK_FLAG_IN_CALL) != 0 && \
219e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor		                ((source)->flags & G_SOURCE_CAN_RECURSE) == 0)
220e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
221e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor#define SOURCE_UNREF(source, context)                       \
222e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor   G_STMT_START {                                           \
223e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    if ((source)->ref_count > 1)                            \
224e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      (source)->ref_count--;                                \
225e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    else                                                    \
226e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      g_source_unref_internal ((source), (context), TRUE);  \
227e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor   } G_STMT_END
228e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
229beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
230beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor/* Forward declarations */
231e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
232e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorstatic void g_source_unref_internal             (GSource      *source,
233e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor						 GMainContext *context,
234e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor						 gboolean      have_lock);
235e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorstatic void g_source_destroy_internal           (GSource      *source,
236e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor						 GMainContext *context,
237e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor						 gboolean      have_lock);
238e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorstatic void g_main_context_poll                 (GMainContext *context,
239e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor						 gint          timeout,
240e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor						 gint          priority,
241e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor						 GPollFD      *fds,
242e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor						 gint          n_fds);
243e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorstatic void g_main_context_add_poll_unlocked    (GMainContext *context,
244e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor						 gint          priority,
245e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor						 GPollFD      *fd);
246e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorstatic void g_main_context_remove_poll_unlocked (GMainContext *context,
2478951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor						 GPollFD      *fd);
248e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorstatic void g_main_context_wakeup_unlocked      (GMainContext *context);
249e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
250e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorstatic gboolean g_timeout_prepare  (GSource     *source,
251e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor				    gint        *timeout);
252e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorstatic gboolean g_timeout_check    (GSource     *source);
253e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorstatic gboolean g_timeout_dispatch (GSource     *source,
254e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor				    GSourceFunc  callback,
255540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen				    gpointer     user_data);
256540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasenstatic gboolean g_child_watch_prepare  (GSource     *source,
257540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen				        gint        *timeout);
258540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasenstatic gboolean g_child_watch_check    (GSource     *source);
259540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasenstatic gboolean g_child_watch_dispatch (GSource     *source,
260540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen					GSourceFunc  callback,
261e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor					gpointer     user_data);
262e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorstatic gboolean g_idle_prepare     (GSource     *source,
263e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor				    gint        *timeout);
264e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorstatic gboolean g_idle_check       (GSource     *source);
265e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorstatic gboolean g_idle_dispatch    (GSource     *source,
266e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor				    GSourceFunc  callback,
267e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor				    gpointer     user_data);
268b37e032581c44135b480dc74ae0355e72eef1372Sebastian Wilhelmi
269e2fd4e2bd0589b159f87b491095565d16fac2789Owen TaylorG_LOCK_DEFINE_STATIC (main_loop);
270659fd4113b919a9491c5f872d11a445b6ea48765Sebastian Wilhelmistatic GMainContext *default_main_context;
271931ea952650b013b834041b91b0c37a748ffd449Owen Taylorstatic GSList *main_contexts_without_pipe = NULL;
2724d470362b20627044ed9e56fa47ba012cb9b4c54Hans Breuer
273540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen#ifndef G_OS_WIN32
274540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen/* Child status monitoring code */
275540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasenenum {
276540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  CHILD_WATCH_UNINITIALIZED,
277540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  CHILD_WATCH_INITIALIZED_SINGLE,
278540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  CHILD_WATCH_INITIALIZED_THREADED
279540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen};
2800631238743d968a39798ebc2f32eb1418ff697c6Matthias Clasenstatic gint child_watch_init_state = CHILD_WATCH_UNINITIALIZED;
281540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasenstatic gint child_watch_count = 1;
2824d470362b20627044ed9e56fa47ba012cb9b4c54Hans Breuerstatic gint child_watch_wake_up_pipe[2] = {0, 0};
283540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen#endif /* !G_OS_WIN32 */
284540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias ClasenG_LOCK_DEFINE_STATIC (main_context_list);
285540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasenstatic GSList *main_context_list = NULL;
286f8c1c1f9e019d8fd2d5e56e3aa44183d0e752130Matthias Clasen
287f8c1c1f9e019d8fd2d5e56e3aa44183d0e752130Matthias Clasenstatic gint timer_perturb = -1;
288b4c3107c7a1dc5dd9e8050ed06f24d6be408e840Owen Taylor
28908425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim JanikGSourceFuncs g_timeout_funcs =
290beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor{
291beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  g_timeout_prepare,
292beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  g_timeout_check,
293e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  g_timeout_dispatch,
294beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  NULL
295beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor};
296540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen
297540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias ClasenGSourceFuncs g_child_watch_funcs =
298540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen{
299540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  g_child_watch_prepare,
300540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  g_child_watch_check,
301540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  g_child_watch_dispatch,
302540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  NULL
303540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen};
304b4c3107c7a1dc5dd9e8050ed06f24d6be408e840Owen Taylor
30508425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim JanikGSourceFuncs g_idle_funcs =
306beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor{
307beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  g_idle_prepare,
308beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  g_idle_check,
309e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  g_idle_dispatch,
310beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  NULL
311beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor};
3128951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor
3138951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor/**
31416fc3b22c0ae7ca268f34d554da4f4850748d335Owen Taylor * g_main_context_ref:
3158951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor * @context: a #GMainContext
3168951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor *
317c83e52605f373aeae29f02361d51af3799e6dae2Matthias Clasen * Increases the reference count on a #GMainContext object by one.
318c83e52605f373aeae29f02361d51af3799e6dae2Matthias Clasen *
3198951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor * Returns: the @context that was passed in (since 2.6)
320c83e52605f373aeae29f02361d51af3799e6dae2Matthias Clasen **/
3218951f96c50fda95a8cfaf48e8e378136a9268365Owen TaylorGMainContext *
322dc602866312bff134f4d827190f5c24934970e19Owen Taylorg_main_context_ref (GMainContext *context)
323f026692d2ab3434b82bb7bdde57ed8cfb943d8a7Manish Singh{
324f026692d2ab3434b82bb7bdde57ed8cfb943d8a7Manish Singh  g_return_val_if_fail (context != NULL, NULL);
3258951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  g_return_val_if_fail (g_atomic_int_get (&context->ref_count) > 0, NULL);
326c40b15fc6b37d152d67c2d2ec18d0e635ea70f90Sebastian Wilhelmi
327f026692d2ab3434b82bb7bdde57ed8cfb943d8a7Manish Singh  g_atomic_int_inc (&context->ref_count);
328f026692d2ab3434b82bb7bdde57ed8cfb943d8a7Manish Singh
3298951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  return context;
3308951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor}
3310cba1b531d5d28890fa4f48359d4e7adacf2a603Tim Janik
3322afc40f3a62146ac0518cf6fa6d936c708f66d42Owen Taylorstatic inline void
3332afc40f3a62146ac0518cf6fa6d936c708f66d42Owen Taylorpoll_rec_list_free (GMainContext *context,
3342afc40f3a62146ac0518cf6fa6d936c708f66d42Owen Taylor		    GPollRec     *list)
3356ed79b115c311323be086e2581650c33366c6f37Tim Janik{
3362afc40f3a62146ac0518cf6fa6d936c708f66d42Owen Taylor  g_slice_free_chain (GPollRec, list, next);
3372afc40f3a62146ac0518cf6fa6d936c708f66d42Owen Taylor}
338c40b15fc6b37d152d67c2d2ec18d0e635ea70f90Sebastian Wilhelmi
339c40b15fc6b37d152d67c2d2ec18d0e635ea70f90Sebastian Wilhelmi/**
340c40b15fc6b37d152d67c2d2ec18d0e635ea70f90Sebastian Wilhelmi * g_main_context_unref:
341c40b15fc6b37d152d67c2d2ec18d0e635ea70f90Sebastian Wilhelmi * @context: a #GMainContext
342c40b15fc6b37d152d67c2d2ec18d0e635ea70f90Sebastian Wilhelmi *
343c40b15fc6b37d152d67c2d2ec18d0e635ea70f90Sebastian Wilhelmi * Decreases the reference count on a #GMainContext object by one. If
344c40b15fc6b37d152d67c2d2ec18d0e635ea70f90Sebastian Wilhelmi * the result is zero, free the context and free all associated memory.
345c40b15fc6b37d152d67c2d2ec18d0e635ea70f90Sebastian Wilhelmi **/
346c40b15fc6b37d152d67c2d2ec18d0e635ea70f90Sebastian Wilhelmivoid
3478951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylorg_main_context_unref (GMainContext *context)
3488951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor{
349c40b15fc6b37d152d67c2d2ec18d0e635ea70f90Sebastian Wilhelmi  GSource *source;
350c40b15fc6b37d152d67c2d2ec18d0e635ea70f90Sebastian Wilhelmi  g_return_if_fail (context != NULL);
3518951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  g_return_if_fail (g_atomic_int_get (&context->ref_count) > 0);
352c40b15fc6b37d152d67c2d2ec18d0e635ea70f90Sebastian Wilhelmi
353c40b15fc6b37d152d67c2d2ec18d0e635ea70f90Sebastian Wilhelmi  if (!g_atomic_int_dec_and_test (&context->ref_count))
3548951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor    return;
355540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen
356540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  G_LOCK (main_context_list);
357540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  main_context_list = g_slist_remove (main_context_list, context);
358540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  G_UNLOCK (main_context_list);
359e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
360e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  source = context->source_list;
361e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  while (source)
362e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    {
363d0ee63840cd8c7760614810822370aee0382683fMatthias Clasen      GSource *next = source->next;
364e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      g_source_destroy_internal (source, context, FALSE);
365e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      source = next;
36608425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik    }
367e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
3688951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor#ifdef G_THREADS_ENABLED
369e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  g_static_mutex_free (&context->mutex);
37008425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik#endif
371e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
372e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  g_ptr_array_free (context->pending_dispatches, TRUE);
3732afc40f3a62146ac0518cf6fa6d936c708f66d42Owen Taylor  g_free (context->cached_poll_array);
3742afc40f3a62146ac0518cf6fa6d936c708f66d42Owen Taylor
3752afc40f3a62146ac0518cf6fa6d936c708f66d42Owen Taylor  poll_rec_list_free (context, context->poll_records);
3769edb08492d09a36caf389f639f45c8c1c8315f10Havoc Pennington
377e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor#ifdef G_THREADS_ENABLED
378e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  if (g_thread_supported())
379e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    {
380e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor#ifndef G_OS_WIN32
381e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      close (context->wake_up_pipe[0]);
382e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      close (context->wake_up_pipe[1]);
383e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor#else
384e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      CloseHandle (context->wake_up_semaphore);
385659fd4113b919a9491c5f872d11a445b6ea48765Sebastian Wilhelmi#endif
386659fd4113b919a9491c5f872d11a445b6ea48765Sebastian Wilhelmi    }
387659fd4113b919a9491c5f872d11a445b6ea48765Sebastian Wilhelmi  else
388659fd4113b919a9491c5f872d11a445b6ea48765Sebastian Wilhelmi    main_contexts_without_pipe = g_slist_remove (main_contexts_without_pipe,
3891c93d867fc8c14c2d315ac1ffa05ad406a44ed8dMatthias Clasen						 context);
3901c93d867fc8c14c2d315ac1ffa05ad406a44ed8dMatthias Clasen
3911c93d867fc8c14c2d315ac1ffa05ad406a44ed8dMatthias Clasen  if (context->cond != NULL)
3929edb08492d09a36caf389f639f45c8c1c8315f10Havoc Pennington    g_cond_free (context->cond);
393e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor#endif
394e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
395dc602866312bff134f4d827190f5c24934970e19Owen Taylor  g_free (context);
396dc602866312bff134f4d827190f5c24934970e19Owen Taylor}
397659fd4113b919a9491c5f872d11a445b6ea48765Sebastian Wilhelmi
398659fd4113b919a9491c5f872d11a445b6ea48765Sebastian Wilhelmi#ifdef G_THREADS_ENABLED
399659fd4113b919a9491c5f872d11a445b6ea48765Sebastian Wilhelmistatic void
400659fd4113b919a9491c5f872d11a445b6ea48765Sebastian Wilhelmig_main_context_init_pipe (GMainContext *context)
401fc9afe0d219ad7bb16c2ba8ce2a1e268bdd25479Hans Breuer{
402540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen# ifndef G_OS_WIN32
403540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  if (context->wake_up_pipe[0] != -1)
404659fd4113b919a9491c5f872d11a445b6ea48765Sebastian Wilhelmi    return;
405659fd4113b919a9491c5f872d11a445b6ea48765Sebastian Wilhelmi  if (pipe (context->wake_up_pipe) < 0)
406659fd4113b919a9491c5f872d11a445b6ea48765Sebastian Wilhelmi    g_error ("Cannot create pipe main loop wake-up: %s\n",
4074c78992dbf2244577bc2487c7606b6b0f0bf242cMatthias Clasen	     g_strerror (errno));
4084c78992dbf2244577bc2487c7606b6b0f0bf242cMatthias Clasen
4094c78992dbf2244577bc2487c7606b6b0f0bf242cMatthias Clasen  fcntl (context->wake_up_pipe[0], F_SETFD, FD_CLOEXEC);
4104c78992dbf2244577bc2487c7606b6b0f0bf242cMatthias Clasen  fcntl (context->wake_up_pipe[1], F_SETFD, FD_CLOEXEC);
411659fd4113b919a9491c5f872d11a445b6ea48765Sebastian Wilhelmi
412659fd4113b919a9491c5f872d11a445b6ea48765Sebastian Wilhelmi  context->wake_up_rec.fd = context->wake_up_pipe[0];
413659fd4113b919a9491c5f872d11a445b6ea48765Sebastian Wilhelmi  context->wake_up_rec.events = G_IO_IN;
414fc9afe0d219ad7bb16c2ba8ce2a1e268bdd25479Hans Breuer# else
415fc9afe0d219ad7bb16c2ba8ce2a1e268bdd25479Hans Breuer  if (context->wake_up_semaphore != NULL)
416659fd4113b919a9491c5f872d11a445b6ea48765Sebastian Wilhelmi    return;
417659fd4113b919a9491c5f872d11a445b6ea48765Sebastian Wilhelmi  context->wake_up_semaphore = CreateSemaphore (NULL, 0, 100, NULL);
418659fd4113b919a9491c5f872d11a445b6ea48765Sebastian Wilhelmi  if (context->wake_up_semaphore == NULL)
419659fd4113b919a9491c5f872d11a445b6ea48765Sebastian Wilhelmi    g_error ("Cannot create wake-up semaphore: %s",
4200e2384faa8778b91d502c228b4c5b7988d872959Tor Lillqvist	     g_win32_error_message (GetLastError ()));
421659fd4113b919a9491c5f872d11a445b6ea48765Sebastian Wilhelmi  context->wake_up_rec.fd = (gintptr) context->wake_up_semaphore;
422605682521b501912a8a0c2e66a24bca171ae0df1Tor Lillqvist  context->wake_up_rec.events = G_IO_IN;
423fc542a462a750f19b8fb06fcecc6f2034ec86d59Tor Lillqvist
424a3fa74853aa93af9e1754b61769e5ec76f0918bcTor Lillqvist  if (_g_main_poll_debug)
425659fd4113b919a9491c5f872d11a445b6ea48765Sebastian Wilhelmi    g_print ("wake-up semaphore: %p\n", context->wake_up_semaphore);
426659fd4113b919a9491c5f872d11a445b6ea48765Sebastian Wilhelmi# endif
427659fd4113b919a9491c5f872d11a445b6ea48765Sebastian Wilhelmi  g_main_context_add_poll_unlocked (context, 0, &context->wake_up_rec);
428659fd4113b919a9491c5f872d11a445b6ea48765Sebastian Wilhelmi}
429659fd4113b919a9491c5f872d11a445b6ea48765Sebastian Wilhelmi
4302e7514d052ca81b12645f0048f280269a443ea5aMatthias Clasenvoid
431659fd4113b919a9491c5f872d11a445b6ea48765Sebastian Wilhelmi_g_main_thread_init (void)
432659fd4113b919a9491c5f872d11a445b6ea48765Sebastian Wilhelmi{
433659fd4113b919a9491c5f872d11a445b6ea48765Sebastian Wilhelmi  GSList *curr = main_contexts_without_pipe;
434659fd4113b919a9491c5f872d11a445b6ea48765Sebastian Wilhelmi  while (curr)
435659fd4113b919a9491c5f872d11a445b6ea48765Sebastian Wilhelmi    {
436659fd4113b919a9491c5f872d11a445b6ea48765Sebastian Wilhelmi      g_main_context_init_pipe ((GMainContext *)curr->data);
437659fd4113b919a9491c5f872d11a445b6ea48765Sebastian Wilhelmi      curr = curr->next;
438659fd4113b919a9491c5f872d11a445b6ea48765Sebastian Wilhelmi    }
439659fd4113b919a9491c5f872d11a445b6ea48765Sebastian Wilhelmi  g_slist_free (main_contexts_without_pipe);
440659fd4113b919a9491c5f872d11a445b6ea48765Sebastian Wilhelmi  main_contexts_without_pipe = NULL;
441659fd4113b919a9491c5f872d11a445b6ea48765Sebastian Wilhelmi}
442659fd4113b919a9491c5f872d11a445b6ea48765Sebastian Wilhelmi#endif /* G_THREADS_ENABLED */
443e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
4448951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor/**
445e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * g_main_context_new:
44658178261fdf00ec7b9eb8a8f3a665c792f053287Matthias Clasen *
447e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * Creates a new #GMainContext structure.
4488951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor *
449e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * Return value: the new #GMainContext
450e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor **/
4512e7514d052ca81b12645f0048f280269a443ea5aMatthias ClasenGMainContext *
452e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorg_main_context_new (void)
4538951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor{
45470a7a7654ef87c05a281318262ed635b90ffeebeOwen Taylor  GMainContext *context = g_new0 (GMainContext, 1);
455605682521b501912a8a0c2e66a24bca171ae0df1Tor Lillqvist
456605682521b501912a8a0c2e66a24bca171ae0df1Tor Lillqvist#ifdef G_MAIN_POLL_DEBUG
457605682521b501912a8a0c2e66a24bca171ae0df1Tor Lillqvist  {
458605682521b501912a8a0c2e66a24bca171ae0df1Tor Lillqvist    static gboolean beenhere = FALSE;
459605682521b501912a8a0c2e66a24bca171ae0df1Tor Lillqvist
460605682521b501912a8a0c2e66a24bca171ae0df1Tor Lillqvist    if (!beenhere)
461605682521b501912a8a0c2e66a24bca171ae0df1Tor Lillqvist      {
462fc542a462a750f19b8fb06fcecc6f2034ec86d59Tor Lillqvist	if (getenv ("G_MAIN_POLL_DEBUG") != NULL)
463605682521b501912a8a0c2e66a24bca171ae0df1Tor Lillqvist	  _g_main_poll_debug = TRUE;
464605682521b501912a8a0c2e66a24bca171ae0df1Tor Lillqvist	beenhere = TRUE;
465605682521b501912a8a0c2e66a24bca171ae0df1Tor Lillqvist      }
466605682521b501912a8a0c2e66a24bca171ae0df1Tor Lillqvist  }
467605682521b501912a8a0c2e66a24bca171ae0df1Tor Lillqvist#endif
46870a7a7654ef87c05a281318262ed635b90ffeebeOwen Taylor
4698951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor#ifdef G_THREADS_ENABLED
47070a7a7654ef87c05a281318262ed635b90ffeebeOwen Taylor  g_static_mutex_init (&context->mutex);
4718951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor
4728951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  context->owner = NULL;
473540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  context->waiters = NULL;
474fc9afe0d219ad7bb16c2ba8ce2a1e268bdd25479Hans Breuer
475540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen# ifndef G_OS_WIN32
476540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  context->wake_up_pipe[0] = -1;
477fc9afe0d219ad7bb16c2ba8ce2a1e268bdd25479Hans Breuer  context->wake_up_pipe[1] = -1;
478fc9afe0d219ad7bb16c2ba8ce2a1e268bdd25479Hans Breuer# else
479fc9afe0d219ad7bb16c2ba8ce2a1e268bdd25479Hans Breuer  context->wake_up_semaphore = NULL;
480f18db7d2d498c80d58d2ac7abb082529d3b06a12Sebastian Wilhelmi# endif
481540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen#endif
4828951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor
4838951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  context->ref_count = 1;
484659fd4113b919a9491c5f872d11a445b6ea48765Sebastian Wilhelmi
485659fd4113b919a9491c5f872d11a445b6ea48765Sebastian Wilhelmi  context->next_id = 1;
486659fd4113b919a9491c5f872d11a445b6ea48765Sebastian Wilhelmi
487659fd4113b919a9491c5f872d11a445b6ea48765Sebastian Wilhelmi  context->source_list = NULL;
488659fd4113b919a9491c5f872d11a445b6ea48765Sebastian Wilhelmi
489659fd4113b919a9491c5f872d11a445b6ea48765Sebastian Wilhelmi  context->poll_func = g_poll;
490659fd4113b919a9491c5f872d11a445b6ea48765Sebastian Wilhelmi
491659fd4113b919a9491c5f872d11a445b6ea48765Sebastian Wilhelmi  context->cached_poll_array = NULL;
492659fd4113b919a9491c5f872d11a445b6ea48765Sebastian Wilhelmi  context->cached_poll_array_size = 0;
493659fd4113b919a9491c5f872d11a445b6ea48765Sebastian Wilhelmi
494659fd4113b919a9491c5f872d11a445b6ea48765Sebastian Wilhelmi  context->pending_dispatches = g_ptr_array_new ();
495659fd4113b919a9491c5f872d11a445b6ea48765Sebastian Wilhelmi
496659fd4113b919a9491c5f872d11a445b6ea48765Sebastian Wilhelmi  context->time_is_current = FALSE;
497f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist
498659fd4113b919a9491c5f872d11a445b6ea48765Sebastian Wilhelmi#ifdef G_THREADS_ENABLED
499659fd4113b919a9491c5f872d11a445b6ea48765Sebastian Wilhelmi  if (g_thread_supported ())
500659fd4113b919a9491c5f872d11a445b6ea48765Sebastian Wilhelmi    g_main_context_init_pipe (context);
501659fd4113b919a9491c5f872d11a445b6ea48765Sebastian Wilhelmi  else
502659fd4113b919a9491c5f872d11a445b6ea48765Sebastian Wilhelmi    main_contexts_without_pipe = g_slist_prepend (main_contexts_without_pipe,
503e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor						  context);
504e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor#endif
505540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen
506540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  G_LOCK (main_context_list);
5072ded70ee9463ef0a24eeecb85074378c5c896500Tor Lillqvist  main_context_list = g_slist_append (main_context_list, context);
5082ded70ee9463ef0a24eeecb85074378c5c896500Tor Lillqvist
509fc542a462a750f19b8fb06fcecc6f2034ec86d59Tor Lillqvist#ifdef G_MAIN_POLL_DEBUG
5102ded70ee9463ef0a24eeecb85074378c5c896500Tor Lillqvist  if (_g_main_poll_debug)
5112ded70ee9463ef0a24eeecb85074378c5c896500Tor Lillqvist    g_print ("created context=%p\n", context);
5122ded70ee9463ef0a24eeecb85074378c5c896500Tor Lillqvist#endif
513540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen
514540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  G_UNLOCK (main_context_list);
515e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
516beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  return context;
517beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor}
518e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
519e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor/**
520e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * g_main_context_default:
521a52e2986cd4a2147cfc8d41ae23d98907caaf3a0Matthias Clasen *
522e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * Returns the default main context. This is the main context used
523e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * for main loop functions when a main loop is not explicitly
524e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * specified.
525e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *
526e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * Return value: the default main context.
527e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor **/
528e2fd4e2bd0589b159f87b491095565d16fac2789Owen TaylorGMainContext *
529beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylorg_main_context_default (void)
530e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor{
531e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  /* Slow, but safe */
532b2e318ff3ecc50d72121a4e8561442a6d79a7a84Tim Janik
533931ea952650b013b834041b91b0c37a748ffd449Owen Taylor  G_LOCK (main_loop);
534e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
5352ded70ee9463ef0a24eeecb85074378c5c896500Tor Lillqvist  if (!default_main_context)
5362ded70ee9463ef0a24eeecb85074378c5c896500Tor Lillqvist    {
5372ded70ee9463ef0a24eeecb85074378c5c896500Tor Lillqvist      default_main_context = g_main_context_new ();
538fc542a462a750f19b8fb06fcecc6f2034ec86d59Tor Lillqvist#ifdef G_MAIN_POLL_DEBUG
5392ded70ee9463ef0a24eeecb85074378c5c896500Tor Lillqvist      if (_g_main_poll_debug)
5402ded70ee9463ef0a24eeecb85074378c5c896500Tor Lillqvist	g_print ("default context=%p\n", default_main_context);
5412ded70ee9463ef0a24eeecb85074378c5c896500Tor Lillqvist#endif
542931ea952650b013b834041b91b0c37a748ffd449Owen Taylor    }
543b2e318ff3ecc50d72121a4e8561442a6d79a7a84Tim Janik
54408425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik  G_UNLOCK (main_loop);
545e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
546beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  return default_main_context;
547beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor}
548e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
549e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor/* Hooks for adding to the main loop */
550e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
551e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor/**
552e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * g_source_new:
553e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * @source_funcs: structure containing functions that implement
554a52e2986cd4a2147cfc8d41ae23d98907caaf3a0Matthias Clasen *                the sources behavior.
555e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * @struct_size: size of the #GSource structure to create.
556a52e2986cd4a2147cfc8d41ae23d98907caaf3a0Matthias Clasen *
557a52e2986cd4a2147cfc8d41ae23d98907caaf3a0Matthias Clasen * Creates a new #GSource structure. The size is specified to
558e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * allow creating structures derived from #GSource that contain
559a52e2986cd4a2147cfc8d41ae23d98907caaf3a0Matthias Clasen * additional data. The size passed in must be at least
560e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * <literal>sizeof (GSource)</literal>.
561e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *
5625e45a337b8c9e0d77375711d643ecd22c95d194bMatthias Clasen * The source will not initially be associated with any #GMainContext
563e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * and must be added to one with g_source_attach() before it will be
564e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * executed.
565a52e2986cd4a2147cfc8d41ae23d98907caaf3a0Matthias Clasen *
566e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * Return value: the newly-created #GSource.
567e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor **/
568e2fd4e2bd0589b159f87b491095565d16fac2789Owen TaylorGSource *
569e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorg_source_new (GSourceFuncs *source_funcs,
570beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor	      guint         struct_size)
571e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor{
572e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  GSource *source;
573e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
574e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  g_return_val_if_fail (source_funcs != NULL, NULL);
575931ea952650b013b834041b91b0c37a748ffd449Owen Taylor  g_return_val_if_fail (struct_size >= sizeof (GSource), NULL);
576e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
577e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  source = (GSource*) g_malloc0 (struct_size);
578e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
579e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  source->source_funcs = source_funcs;
580931ea952650b013b834041b91b0c37a748ffd449Owen Taylor  source->ref_count = 1;
581e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
582931ea952650b013b834041b91b0c37a748ffd449Owen Taylor  source->priority = G_PRIORITY_DEFAULT;
583e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
58408425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik  source->flags = G_HOOK_FLAG_ACTIVE;
585e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
586e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  /* NULL/0 initialization for all other fields */
587e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
588beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  return source;
589beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor}
590e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
591e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor/* Holds context's lock
592e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor */
593e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorstatic void
594e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorg_source_list_add (GSource      *source,
595beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor		   GMainContext *context)
596e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor{
597e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  GSource *tmp_source, *last_source;
598e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
599e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  last_source = NULL;
600e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  tmp_source = context->source_list;
601e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  while (tmp_source && tmp_source->priority <= source->priority)
602e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    {
603e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      last_source = tmp_source;
604e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      tmp_source = tmp_source->next;
605a62ebb0e757c972ef4bc5892d7e3e673c6426015Tim Janik    }
606e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
607e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  source->next = tmp_source;
608e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  if (tmp_source)
609e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    tmp_source->prev = source;
610e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
611e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  source->prev = last_source;
612e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  if (last_source)
613e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    last_source->next = source;
614e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  else
615beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor    context->source_list = source;
616beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor}
617e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
618e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor/* Holds context's lock
619e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor */
620e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorstatic void
621e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorg_source_list_remove (GSource      *source,
622beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor		      GMainContext *context)
623e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor{
624e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  if (source->prev)
625e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    source->prev->next = source->next;
626e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  else
627931ea952650b013b834041b91b0c37a748ffd449Owen Taylor    context->source_list = source->next;
628e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
629e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  if (source->next)
63008425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik    source->next->prev = source->prev;
631e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
632e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  source->prev = NULL;
63308425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik  source->next = NULL;
63408425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik}
635e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
636e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor/**
637e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * g_source_attach:
638e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * @source: a #GSource
639e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * @context: a #GMainContext (if %NULL, the default context will be used)
640e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *
641ee685b003e3b8dfe50670417dddd7422b9d2a6f0Sven Herzberg * Adds a #GSource to a @context so that it will be executed within
642e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * that context. Remove it by calling g_source_destroy().
64390bd00b055d71ad0b158b8125003b7a62ada657fMatthias Clasen *
64490bd00b055d71ad0b158b8125003b7a62ada657fMatthias Clasen * Return value: the ID (greater than 0) for the source within the
645e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *   #GMainContext.
646e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor **/
647e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorguint
648e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorg_source_attach (GSource      *source,
64908425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik		 GMainContext *context)
650e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor{
651e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  guint result = 0;
65208425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik  GSList *tmp_list;
653e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
654e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  g_return_val_if_fail (source->context == NULL, 0);
655e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  g_return_val_if_fail (!SOURCE_DESTROYED (source), 0);
656e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
657e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  if (!context)
65808425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik    context = g_main_context_default ();
659e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
66008425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik  LOCK_CONTEXT (context);
661e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
66213852a10d4e2a94320f4c6db09a274de0aba63d7Owen Taylor  source->context = context;
66308425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik  result = source->source_id = context->next_id++;
6641084477e032113aefa2aad6d8c0a7360fafaae91Owen Taylor
665e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  source->ref_count++;
66608425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik  g_source_list_add (source, context);
667e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
668e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  tmp_list = source->poll_fds;
669e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  while (tmp_list)
670e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    {
671e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      g_main_context_add_poll_unlocked (context, source->priority, tmp_list->data);
672e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      tmp_list = tmp_list->next;
67308425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik    }
674e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
675e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor#ifdef G_THREADS_ENABLED
6768951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  /* Now wake up the main loop if it is waiting in the poll() */
677e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  g_main_context_wakeup_unlocked (context);
67808425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik#endif
679e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
68008425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik  UNLOCK_CONTEXT (context);
681e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
682beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  return result;
683beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor}
684e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
685e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorstatic void
686e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorg_source_destroy_internal (GSource      *source,
687e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor			   GMainContext *context,
688beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor			   gboolean      have_lock)
689e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor{
690e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  if (!have_lock)
691e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    LOCK_CONTEXT (context);
692e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
693e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  if (!SOURCE_DESTROYED (source))
694cbd74878d1ff8d218e9854fe5b42bfdad3397acaOwen Taylor    {
695e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      GSList *tmp_list;
696e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      gpointer old_cb_data;
697e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      GSourceCallbackFuncs *old_cb_funcs;
698e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
699a62ebb0e757c972ef4bc5892d7e3e673c6426015Tim Janik      source->flags &= ~G_HOOK_FLAG_ACTIVE;
700e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
701e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      old_cb_data = source->callback_data;
702f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist      old_cb_funcs = source->callback_funcs;
703e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
704e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      source->callback_data = NULL;
70548b41a2f5f36507a78ff7f8f1b4d57393ee4ec7eTor Lillqvist      source->callback_funcs = NULL;
706e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
707e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      if (old_cb_funcs)
708e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	{
709e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	  UNLOCK_CONTEXT (context);
710e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	  old_cb_funcs->unref (old_cb_data);
711e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	  LOCK_CONTEXT (context);
7129753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor	}
7139753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor
714cbd74878d1ff8d218e9854fe5b42bfdad3397acaOwen Taylor      if (!SOURCE_BLOCKED (source))
7159753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor	{
7169753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor	  tmp_list = source->poll_fds;
7179753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor	  while (tmp_list)
7189753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor	    {
7199753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor	      g_main_context_remove_poll_unlocked (context, tmp_list->data);
7209753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor	      tmp_list = tmp_list->next;
721cbd74878d1ff8d218e9854fe5b42bfdad3397acaOwen Taylor	    }
7229753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor	}
723e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
724e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      g_source_unref_internal (source, context, TRUE);
725f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist    }
726e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
727e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  if (!have_lock)
728beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor    UNLOCK_CONTEXT (context);
729beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor}
730e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
731e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor/**
732e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * g_source_destroy:
733e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * @source: a #GSource
734a52e2986cd4a2147cfc8d41ae23d98907caaf3a0Matthias Clasen *
735e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * Removes a source from its #GMainContext, if any, and mark it as
736e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * destroyed.  The source cannot be subsequently added to another
737e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * context.
738e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor **/
739e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorvoid
740e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorg_source_destroy (GSource *source)
741e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor{
742e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  GMainContext *context;
743e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
744e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  g_return_if_fail (source != NULL);
745e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
746e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  context = source->context;
747e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
748e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  if (context)
749e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    g_source_destroy_internal (source, context, FALSE);
750e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  else
751e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    source->flags &= ~G_HOOK_FLAG_ACTIVE;
752beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor}
753e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
754e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor/**
755e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * g_source_get_id:
756e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * @source: a #GSource
757a52e2986cd4a2147cfc8d41ae23d98907caaf3a0Matthias Clasen *
75890bd00b055d71ad0b158b8125003b7a62ada657fMatthias Clasen * Returns the numeric ID for a particular source. The ID of a source
75990bd00b055d71ad0b158b8125003b7a62ada657fMatthias Clasen * is a positive integer which is unique within a particular main loop
760e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * context. The reverse
761e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * mapping from ID to source is done by g_main_context_find_source_by_id().
76290bd00b055d71ad0b158b8125003b7a62ada657fMatthias Clasen *
763e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * Return value: the ID (greater than 0) for the source
764e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor **/
765e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorguint
766beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylorg_source_get_id (GSource *source)
767e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor{
768e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  guint result;
769e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
770e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  g_return_val_if_fail (source != NULL, 0);
771e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  g_return_val_if_fail (source->context != NULL, 0);
772e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
77313852a10d4e2a94320f4c6db09a274de0aba63d7Owen Taylor  LOCK_CONTEXT (source->context);
774e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  result = source->source_id;
775e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  UNLOCK_CONTEXT (source->context);
776e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
777e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  return result;
778beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor}
779e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
780e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor/**
781e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * g_source_get_context:
782e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * @source: a #GSource
783a52e2986cd4a2147cfc8d41ae23d98907caaf3a0Matthias Clasen *
784e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * Gets the #GMainContext with which the source is associated.
785e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * Calling this function on a destroyed source is an error.
786e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *
787e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * Return value: the #GMainContext with which the source is associated,
788e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *               or %NULL if the context has not yet been added
789e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *               to a source.
790e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor **/
791e2fd4e2bd0589b159f87b491095565d16fac2789Owen TaylorGMainContext *
792e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorg_source_get_context (GSource *source)
793e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor{
794beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  g_return_val_if_fail (!SOURCE_DESTROYED (source), NULL);
795e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
796e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  return source->context;
797931ea952650b013b834041b91b0c37a748ffd449Owen Taylor}
798e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
79953be713583cf00b61da8d67348a664e2ec970ddcOwen Taylor/**
800e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * g_source_add_poll:
801e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * @source:a #GSource
802e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * @fd: a #GPollFD structure holding information about a file
803e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *      descriptor to watch.
804a52e2986cd4a2147cfc8d41ae23d98907caaf3a0Matthias Clasen *
805e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * Adds a file descriptor to the set of file descriptors polled for
806e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * this source. This is usually combined with g_source_new() to add an
807a52e2986cd4a2147cfc8d41ae23d98907caaf3a0Matthias Clasen * event source. The event source's check function will typically test
808e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * the @revents field in the #GPollFD struct and return %TRUE if events need
809e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * to be processed.
810e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor **/
811e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorvoid
812e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorg_source_add_poll (GSource *source,
813e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor		   GPollFD *fd)
814e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor{
815e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  GMainContext *context;
816e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
817e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  g_return_if_fail (source != NULL);
818b74e7d2f4780c159f7583bd4eecd07ee222d1d9cTor Lillqvist  g_return_if_fail (fd != NULL);
819cbd74878d1ff8d218e9854fe5b42bfdad3397acaOwen Taylor  g_return_if_fail (!SOURCE_DESTROYED (source));
820e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
821931ea952650b013b834041b91b0c37a748ffd449Owen Taylor  context = source->context;
822e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
823e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  if (context)
824e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    LOCK_CONTEXT (context);
825e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
826beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  source->poll_fds = g_slist_prepend (source->poll_fds, fd);
827e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
828e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  if (context)
8299753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor    {
8309753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor      if (!SOURCE_BLOCKED (source))
831e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	g_main_context_add_poll_unlocked (context, source->priority, fd);
832beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor      UNLOCK_CONTEXT (context);
833beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor    }
834beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor}
835e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
83653be713583cf00b61da8d67348a664e2ec970ddcOwen Taylor/**
83753be713583cf00b61da8d67348a664e2ec970ddcOwen Taylor * g_source_remove_poll:
8385e45a337b8c9e0d77375711d643ecd22c95d194bMatthias Clasen * @source:a #GSource
83953be713583cf00b61da8d67348a664e2ec970ddcOwen Taylor * @fd: a #GPollFD structure previously passed to g_source_add_poll().
840a52e2986cd4a2147cfc8d41ae23d98907caaf3a0Matthias Clasen *
84153be713583cf00b61da8d67348a664e2ec970ddcOwen Taylor * Removes a file descriptor from the set of file descriptors polled for
84253be713583cf00b61da8d67348a664e2ec970ddcOwen Taylor * this source.
84353be713583cf00b61da8d67348a664e2ec970ddcOwen Taylor **/
84453be713583cf00b61da8d67348a664e2ec970ddcOwen Taylorvoid
84553be713583cf00b61da8d67348a664e2ec970ddcOwen Taylorg_source_remove_poll (GSource *source,
84653be713583cf00b61da8d67348a664e2ec970ddcOwen Taylor		      GPollFD *fd)
84753be713583cf00b61da8d67348a664e2ec970ddcOwen Taylor{
84853be713583cf00b61da8d67348a664e2ec970ddcOwen Taylor  GMainContext *context;
84953be713583cf00b61da8d67348a664e2ec970ddcOwen Taylor
85053be713583cf00b61da8d67348a664e2ec970ddcOwen Taylor  g_return_if_fail (source != NULL);
85153be713583cf00b61da8d67348a664e2ec970ddcOwen Taylor  g_return_if_fail (fd != NULL);
85253be713583cf00b61da8d67348a664e2ec970ddcOwen Taylor  g_return_if_fail (!SOURCE_DESTROYED (source));
85353be713583cf00b61da8d67348a664e2ec970ddcOwen Taylor
85453be713583cf00b61da8d67348a664e2ec970ddcOwen Taylor  context = source->context;
85553be713583cf00b61da8d67348a664e2ec970ddcOwen Taylor
85653be713583cf00b61da8d67348a664e2ec970ddcOwen Taylor  if (context)
85753be713583cf00b61da8d67348a664e2ec970ddcOwen Taylor    LOCK_CONTEXT (context);
85853be713583cf00b61da8d67348a664e2ec970ddcOwen Taylor
85953be713583cf00b61da8d67348a664e2ec970ddcOwen Taylor  source->poll_fds = g_slist_remove (source->poll_fds, fd);
86053be713583cf00b61da8d67348a664e2ec970ddcOwen Taylor
86153be713583cf00b61da8d67348a664e2ec970ddcOwen Taylor  if (context)
8629753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor    {
8639753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor      if (!SOURCE_BLOCKED (source))
86453be713583cf00b61da8d67348a664e2ec970ddcOwen Taylor	g_main_context_remove_poll_unlocked (context, fd);
86553be713583cf00b61da8d67348a664e2ec970ddcOwen Taylor      UNLOCK_CONTEXT (context);
86653be713583cf00b61da8d67348a664e2ec970ddcOwen Taylor    }
86753be713583cf00b61da8d67348a664e2ec970ddcOwen Taylor}
86853be713583cf00b61da8d67348a664e2ec970ddcOwen Taylor
869e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor/**
870e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * g_source_set_callback_indirect:
871e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * @source: the source
872a52e2986cd4a2147cfc8d41ae23d98907caaf3a0Matthias Clasen * @callback_data: pointer to callback data "object"
873e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * @callback_funcs: functions for reference counting @callback_data
874e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *                  and getting the callback and data
875a52e2986cd4a2147cfc8d41ae23d98907caaf3a0Matthias Clasen *
8765e45a337b8c9e0d77375711d643ecd22c95d194bMatthias Clasen * Sets the callback function storing the data as a refcounted callback
8775e45a337b8c9e0d77375711d643ecd22c95d194bMatthias Clasen * "object". This is used internally. Note that calling
878e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * g_source_set_callback_indirect() assumes
879e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * an initial reference count on @callback_data, and thus
880e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * @callback_funcs->unref will eventually be called once more
881e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * than @callback_funcs->ref.
882e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor **/
883e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorvoid
884e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorg_source_set_callback_indirect (GSource              *source,
885e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor				gpointer              callback_data,
886beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor				GSourceCallbackFuncs *callback_funcs)
887e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor{
888e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  GMainContext *context;
889e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  gpointer old_cb_data;
890e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  GSourceCallbackFuncs *old_cb_funcs;
891e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
892e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  g_return_if_fail (source != NULL);
893beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  g_return_if_fail (callback_funcs != NULL || callback_data == NULL);
894e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
895beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  context = source->context;
896e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
897e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  if (context)
898931ea952650b013b834041b91b0c37a748ffd449Owen Taylor    LOCK_CONTEXT (context);
899e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
900e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  old_cb_data = source->callback_data;
90187c7aeb93bd654776f59805a342ad913031034f3Tim Janik  old_cb_funcs = source->callback_funcs;
902e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
903e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  source->callback_data = callback_data;
904beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  source->callback_funcs = callback_funcs;
905e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
906e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  if (context)
907e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    UNLOCK_CONTEXT (context);
908e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
909e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  if (old_cb_funcs)
910e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    old_cb_funcs->unref (old_cb_data);
9118be41eae4d0077069ecf77a8904b5f624d5ea5ffTim Janik}
912e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
913e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorstatic void
914e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorg_source_callback_ref (gpointer cb_data)
915e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor{
916beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  GSourceCallback *callback = cb_data;
917e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
918e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  callback->ref_count++;
919beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor}
920e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
921e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
922e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorstatic void
923e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorg_source_callback_unref (gpointer cb_data)
924e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor{
925e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  GSourceCallback *callback = cb_data;
926e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
927e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  callback->ref_count--;
928beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  if (callback->ref_count == 0)
929e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    {
930e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      if (callback->notify)
9316d145180181075ac9aae1b46af3cddc6e90d4ed2callback);	callback->notify (callback->data);
932e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      g_free (callback);
933e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    }
934beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor}
935e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
936e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorstatic void
937b4c3107c7a1dc5dd9e8050ed06f24d6be408e840Owen Taylorg_source_callback_get (gpointer     cb_data,
938e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor		       GSource     *source,
939e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor		       GSourceFunc *func,
940e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor		       gpointer    *data)
941e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor{
942beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  GSourceCallback *callback = cb_data;
943e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
944e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  *func = callback->func;
945e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  *data = callback->data;
946f26256fe182bc1249d3058d9f18402d0ac26974cOwen Taylor}
947e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
948e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorstatic GSourceCallbackFuncs g_source_callback_funcs = {
949e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  g_source_callback_ref,
950e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  g_source_callback_unref,
951e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  g_source_callback_get,
952f26256fe182bc1249d3058d9f18402d0ac26974cOwen Taylor};
953e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
954e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor/**
955e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * g_source_set_callback:
956e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * @source: the source
957e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * @func: a callback function
958e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * @data: the data to pass to callback function
959e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * @notify: a function to call when @data is no longer in use, or %NULL.
9604acacec101e4fb1456bcdf7f0b503f8e5d809cd1Soeren Sandmann *
9614acacec101e4fb1456bcdf7f0b503f8e5d809cd1Soeren Sandmann * Sets the callback function for a source. The callback for a source is
9624acacec101e4fb1456bcdf7f0b503f8e5d809cd1Soeren Sandmann * called from the source's dispatch function.
9634acacec101e4fb1456bcdf7f0b503f8e5d809cd1Soeren Sandmann *
9644acacec101e4fb1456bcdf7f0b503f8e5d809cd1Soeren Sandmann * The exact type of @func depends on the type of source; ie. you
9654acacec101e4fb1456bcdf7f0b503f8e5d809cd1Soeren Sandmann * should not count on @func being called with @data as its first
9664acacec101e4fb1456bcdf7f0b503f8e5d809cd1Soeren Sandmann * parameter.
9674acacec101e4fb1456bcdf7f0b503f8e5d809cd1Soeren Sandmann *
9684acacec101e4fb1456bcdf7f0b503f8e5d809cd1Soeren Sandmann * Typically, you won't use this function. Instead use functions specific
969e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * to the type of source you are using.
970e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor **/
971e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorvoid
972e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorg_source_set_callback (GSource        *source,
973e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor		       GSourceFunc     func,
974e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor		       gpointer        data,
975e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor		       GDestroyNotify  notify)
976e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor{
977f26256fe182bc1249d3058d9f18402d0ac26974cOwen Taylor  GSourceCallback *new_callback;
978e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
9798be41eae4d0077069ecf77a8904b5f624d5ea5ffTim Janik  g_return_if_fail (source != NULL);
980e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
981e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  new_callback = g_new (GSourceCallback, 1);
982e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
983e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  new_callback->ref_count = 1;
984e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  new_callback->func = func;
985e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  new_callback->data = data;
986e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  new_callback->notify = notify;
987e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
988bef319723baaeb219d94b37727de7e499cb71fdfMatthias Clasen  g_source_set_callback_indirect (source, new_callback, &g_source_callback_funcs);
989bef319723baaeb219d94b37727de7e499cb71fdfMatthias Clasen}
990bef319723baaeb219d94b37727de7e499cb71fdfMatthias Clasen
991bef319723baaeb219d94b37727de7e499cb71fdfMatthias Clasen
992bef319723baaeb219d94b37727de7e499cb71fdfMatthias Clasen/**
993bef319723baaeb219d94b37727de7e499cb71fdfMatthias Clasen * g_source_set_funcs:
994bef319723baaeb219d94b37727de7e499cb71fdfMatthias Clasen * @source: a #GSource
995bef319723baaeb219d94b37727de7e499cb71fdfMatthias Clasen * @funcs: the new #GSourceFuncs
996bef319723baaeb219d94b37727de7e499cb71fdfMatthias Clasen *
997bef319723baaeb219d94b37727de7e499cb71fdfMatthias Clasen * Sets the source functions (can be used to override
998bef319723baaeb219d94b37727de7e499cb71fdfMatthias Clasen * default implementations) of an unattached source.
999bef319723baaeb219d94b37727de7e499cb71fdfMatthias Clasen *
1000bef319723baaeb219d94b37727de7e499cb71fdfMatthias Clasen * Since: 2.12
1001bef319723baaeb219d94b37727de7e499cb71fdfMatthias Clasen */
1002bef319723baaeb219d94b37727de7e499cb71fdfMatthias Clasenvoid
1003bef319723baaeb219d94b37727de7e499cb71fdfMatthias Claseng_source_set_funcs (GSource     *source,
1004bef319723baaeb219d94b37727de7e499cb71fdfMatthias Clasen	           GSourceFuncs *funcs)
1005bef319723baaeb219d94b37727de7e499cb71fdfMatthias Clasen{
1006bef319723baaeb219d94b37727de7e499cb71fdfMatthias Clasen  g_return_if_fail (source != NULL);
1007bef319723baaeb219d94b37727de7e499cb71fdfMatthias Clasen  g_return_if_fail (source->context == NULL);
1008bef319723baaeb219d94b37727de7e499cb71fdfMatthias Clasen  g_return_if_fail (source->ref_count > 0);
1009bef319723baaeb219d94b37727de7e499cb71fdfMatthias Clasen  g_return_if_fail (funcs != NULL);
1010bef319723baaeb219d94b37727de7e499cb71fdfMatthias Clasen
1011e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  source->source_funcs = funcs;
1012e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor}
1013e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1014e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor/**
1015e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * g_source_set_priority:
1016a52e2986cd4a2147cfc8d41ae23d98907caaf3a0Matthias Clasen * @source: a #GSource
1017720e9f5e66a15b7df89aeaa6a9850bfec68e112eMatthias Clasen * @priority: the new priority.
1018720e9f5e66a15b7df89aeaa6a9850bfec68e112eMatthias Clasen *
1019e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * Sets the priority of a source. While the main loop is being
1020e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * run, a source will be dispatched if it is ready to be dispatched and no sources
1021e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * at a higher (numerically smaller) priority are ready to be dispatched.
1022e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor **/
1023e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorvoid
1024e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorg_source_set_priority (GSource  *source,
1025e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor		       gint      priority)
1026e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor{
1027e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  GSList *tmp_list;
1028e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  GMainContext *context;
1029e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1030e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  g_return_if_fail (source != NULL);
1031e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1032e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  context = source->context;
1033e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1034e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  if (context)
1035e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    LOCK_CONTEXT (context);
1036e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1037e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  source->priority = priority;
10389753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor
10399753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor  if (context)
10409753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor    {
10419753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor      /* Remove the source from the context's source and then
10429753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor       * add it back so it is sorted in the correct plcae
10439753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor       */
10449753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor      g_source_list_remove (source, source->context);
1045e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      g_source_list_add (source, source->context);
10469753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor
10479753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor      if (!SOURCE_BLOCKED (source))
10489753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor	{
10499753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor	  tmp_list = source->poll_fds;
10509753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor	  while (tmp_list)
10519753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor	    {
10529753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor	      g_main_context_remove_poll_unlocked (context, tmp_list->data);
10539753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor	      g_main_context_add_poll_unlocked (context, priority, tmp_list->data);
1054e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1055e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	      tmp_list = tmp_list->next;
1056e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	    }
1057e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	}
1058e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1059e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      UNLOCK_CONTEXT (source->context);
1060e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    }
1061e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor}
1062e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1063e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor/**
1064a52e2986cd4a2147cfc8d41ae23d98907caaf3a0Matthias Clasen * g_source_get_priority:
1065e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * @source: a #GSource
1066e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *
1067e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * Gets the priority of a source.
1068e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *
1069e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * Return value: the priority of the source
1070e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor **/
1071e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorgint
1072e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorg_source_get_priority (GSource *source)
1073e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor{
1074e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  g_return_val_if_fail (source != NULL, 0);
1075e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1076e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  return source->priority;
1077e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor}
1078e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1079e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor/**
1080e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * g_source_set_can_recurse:
1081e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * @source: a #GSource
1082e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * @can_recurse: whether recursion is allowed for this source
1083e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *
1084e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * Sets whether a source can be called recursively. If @can_recurse is
1085e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * %TRUE, then while the source is being dispatched then this source
1086e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * will be processed normally. Otherwise, all processing of this
1087e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * source is blocked until the dispatch function returns.
1088e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor **/
1089e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorvoid
1090e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorg_source_set_can_recurse (GSource  *source,
1091e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor			  gboolean  can_recurse)
1092e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor{
1093e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  GMainContext *context;
1094e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1095e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  g_return_if_fail (source != NULL);
1096e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1097e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  context = source->context;
1098e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1099e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  if (context)
1100e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    LOCK_CONTEXT (context);
1101e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1102e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  if (can_recurse)
1103e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    source->flags |= G_SOURCE_CAN_RECURSE;
1104e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  else
1105e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    source->flags &= ~G_SOURCE_CAN_RECURSE;
1106e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1107e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  if (context)
1108e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    UNLOCK_CONTEXT (context);
1109e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor}
1110e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1111e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor/**
1112e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * g_source_get_can_recurse:
1113a52e2986cd4a2147cfc8d41ae23d98907caaf3a0Matthias Clasen * @source: a #GSource
1114e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *
1115e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * Checks whether a source is allowed to be called recursively.
1116e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * see g_source_set_can_recurse().
1117e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *
1118e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * Return value: whether recursion is allowed.
1119e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor **/
1120e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorgboolean
1121e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorg_source_get_can_recurse (GSource  *source)
1122e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor{
1123e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  g_return_val_if_fail (source != NULL, FALSE);
1124e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1125e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  return (source->flags & G_SOURCE_CAN_RECURSE) != 0;
1126e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor}
1127e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1128e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor/**
1129e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * g_source_ref:
1130e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * @source: a #GSource
1131e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *
1132e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * Increases the reference count on a source by one.
1133e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *
1134e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * Return value: @source
1135e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor **/
1136e2fd4e2bd0589b159f87b491095565d16fac2789Owen TaylorGSource *
1137e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorg_source_ref (GSource *source)
1138e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor{
1139e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  GMainContext *context;
1140e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1141e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  g_return_val_if_fail (source != NULL, NULL);
1142e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1143e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  context = source->context;
1144e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1145e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  if (context)
1146e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    LOCK_CONTEXT (context);
1147e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1148e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  source->ref_count++;
1149e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1150e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  if (context)
1151e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    UNLOCK_CONTEXT (context);
1152e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1153e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  return source;
1154e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor}
1155e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1156e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor/* g_source_unref() but possible to call within context lock
1157e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor */
1158e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorstatic void
1159e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorg_source_unref_internal (GSource      *source,
116007267bf096978a528a02bfa9d12aec2d6f5de541Owen Taylor			 GMainContext *context,
116107267bf096978a528a02bfa9d12aec2d6f5de541Owen Taylor			 gboolean      have_lock)
1162e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor{
1163e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  gpointer old_cb_data = NULL;
1164e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  GSourceCallbackFuncs *old_cb_funcs = NULL;
1165e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1166e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  g_return_if_fail (source != NULL);
1167e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1168e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  if (!have_lock && context)
1169e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    LOCK_CONTEXT (context);
1170e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
117107267bf096978a528a02bfa9d12aec2d6f5de541Owen Taylor  source->ref_count--;
117207267bf096978a528a02bfa9d12aec2d6f5de541Owen Taylor  if (source->ref_count == 0)
117307267bf096978a528a02bfa9d12aec2d6f5de541Owen Taylor    {
117407267bf096978a528a02bfa9d12aec2d6f5de541Owen Taylor      old_cb_data = source->callback_data;
117507267bf096978a528a02bfa9d12aec2d6f5de541Owen Taylor      old_cb_funcs = source->callback_funcs;
117607267bf096978a528a02bfa9d12aec2d6f5de541Owen Taylor
1177e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      source->callback_data = NULL;
1178e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      source->callback_funcs = NULL;
1179e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1180e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      if (context && !SOURCE_DESTROYED (source))
1181e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	{
1182cbd74878d1ff8d218e9854fe5b42bfdad3397acaOwen Taylor	  g_warning (G_STRLOC ": ref_count == 0, but source is still attached to a context!");
1183cbd74878d1ff8d218e9854fe5b42bfdad3397acaOwen Taylor	  source->ref_count++;
1184cbd74878d1ff8d218e9854fe5b42bfdad3397acaOwen Taylor	}
1185b37e7bbb53afd0f8d3386065aff0d74195737fd1Owen Taylor      else if (context)
1186b37e7bbb53afd0f8d3386065aff0d74195737fd1Owen Taylor	g_source_list_remove (source, context);
1187cbd74878d1ff8d218e9854fe5b42bfdad3397acaOwen Taylor
1188cbd74878d1ff8d218e9854fe5b42bfdad3397acaOwen Taylor      if (source->source_funcs->finalize)
1189cbd74878d1ff8d218e9854fe5b42bfdad3397acaOwen Taylor	source->source_funcs->finalize (source);
1190cbd74878d1ff8d218e9854fe5b42bfdad3397acaOwen Taylor
1191e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      g_slist_free (source->poll_fds);
1192e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      source->poll_fds = NULL;
1193e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      g_free (source);
1194e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    }
1195e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
119607267bf096978a528a02bfa9d12aec2d6f5de541Owen Taylor  if (!have_lock && context)
1197e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    UNLOCK_CONTEXT (context);
1198e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1199e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  if (old_cb_funcs)
1200e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    {
120107267bf096978a528a02bfa9d12aec2d6f5de541Owen Taylor      if (have_lock)
1202e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	UNLOCK_CONTEXT (context);
1203e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1204e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      old_cb_funcs->unref (old_cb_data);
1205e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1206e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      if (have_lock)
1207e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	LOCK_CONTEXT (context);
1208e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    }
1209e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor}
1210e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1211e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor/**
1212e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * g_source_unref:
1213e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * @source: a #GSource
1214e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *
1215e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * Decreases the reference count of a source by one. If the
1216e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * resulting reference count is zero the source and associated
1217e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * memory will be destroyed.
1218e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor **/
1219e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorvoid
1220e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorg_source_unref (GSource *source)
1221e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor{
1222e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  g_return_if_fail (source != NULL);
1223e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1224e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  g_source_unref_internal (source, source->context, FALSE);
1225e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor}
1226e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
122790bd00b055d71ad0b158b8125003b7a62ada657fMatthias Clasen/**
1228e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * g_main_context_find_source_by_id:
122990bd00b055d71ad0b158b8125003b7a62ada657fMatthias Clasen * @context: a #GMainContext (if %NULL, the default context will be used)
1230e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * @source_id: the source ID, as returned by g_source_get_id().
1231e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *
1232e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * Finds a #GSource given a pair of context and ID.
1233e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *
1234e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * Return value: the #GSource if found, otherwise, %NULL
123513852a10d4e2a94320f4c6db09a274de0aba63d7Owen Taylor **/
1236e2fd4e2bd0589b159f87b491095565d16fac2789Owen TaylorGSource *
1237e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorg_main_context_find_source_by_id (GMainContext *context,
1238e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor				  guint         source_id)
1239ea9a7199a17a8f391cb3a4b0c40606c3d628e015Matthias Clasen{
1240e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  GSource *source;
1241e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1242e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  g_return_val_if_fail (source_id > 0, NULL);
1243e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1244e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  if (context == NULL)
1245e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    context = g_main_context_default ();
1246e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1247e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  LOCK_CONTEXT (context);
1248e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1249e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  source = context->source_list;
125013852a10d4e2a94320f4c6db09a274de0aba63d7Owen Taylor  while (source)
1251e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    {
1252e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      if (!SOURCE_DESTROYED (source) &&
1253e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	  source->source_id == source_id)
1254e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	break;
1255e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      source = source->next;
1256e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    }
1257e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1258e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  UNLOCK_CONTEXT (context);
1259e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1260e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  return source;
1261e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor}
1262e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1263e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor/**
1264e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * g_main_context_find_source_by_funcs_user_data:
1265e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * @context: a #GMainContext (if %NULL, the default context will be used).
1266e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * @funcs: the @source_funcs passed to g_source_new().
1267e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * @user_data: the user data from the callback.
1268e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *
1269e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * Finds a source with the given source functions and user data.  If
1270e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * multiple sources exist with the same source function and user data,
1271e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * the first one found will be returned.
1272e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *
1273e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * Return value: the source, if one was found, otherwise %NULL
1274e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor **/
1275e2fd4e2bd0589b159f87b491095565d16fac2789Owen TaylorGSource *
1276e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorg_main_context_find_source_by_funcs_user_data (GMainContext *context,
1277e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor					       GSourceFuncs *funcs,
1278e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor					       gpointer      user_data)
1279ea9a7199a17a8f391cb3a4b0c40606c3d628e015Matthias Clasen{
1280e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  GSource *source;
1281e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1282e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  g_return_val_if_fail (funcs != NULL, NULL);
1283e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1284e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  if (context == NULL)
1285e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    context = g_main_context_default ();
1286e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1287e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  LOCK_CONTEXT (context);
1288e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1289e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  source = context->source_list;
1290e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  while (source)
1291ffe592544fbc7527f489bc13e91bebccf6ceb4f7Owen Taylor    {
1292ffe592544fbc7527f489bc13e91bebccf6ceb4f7Owen Taylor      if (!SOURCE_DESTROYED (source) &&
1293ffe592544fbc7527f489bc13e91bebccf6ceb4f7Owen Taylor	  source->source_funcs == funcs &&
1294ffe592544fbc7527f489bc13e91bebccf6ceb4f7Owen Taylor	  source->callback_funcs)
1295ffe592544fbc7527f489bc13e91bebccf6ceb4f7Owen Taylor	{
1296ffe592544fbc7527f489bc13e91bebccf6ceb4f7Owen Taylor	  GSourceFunc callback;
1297ffe592544fbc7527f489bc13e91bebccf6ceb4f7Owen Taylor	  gpointer callback_data;
1298ffe592544fbc7527f489bc13e91bebccf6ceb4f7Owen Taylor
1299ffe592544fbc7527f489bc13e91bebccf6ceb4f7Owen Taylor	  source->callback_funcs->get (source->callback_data, source, &callback, &callback_data);
1300ffe592544fbc7527f489bc13e91bebccf6ceb4f7Owen Taylor
1301e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	  if (callback_data == user_data)
1302e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	    break;
1303e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	}
1304e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      source = source->next;
1305e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    }
1306e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1307e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  UNLOCK_CONTEXT (context);
1308e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1309e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  return source;
1310e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor}
1311e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1312e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor/**
1313e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * g_main_context_find_source_by_user_data:
1314e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * @context: a #GMainContext
1315e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * @user_data: the user_data for the callback.
1316e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *
1317e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * Finds a source with the given user data for the callback.  If
1318e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * multiple sources exist with the same user data, the first
1319e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * one found will be returned.
1320e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *
1321e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * Return value: the source, if one was found, otherwise %NULL
1322e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor **/
1323e2fd4e2bd0589b159f87b491095565d16fac2789Owen TaylorGSource *
1324e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorg_main_context_find_source_by_user_data (GMainContext *context,
1325e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor					 gpointer      user_data)
1326e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor{
1327e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  GSource *source;
1328e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1329e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  if (context == NULL)
1330e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    context = g_main_context_default ();
1331e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1332e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  LOCK_CONTEXT (context);
1333e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1334e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  source = context->source_list;
1335ffe592544fbc7527f489bc13e91bebccf6ceb4f7Owen Taylor  while (source)
1336ffe592544fbc7527f489bc13e91bebccf6ceb4f7Owen Taylor    {
1337ffe592544fbc7527f489bc13e91bebccf6ceb4f7Owen Taylor      if (!SOURCE_DESTROYED (source) &&
1338ffe592544fbc7527f489bc13e91bebccf6ceb4f7Owen Taylor	  source->callback_funcs)
1339ffe592544fbc7527f489bc13e91bebccf6ceb4f7Owen Taylor	{
1340ffe592544fbc7527f489bc13e91bebccf6ceb4f7Owen Taylor	  GSourceFunc callback;
1341ffe592544fbc7527f489bc13e91bebccf6ceb4f7Owen Taylor	  gpointer callback_data = NULL;
1342ffe592544fbc7527f489bc13e91bebccf6ceb4f7Owen Taylor
1343ffe592544fbc7527f489bc13e91bebccf6ceb4f7Owen Taylor	  source->callback_funcs->get (source->callback_data, source, &callback, &callback_data);
1344ffe592544fbc7527f489bc13e91bebccf6ceb4f7Owen Taylor
1345e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	  if (callback_data == user_data)
1346e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	    break;
1347e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	}
1348e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      source = source->next;
1349e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    }
1350e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1351e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  UNLOCK_CONTEXT (context);
1352e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1353e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  return source;
1354e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor}
135590bd00b055d71ad0b158b8125003b7a62ada657fMatthias Clasen
1356e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor/**
135790bd00b055d71ad0b158b8125003b7a62ada657fMatthias Clasen * g_source_remove:
135890bd00b055d71ad0b158b8125003b7a62ada657fMatthias Clasen * @tag: the ID of the source to remove.
1359540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen *
1360540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen * Removes the source with the given id from the default main context.
1361540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen * The id of
1362540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen * a #GSource is given by g_source_get_id(), or will be returned by the
1363e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * functions g_source_attach(), g_idle_add(), g_idle_add_full(),
1364ee685b003e3b8dfe50670417dddd7422b9d2a6f0Sven Herzberg * g_timeout_add(), g_timeout_add_full(), g_child_watch_add(),
1365ee685b003e3b8dfe50670417dddd7422b9d2a6f0Sven Herzberg * g_child_watch_add_full(), g_io_add_watch(), and g_io_add_watch_full().
1366e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *
1367e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * See also g_source_destroy(). You must use g_source_destroy() for sources
1368e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * added to a non-default main context.
1369e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *
1370e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * Return value: %TRUE if the source was found and removed.
1371e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor **/
1372e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorgboolean
1373e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorg_source_remove (guint tag)
1374e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor{
1375e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  GSource *source;
1376e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1377e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  g_return_val_if_fail (tag > 0, FALSE);
1378e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1379e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  source = g_main_context_find_source_by_id (NULL, tag);
1380e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  if (source)
1381e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    g_source_destroy (source);
1382e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1383e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  return source != NULL;
1384e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor}
1385e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1386e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor/**
1387e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * g_source_remove_by_user_data:
1388e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * @user_data: the user_data for the callback.
1389e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *
1390e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * Removes a source from the default main loop context given the user
1391e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * data for the callback. If multiple sources exist with the same user
1392e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * data, only one will be destroyed.
1393e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *
1394e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * Return value: %TRUE if a source was found and removed.
1395e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor **/
1396e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorgboolean
1397e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorg_source_remove_by_user_data (gpointer user_data)
1398e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor{
1399e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  GSource *source;
1400e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1401e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  source = g_main_context_find_source_by_user_data (NULL, user_data);
1402e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  if (source)
1403e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    {
1404e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      g_source_destroy (source);
1405e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      return TRUE;
1406e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    }
1407e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  else
1408e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    return FALSE;
1409e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor}
1410e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1411e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor/**
1412e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * g_source_remove_by_funcs_user_data:
1413e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * @funcs: The @source_funcs passed to g_source_new()
1414e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * @user_data: the user data for the callback
1415e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *
1416e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * Removes a source from the default main loop context given the
1417e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * source functions and user data. If multiple sources exist with the
1418e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * same source functions and user data, only one will be destroyed.
1419e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *
1420e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * Return value: %TRUE if a source was found and removed.
1421e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor **/
1422e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorgboolean
1423e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorg_source_remove_by_funcs_user_data (GSourceFuncs *funcs,
1424e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor				    gpointer      user_data)
1425e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor{
1426e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  GSource *source;
1427e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1428e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  g_return_val_if_fail (funcs != NULL, FALSE);
1429e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1430e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  source = g_main_context_find_source_by_funcs_user_data (NULL, funcs, user_data);
1431e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  if (source)
1432e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    {
1433e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      g_source_destroy (source);
1434e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      return TRUE;
1435e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    }
1436e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  else
1437e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    return FALSE;
1438e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor}
1439e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1440e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor/**
1441a412fb16541620ed72da86daac0774afe4703d9dMatthias Clasen * g_get_current_time:
1442e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * @result: #GTimeVal structure in which to store current time.
1443e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *
1444e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * Equivalent to the UNIX gettimeofday() function, but portable.
1445e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor **/
1446e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorvoid
1447e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorg_get_current_time (GTimeVal *result)
1448e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor{
1449e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor#ifndef G_OS_WIN32
1450e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  struct timeval r;
1451e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1452e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  g_return_if_fail (result != NULL);
1453e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1454e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  /*this is required on alpha, there the timeval structs are int's
1455e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    not longs and a cast only would fail horribly*/
1456e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  gettimeofday (&r, NULL);
14578ced6d247870d30d02cdd9e697904f54ec7eb303Tor Lillqvist  result->tv_sec = r.tv_sec;
1458c9211d68fc38f7114ffd6e5999f1a9ce08738d9aTor Lillqvist  result->tv_usec = r.tv_usec;
1459e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor#else
1460fef22bfe23afd7ae4864ad394586b2bd4cfda0d7Matthias Clasen  FILETIME ft;
1461fef22bfe23afd7ae4864ad394586b2bd4cfda0d7Matthias Clasen  guint64 time64;
14628ced6d247870d30d02cdd9e697904f54ec7eb303Tor Lillqvist
1463c9211d68fc38f7114ffd6e5999f1a9ce08738d9aTor Lillqvist  g_return_if_fail (result != NULL);
1464e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
14658ced6d247870d30d02cdd9e697904f54ec7eb303Tor Lillqvist  GetSystemTimeAsFileTime (&ft);
14668ced6d247870d30d02cdd9e697904f54ec7eb303Tor Lillqvist  memmove (&time64, &ft, sizeof (FILETIME));
14678ced6d247870d30d02cdd9e697904f54ec7eb303Tor Lillqvist
1468c9211d68fc38f7114ffd6e5999f1a9ce08738d9aTor Lillqvist  /* Convert from 100s of nanoseconds since 1601-01-01
1469c9211d68fc38f7114ffd6e5999f1a9ce08738d9aTor Lillqvist   * to Unix epoch. Yes, this is Y2038 unsafe.
1470e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor   */
1471c9211d68fc38f7114ffd6e5999f1a9ce08738d9aTor Lillqvist  time64 -= G_GINT64_CONSTANT (116444736000000000);
1472c9211d68fc38f7114ffd6e5999f1a9ce08738d9aTor Lillqvist  time64 /= 10;
1473e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1474e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  result->tv_sec = time64 / 1000000;
1475e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  result->tv_usec = time64 % 1000000;
147603c90584b8ae6e3515e5dd3c98051eaa07b57fd8Matthias Clasen#endif
147703c90584b8ae6e3515e5dd3c98051eaa07b57fd8Matthias Clasen}
147803c90584b8ae6e3515e5dd3c98051eaa07b57fd8Matthias Clasen
147903c90584b8ae6e3515e5dd3c98051eaa07b57fd8Matthias Clasenstatic void
148003c90584b8ae6e3515e5dd3c98051eaa07b57fd8Matthias Claseng_main_dispatch_free (gpointer dispatch)
148103c90584b8ae6e3515e5dd3c98051eaa07b57fd8Matthias Clasen{
1482e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  g_slice_free (GMainDispatch, dispatch);
1483e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor}
1484bef319723baaeb219d94b37727de7e499cb71fdfMatthias Clasen
1485bef319723baaeb219d94b37727de7e499cb71fdfMatthias Clasen/* Running the main loop */
14860875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor
14870875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylorstatic GMainDispatch *
1488bef319723baaeb219d94b37727de7e499cb71fdfMatthias Clasenget_dispatch (void)
1489bef319723baaeb219d94b37727de7e499cb71fdfMatthias Clasen{
14900875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor  static GStaticPrivate depth_private = G_STATIC_PRIVATE_INIT;
1491bef319723baaeb219d94b37727de7e499cb71fdfMatthias Clasen  GMainDispatch *dispatch = g_static_private_get (&depth_private);
149203c90584b8ae6e3515e5dd3c98051eaa07b57fd8Matthias Clasen  if (!dispatch)
14930875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor    {
14940875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor      dispatch = g_slice_new0 (GMainDispatch);
1495bef319723baaeb219d94b37727de7e499cb71fdfMatthias Clasen      g_static_private_set (&depth_private, dispatch, g_main_dispatch_free);
14960875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor    }
14970875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor
14980875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor  return dispatch;
14990875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor}
15000875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor
15010875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor/**
15020875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor * g_main_depth:
15030875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor *
15040875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor * Returns the depth of the stack of calls to
15050875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor * g_main_context_dispatch() on any #GMainContext in the current thread.
15060875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor *  That is, when called from the toplevel, it gives 0. When
15070875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor * called from within a callback from g_main_context_iteration()
15080875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor * (or g_main_loop_run(), etc.) it returns 1. When called from within
15090875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor * a callback to a recursive call to g_main_context_iterate(),
15100875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor * it returns 2. And so forth.
15110875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor *
151234a9878985f2f3d8118219890d2585219f18f8cdMatthias Clasen * This function is useful in a situation like the following:
15130875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor * Imagine an extremely simple "garbage collected" system.
151434a9878985f2f3d8118219890d2585219f18f8cdMatthias Clasen *
15150875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor * |[
15160875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor * static GList *free_list;
15170875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor *
15180875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor * gpointer
15190875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor * allocate_memory (gsize size)
15200875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor * {
15210875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor *   gpointer result = g_malloc (size);
152234a9878985f2f3d8118219890d2585219f18f8cdMatthias Clasen *   free_list = g_list_prepend (free_list, result);
15230875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor *   return result;
15240875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor * }
15250875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor *
15260875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor * void
15270875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor * free_allocated_memory (void)
15280875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor * {
15290875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor *   GList *l;
15300875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor *   for (l = free_list; l; l = l->next);
15310875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor *     g_free (l->data);
153234a9878985f2f3d8118219890d2585219f18f8cdMatthias Clasen *   g_list_free (free_list);
15330875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor *   free_list = NULL;
153434a9878985f2f3d8118219890d2585219f18f8cdMatthias Clasen *  }
15350875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor *
15360875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor * [...]
15370875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor *
15380875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor * while (TRUE);
15390875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor *  {
154034a9878985f2f3d8118219890d2585219f18f8cdMatthias Clasen *    g_main_context_iteration (NULL, TRUE);
15410875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor *    free_allocated_memory();
15420875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor *   }
15430875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor * ]|
15440875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor *
15450875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor * This works from an application, however, if you want to do the same
15460875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor * thing from a library, it gets more difficult, since you no longer
1547e1c15eb0d13eecfeea5059cf1f93e18040be4653Owen Taylor * control the main loop. You might think you can simply use an idle
15480875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor * function to make the call to free_allocated_memory(), but that
154934a9878985f2f3d8118219890d2585219f18f8cdMatthias Clasen * doesn't work, since the idle function could be called from a
15500875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor * recursive callback. This can be fixed by using g_main_depth()
15510875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor *
15520875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor * |[
155334a9878985f2f3d8118219890d2585219f18f8cdMatthias Clasen * gpointer
15540875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor * allocate_memory (gsize size)
1555e1c15eb0d13eecfeea5059cf1f93e18040be4653Owen Taylor * {
15560875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor *   FreeListBlock *block = g_new (FreeListBlock, 1);
15570875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor *   block->mem = g_malloc (size);
15580875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor *   block->depth = g_main_depth ();
155934a9878985f2f3d8118219890d2585219f18f8cdMatthias Clasen *   free_list = g_list_prepend (free_list, block);
15600875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor *   return block->mem;
15610875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor * }
15620875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor *
15630875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor * void
156434a9878985f2f3d8118219890d2585219f18f8cdMatthias Clasen * free_allocated_memory (void)
1565e1c15eb0d13eecfeea5059cf1f93e18040be4653Owen Taylor * {
15660875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor *   GList *l;
15670875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor *
15680875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor *   int depth = g_main_depth ();
15690875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor *   for (l = free_list; l; );
15700f789811beaf59d197d385ea49b40182a330c6cbMatthias Clasen *     {
15710875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor *       GList *next = l->next;
15720875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor *       FreeListBlock *block = l->data;
15730875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor *       if (block->depth > depth)
15740875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor *         {
15750875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor *           g_free (block->mem);
157634a9878985f2f3d8118219890d2585219f18f8cdMatthias Clasen *           g_free (block);
15770875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor *           free_list = g_list_delete_link (free_list, l);
15780875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor *         }
15790875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor *
158034a9878985f2f3d8118219890d2585219f18f8cdMatthias Clasen *       l = next;
15810875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor *     }
1582e1c15eb0d13eecfeea5059cf1f93e18040be4653Owen Taylor *   }
15830875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor * ]|
15840875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor *
15850875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor * There is a temptation to use g_main_depth() to solve
15863e8b3a13f5ff3eaff583d98ca641170ba1422fceOwen Taylor * problems with reentrancy. For instance, while waiting for data
15873e8b3a13f5ff3eaff583d98ca641170ba1422fceOwen Taylor * to be received from the network in response to a menu item,
15883e8b3a13f5ff3eaff583d98ca641170ba1422fceOwen Taylor * the menu item might be selected again. It might seem that
15893e8b3a13f5ff3eaff583d98ca641170ba1422fceOwen Taylor * one could make the menu item's callback return immediately
15900875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor * and do nothing if g_main_depth() returns a value greater than 1.
15910875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor * However, this should be avoided since the user then sees selecting
15920875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor * the menu item do nothing. Furthermore, you'll find yourself adding
15930875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor * these checks all over your code, since there are doubtless many,
15940875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor * many things that the user could do. Instead, you can use the
15950875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor * following techniques:
15960875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor *
15970875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor * <orderedlist>
15980875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor *  <listitem>
15990875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor *   <para>
16000875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor *     Use gtk_widget_set_sensitive() or modal dialogs to prevent
16010875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor *     the user from interacting with elements while the main
16020875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor *     loop is recursing.
16030875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor *   </para>
16040875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor *  </listitem>
16050875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor *  <listitem>
16060875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor *   <para>
16070875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor *     Avoid main loop recursion in situations where you can't handle
16080875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor *     arbitrary  callbacks. Instead, structure your code so that you
16090875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor *     simply return to the main loop and then get called again when
1610109ebb109a49735cb42c84f6c9ba881c50797011Owen Taylor *     there is more work to do.
161134a9878985f2f3d8118219890d2585219f18f8cdMatthias Clasen *   </para>
161234a9878985f2f3d8118219890d2585219f18f8cdMatthias Clasen *  </listitem>
16130875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor * </orderedlist>
16140875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor *
16150875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor * Return value: The main loop recursion level in the current thread
16160875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor **/
1617bef319723baaeb219d94b37727de7e499cb71fdfMatthias Clasenint
1618bef319723baaeb219d94b37727de7e499cb71fdfMatthias Claseng_main_depth (void)
1619bef319723baaeb219d94b37727de7e499cb71fdfMatthias Clasen{
1620bef319723baaeb219d94b37727de7e499cb71fdfMatthias Clasen  GMainDispatch *dispatch = get_dispatch ();
1621bef319723baaeb219d94b37727de7e499cb71fdfMatthias Clasen  return dispatch->depth;
1622bef319723baaeb219d94b37727de7e499cb71fdfMatthias Clasen}
1623bef319723baaeb219d94b37727de7e499cb71fdfMatthias Clasen
1624a74af928cf9724cb384bc36d0109db34f447d226Matthias Clasen/**
1625a74af928cf9724cb384bc36d0109db34f447d226Matthias Clasen * g_main_current_source:
1626a74af928cf9724cb384bc36d0109db34f447d226Matthias Clasen *
1627a74af928cf9724cb384bc36d0109db34f447d226Matthias Clasen * Returns the currently firing source for this thread.
1628a74af928cf9724cb384bc36d0109db34f447d226Matthias Clasen *
1629bef319723baaeb219d94b37727de7e499cb71fdfMatthias Clasen * Return value: The currently firing source or %NULL.
1630bef319723baaeb219d94b37727de7e499cb71fdfMatthias Clasen *
1631bef319723baaeb219d94b37727de7e499cb71fdfMatthias Clasen * Since: 2.12
1632bef319723baaeb219d94b37727de7e499cb71fdfMatthias Clasen */
1633bef319723baaeb219d94b37727de7e499cb71fdfMatthias ClasenGSource *
16340875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylorg_main_current_source (void)
16350875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor{
1636bef319723baaeb219d94b37727de7e499cb71fdfMatthias Clasen  GMainDispatch *dispatch = get_dispatch ();
1637bef319723baaeb219d94b37727de7e499cb71fdfMatthias Clasen  return dispatch->dispatching_sources ? dispatch->dispatching_sources->data : NULL;
1638bef319723baaeb219d94b37727de7e499cb71fdfMatthias Clasen}
1639bef319723baaeb219d94b37727de7e499cb71fdfMatthias Clasen
1640bef319723baaeb219d94b37727de7e499cb71fdfMatthias Clasen/**
1641bef319723baaeb219d94b37727de7e499cb71fdfMatthias Clasen * g_source_is_destroyed:
1642bef319723baaeb219d94b37727de7e499cb71fdfMatthias Clasen * @source: a #GSource
1643bef319723baaeb219d94b37727de7e499cb71fdfMatthias Clasen *
1644bef319723baaeb219d94b37727de7e499cb71fdfMatthias Clasen * Returns whether @source has been destroyed.
1645bef319723baaeb219d94b37727de7e499cb71fdfMatthias Clasen *
1646d2f111fca7949aee688d31dce49d2afe92b6b6b0Matthias Clasen * This is important when you operate upon your objects
1647bef319723baaeb219d94b37727de7e499cb71fdfMatthias Clasen * from within idle handlers, but may have freed the object
1648bef319723baaeb219d94b37727de7e499cb71fdfMatthias Clasen * before the dispatch of your idle handler.
1649bef319723baaeb219d94b37727de7e499cb71fdfMatthias Clasen *
1650bef319723baaeb219d94b37727de7e499cb71fdfMatthias Clasen * |[
1651bef319723baaeb219d94b37727de7e499cb71fdfMatthias Clasen * static gboolean
16520c2646805782c30f3dabf81dda0fee54a9f8aed3Matthias Clasen * idle_callback (gpointer data)
1653bef319723baaeb219d94b37727de7e499cb71fdfMatthias Clasen * {
1654bef319723baaeb219d94b37727de7e499cb71fdfMatthias Clasen *   SomeWidget *self = data;
16550c2646805782c30f3dabf81dda0fee54a9f8aed3Matthias Clasen *
1656bef319723baaeb219d94b37727de7e499cb71fdfMatthias Clasen *   GDK_THREADS_ENTER (<!-- -->);
1657bef319723baaeb219d94b37727de7e499cb71fdfMatthias Clasen *   /<!-- -->* do stuff with self *<!-- -->/
1658bef319723baaeb219d94b37727de7e499cb71fdfMatthias Clasen *   self->idle_id = 0;
16590c2646805782c30f3dabf81dda0fee54a9f8aed3Matthias Clasen *   GDK_THREADS_LEAVE (<!-- -->);
1660bef319723baaeb219d94b37727de7e499cb71fdfMatthias Clasen *
1661bef319723baaeb219d94b37727de7e499cb71fdfMatthias Clasen *   return FALSE;
1662bef319723baaeb219d94b37727de7e499cb71fdfMatthias Clasen * }
1663bef319723baaeb219d94b37727de7e499cb71fdfMatthias Clasen *
1664bef319723baaeb219d94b37727de7e499cb71fdfMatthias Clasen * static void
16650c2646805782c30f3dabf81dda0fee54a9f8aed3Matthias Clasen * some_widget_do_stuff_later (SomeWidget *self)
1666bef319723baaeb219d94b37727de7e499cb71fdfMatthias Clasen * {
1667bef319723baaeb219d94b37727de7e499cb71fdfMatthias Clasen *   self->idle_id = g_idle_add (idle_callback, self);
1668bef319723baaeb219d94b37727de7e499cb71fdfMatthias Clasen * }
1669bef319723baaeb219d94b37727de7e499cb71fdfMatthias Clasen *
16700c2646805782c30f3dabf81dda0fee54a9f8aed3Matthias Clasen * static void
1671bef319723baaeb219d94b37727de7e499cb71fdfMatthias Clasen * some_widget_finalize (GObject *object)
1672bef319723baaeb219d94b37727de7e499cb71fdfMatthias Clasen * {
16730c2646805782c30f3dabf81dda0fee54a9f8aed3Matthias Clasen *   SomeWidget *self = SOME_WIDGET (object);
1674bef319723baaeb219d94b37727de7e499cb71fdfMatthias Clasen *
1675bef319723baaeb219d94b37727de7e499cb71fdfMatthias Clasen *   if (self->idle_id)
1676d2f111fca7949aee688d31dce49d2afe92b6b6b0Matthias Clasen *     g_source_remove (self->idle_id);
1677bef319723baaeb219d94b37727de7e499cb71fdfMatthias Clasen *
1678bef319723baaeb219d94b37727de7e499cb71fdfMatthias Clasen *   G_OBJECT_CLASS (parent_class)->finalize (object);
1679bef319723baaeb219d94b37727de7e499cb71fdfMatthias Clasen * }
1680bef319723baaeb219d94b37727de7e499cb71fdfMatthias Clasen * ]|
1681bef319723baaeb219d94b37727de7e499cb71fdfMatthias Clasen *
1682bef319723baaeb219d94b37727de7e499cb71fdfMatthias Clasen * This will fail in a multi-threaded application if the
1683bef319723baaeb219d94b37727de7e499cb71fdfMatthias Clasen * widget is destroyed before the idle handler fires due
1684d2f111fca7949aee688d31dce49d2afe92b6b6b0Matthias Clasen * to the use after free in the callback. A solution, to
1685bef319723baaeb219d94b37727de7e499cb71fdfMatthias Clasen * this particular problem, is to check to if the source
1686bef319723baaeb219d94b37727de7e499cb71fdfMatthias Clasen * has already been destroy within the callback.
1687bef319723baaeb219d94b37727de7e499cb71fdfMatthias Clasen *
1688bef319723baaeb219d94b37727de7e499cb71fdfMatthias Clasen * |[
1689bef319723baaeb219d94b37727de7e499cb71fdfMatthias Clasen * static gboolean
1690bef319723baaeb219d94b37727de7e499cb71fdfMatthias Clasen * idle_callback (gpointer data)
169189a803beb4da986d68ffc2d3bfccf8a624e260f6Matthias Clasen * {
1692bef319723baaeb219d94b37727de7e499cb71fdfMatthias Clasen *   SomeWidget *self = data;
1693bef319723baaeb219d94b37727de7e499cb71fdfMatthias Clasen *
1694bef319723baaeb219d94b37727de7e499cb71fdfMatthias Clasen *   GDK_THREADS_ENTER ();
1695bef319723baaeb219d94b37727de7e499cb71fdfMatthias Clasen *   if (!g_source_is_destroyed (g_main_current_source ()))
1696bef319723baaeb219d94b37727de7e499cb71fdfMatthias Clasen *     {
1697bef319723baaeb219d94b37727de7e499cb71fdfMatthias Clasen *       /<!-- -->* do stuff with self *<!-- -->/
1698bef319723baaeb219d94b37727de7e499cb71fdfMatthias Clasen *     }
1699d2f111fca7949aee688d31dce49d2afe92b6b6b0Matthias Clasen *   GDK_THREADS_LEAVE ();
1700bef319723baaeb219d94b37727de7e499cb71fdfMatthias Clasen *
1701bef319723baaeb219d94b37727de7e499cb71fdfMatthias Clasen *   return FALSE;
170258ea1db43e02c99805d6baa76ac04d7d3486009bMatthias Clasen * }
170358ea1db43e02c99805d6baa76ac04d7d3486009bMatthias Clasen * ]|
1704bef319723baaeb219d94b37727de7e499cb71fdfMatthias Clasen *
1705bef319723baaeb219d94b37727de7e499cb71fdfMatthias Clasen * Return value: %TRUE if the source has been destroyed
1706bef319723baaeb219d94b37727de7e499cb71fdfMatthias Clasen *
1707bef319723baaeb219d94b37727de7e499cb71fdfMatthias Clasen * Since: 2.12
1708bef319723baaeb219d94b37727de7e499cb71fdfMatthias Clasen */
1709bef319723baaeb219d94b37727de7e499cb71fdfMatthias Clasengboolean
1710bef319723baaeb219d94b37727de7e499cb71fdfMatthias Claseng_source_is_destroyed (GSource *source)
1711bef319723baaeb219d94b37727de7e499cb71fdfMatthias Clasen{
17129753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor  return SOURCE_DESTROYED (source);
17139753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor}
17149753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor
17159753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor
17169753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor/* Temporarily remove all this source's file descriptors from the
1717185c1de57776dc6cc2c5447692d68acd58d8a941Matthias Clasen * poll(), so that if data comes available for one of the file descriptors
17189753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor * we don't continually spin in the poll()
17199753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor */
17209753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor/* HOLDS: source->context's lock */
17219753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylorstatic void
17229753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylorblock_source (GSource *source)
17239753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor{
17249753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor  GSList *tmp_list;
17259753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor
17269753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor  g_return_if_fail (!SOURCE_BLOCKED (source));
17279753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor
17289753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor  tmp_list = source->poll_fds;
17299753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor  while (tmp_list)
17309753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor    {
17319753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor      g_main_context_remove_poll_unlocked (source->context, tmp_list->data);
17329753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor      tmp_list = tmp_list->next;
1733185c1de57776dc6cc2c5447692d68acd58d8a941Matthias Clasen    }
17349753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor}
17359753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor
17369753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor/* HOLDS: source->context's lock */
17379753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylorstatic void
17389753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylorunblock_source (GSource *source)
17399753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor{
17409753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor  GSList *tmp_list;
17419753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor
17429753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor  g_return_if_fail (!SOURCE_BLOCKED (source)); /* Source already unblocked */
17439753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor  g_return_if_fail (!SOURCE_DESTROYED (source));
17449753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor
17459753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor  tmp_list = source->poll_fds;
17469753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor  while (tmp_list)
17479753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor    {
17489753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor      g_main_context_add_poll_unlocked (source->context, source->priority, tmp_list->data);
1749e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      tmp_list = tmp_list->next;
1750e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    }
1751e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor}
1752e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1753bef319723baaeb219d94b37727de7e499cb71fdfMatthias Clasen/* HOLDS: context's lock */
1754f5c28ce4ab8e8015a1432060b6cfe547183b2f9eOwen Taylorstatic void
1755e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorg_main_dispatch (GMainContext *context)
1756e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor{
1757e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  GMainDispatch *current = get_dispatch ();
1758e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  guint i;
1759e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1760e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  for (i = 0; i < context->pending_dispatches->len; i++)
1761e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    {
1762e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      GSource *source = context->pending_dispatches->pdata[i];
1763e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1764e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      context->pending_dispatches->pdata[i] = NULL;
1765e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      g_assert (source);
1766e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1767e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      source->flags &= ~G_SOURCE_READY;
1768e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1769e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      if (!SOURCE_DESTROYED (source))
1770e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	{
1771e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	  gboolean was_in_call;
1772e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	  gpointer user_data = NULL;
1773e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	  GSourceFunc callback = NULL;
1774e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	  GSourceCallbackFuncs *cb_funcs;
1775e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	  gpointer cb_data;
1776e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	  gboolean need_destroy;
1777af8671792d05d52df78ea3a26e182fffe7b37a94Chris Wilson
1778e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	  gboolean (*dispatch) (GSource *,
1779e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor				GSourceFunc,
1780e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor				gpointer);
1781e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	  GSList current_source_link;
1782e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1783e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	  dispatch = source->source_funcs->dispatch;
1784e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	  cb_funcs = source->callback_funcs;
1785e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	  cb_data = source->callback_data;
17869753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor
17879753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor	  if (cb_funcs)
17889753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor	    cb_funcs->ref (cb_data);
1789e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1790e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	  if ((source->flags & G_SOURCE_CAN_RECURSE) == 0)
1791e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	    block_source (source);
1792e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1793b4c3107c7a1dc5dd9e8050ed06f24d6be408e840Owen Taylor	  was_in_call = source->flags & G_HOOK_FLAG_IN_CALL;
1794e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	  source->flags |= G_HOOK_FLAG_IN_CALL;
1795ffe592544fbc7527f489bc13e91bebccf6ceb4f7Owen Taylor
1796ffe592544fbc7527f489bc13e91bebccf6ceb4f7Owen Taylor	  if (cb_funcs)
1797bef319723baaeb219d94b37727de7e499cb71fdfMatthias Clasen	    cb_funcs->get (cb_data, source, &callback, &user_data);
1798af8671792d05d52df78ea3a26e182fffe7b37a94Chris Wilson
1799af8671792d05d52df78ea3a26e182fffe7b37a94Chris Wilson	  UNLOCK_CONTEXT (context);
1800af8671792d05d52df78ea3a26e182fffe7b37a94Chris Wilson
1801af8671792d05d52df78ea3a26e182fffe7b37a94Chris Wilson	  current->depth++;
1802af8671792d05d52df78ea3a26e182fffe7b37a94Chris Wilson	  /* The on-stack allocation of the GSList is unconventional, but
1803af8671792d05d52df78ea3a26e182fffe7b37a94Chris Wilson	   * we know that the lifetime of the link is bounded to this
1804af8671792d05d52df78ea3a26e182fffe7b37a94Chris Wilson	   * function as the link is kept in a thread specific list and
1805af8671792d05d52df78ea3a26e182fffe7b37a94Chris Wilson	   * not manipulated outside of this function and its descendants.
1806af8671792d05d52df78ea3a26e182fffe7b37a94Chris Wilson	   * Avoiding the overhead of a g_slist_alloc() is useful as many
1807af8671792d05d52df78ea3a26e182fffe7b37a94Chris Wilson	   * applications do little more than dispatch events.
1808e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	   *
1809e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	   * This is a performance hack - do not revert to g_slist_prepend()!
1810e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	   */
181102e2b9539333062f0e2e0daf74b03e66cb177c89current->dispatching_sources == &current_source_link);	  current_source_link.data = source;
1812bef319723baaeb219d94b37727de7e499cb71fdfMatthias Clasen	  current_source_link.next = current->dispatching_sources;
18130875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor	  current->dispatching_sources = &current_source_link;
1814e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	  need_destroy = ! dispatch (source,
1815e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor				     callback,
1816e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor				     user_data);
18176d763bd97ca043bdab1847a0c42fce81b3a9c49aMatthias Clasen	  g_assert (current->dispatching_sources == &current_source_link);
18186d763bd97ca043bdab1847a0c42fce81b3a9c49aMatthias Clasen	  current->dispatching_sources = current_source_link.next;
18196d763bd97ca043bdab1847a0c42fce81b3a9c49aMatthias Clasen	  current->depth--;
1820e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1821e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	  if (cb_funcs)
18229753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor	    cb_funcs->unref (cb_data);
18239753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor
18249753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor 	  LOCK_CONTEXT (context);
18259753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor
1826e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	  if (!was_in_call)
1827e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	    source->flags &= ~G_HOOK_FLAG_IN_CALL;
1828e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1829e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	  if ((source->flags & G_SOURCE_CAN_RECURSE) == 0 &&
1830e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	      !SOURCE_DESTROYED (source))
1831e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	    unblock_source (source);
1832e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1833e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	  /* Note: this depends on the fact that we can't switch
1834e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	   * sources from one main context to another
1835e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	   */
1836e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	  if (need_destroy && !SOURCE_DESTROYED (source))
1837e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	    {
1838e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	      g_assert (source->context == context);
1839e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	      g_source_destroy_internal (source, context, TRUE);
1840e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	    }
1841e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	}
1842e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1843e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      SOURCE_UNREF (source, context);
1844e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    }
1845e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1846e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  g_ptr_array_set_size (context->pending_dispatches, 0);
1847e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor}
1848e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1849e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor/* Holds context's lock */
1850e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorstatic inline GSource *
1851e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylornext_valid_source (GMainContext *context,
1852e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor		   GSource      *source)
1853e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor{
1854e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  GSource *new_source = source ? source->next : context->source_list;
1855e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1856e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  while (new_source)
1857e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    {
1858e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      if (!SOURCE_DESTROYED (new_source))
1859e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	{
1860e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	  new_source->ref_count++;
1861e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	  break;
1862e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	}
1863e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1864e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      new_source = new_source->next;
1865e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    }
18668951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor
18678951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  if (source)
18688951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor    SOURCE_UNREF (source, context);
18698951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor
18708951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  return new_source;
1871e8900bc3b7c29165a8fe6138fa7564ffe5f47188Matthias Clasen}
18728951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor
18738951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor/**
18748951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor * g_main_context_acquire:
18758951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor * @context: a #GMainContext
18768951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor *
18778951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor * Tries to become the owner of the specified context.
18788951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor * If some other thread is the owner of the context,
18798951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor * returns %FALSE immediately. Ownership is properly
18808951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor * recursive: the owner can require ownership again
18818951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor * and will release ownership when g_main_context_release()
18828951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor * is called as many times as g_main_context_acquire().
18838951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor *
18848951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor * You must be the owner of a context before you
18858951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor * can call g_main_context_prepare(), g_main_context_query(),
18868951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor * g_main_context_check(), g_main_context_dispatch().
18875cdbc63e478a0432f3c5359043b02542de87347fSebastian Wilhelmi *
18888951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor * Return value: %TRUE if the operation succeeded, and
18898951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor *   this thread is now the owner of @context.
18908951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor **/
18918951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylorgboolean
18928951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylorg_main_context_acquire (GMainContext *context)
18938951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor{
18948951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor#ifdef G_THREADS_ENABLED
18958951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  gboolean result = FALSE;
18968951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  GThread *self = G_THREAD_SELF;
18971107552617653b80ef9fff77437569e1ac8e2408Sebastian Wilhelmi
18981107552617653b80ef9fff77437569e1ac8e2408Sebastian Wilhelmi  if (context == NULL)
18991107552617653b80ef9fff77437569e1ac8e2408Sebastian Wilhelmi    context = g_main_context_default ();
19001107552617653b80ef9fff77437569e1ac8e2408Sebastian Wilhelmi
19018951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  LOCK_CONTEXT (context);
19028951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor
19038951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  if (!context->owner)
19048951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor    {
19058951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor      context->owner = self;
19068951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor      g_assert (context->owner_count == 0);
19078951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor    }
19088951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor
19098951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  if (context->owner == self)
19108951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor    {
19115cdbc63e478a0432f3c5359043b02542de87347fSebastian Wilhelmi      context->owner_count++;
19128951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor      result = TRUE;
19135cdbc63e478a0432f3c5359043b02542de87347fSebastian Wilhelmi    }
19148951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor
19158951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  UNLOCK_CONTEXT (context);
19168951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor
19178951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  return result;
19188951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor#else /* !G_THREADS_ENABLED */
19198951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  return TRUE;
1920a52e2986cd4a2147cfc8d41ae23d98907caaf3a0Matthias Clasen#endif /* G_THREADS_ENABLED */
19218951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor}
192258178261fdf00ec7b9eb8a8f3a665c792f053287Matthias Clasen
19238951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor/**
19248951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor * g_main_context_release:
19258951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor * @context: a #GMainContext
19268951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor *
19278951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor * Releases ownership of a context previously acquired by this thread
19285cdbc63e478a0432f3c5359043b02542de87347fSebastian Wilhelmi * with g_main_context_acquire(). If the context was acquired multiple
19298951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor * times, the ownership will be released only when g_main_context_release()
19308951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor * is called as many times as it was acquired.
19318951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor **/
19328951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylorvoid
19338951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylorg_main_context_release (GMainContext *context)
19348951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor{
19358951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor#ifdef G_THREADS_ENABLED
19368951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  if (context == NULL)
19378951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor    context = g_main_context_default ();
19388951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor
19398951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  LOCK_CONTEXT (context);
19408951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor
19411107552617653b80ef9fff77437569e1ac8e2408Sebastian Wilhelmi  context->owner_count--;
19421107552617653b80ef9fff77437569e1ac8e2408Sebastian Wilhelmi  if (context->owner_count == 0)
19431107552617653b80ef9fff77437569e1ac8e2408Sebastian Wilhelmi    {
19448951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor      context->owner = NULL;
19458951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor
19461107552617653b80ef9fff77437569e1ac8e2408Sebastian Wilhelmi      if (context->waiters)
19471107552617653b80ef9fff77437569e1ac8e2408Sebastian Wilhelmi	{
19481107552617653b80ef9fff77437569e1ac8e2408Sebastian Wilhelmi	  GMainWaiter *waiter = context->waiters->data;
19491107552617653b80ef9fff77437569e1ac8e2408Sebastian Wilhelmi	  gboolean loop_internal_waiter =
19501107552617653b80ef9fff77437569e1ac8e2408Sebastian Wilhelmi	    (waiter->mutex == g_static_mutex_get_mutex (&context->mutex));
19511107552617653b80ef9fff77437569e1ac8e2408Sebastian Wilhelmi	  context->waiters = g_slist_delete_link (context->waiters,
19521107552617653b80ef9fff77437569e1ac8e2408Sebastian Wilhelmi						  context->waiters);
19538951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor	  if (!loop_internal_waiter)
19548951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor	    g_mutex_lock (waiter->mutex);
19558951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor
19561107552617653b80ef9fff77437569e1ac8e2408Sebastian Wilhelmi	  g_cond_signal (waiter->cond);
19575cdbc63e478a0432f3c5359043b02542de87347fSebastian Wilhelmi
19588951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor	  if (!loop_internal_waiter)
19598951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor	    g_mutex_unlock (waiter->mutex);
19608951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor	}
19618951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor    }
19628951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor
19638951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  UNLOCK_CONTEXT (context);
19648951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor#endif /* G_THREADS_ENABLED */
19658951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor}
19668951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor
1967a52e2986cd4a2147cfc8d41ae23d98907caaf3a0Matthias Clasen/**
1968a52e2986cd4a2147cfc8d41ae23d98907caaf3a0Matthias Clasen * g_main_context_wait:
1969a52e2986cd4a2147cfc8d41ae23d98907caaf3a0Matthias Clasen * @context: a #GMainContext
19708951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor * @cond: a condition variable
19718951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor * @mutex: a mutex, currently held
19728951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor *
19738951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor * Tries to become the owner of the specified context,
19748951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor * as with g_main_context_acquire(). But if another thread
19758951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor * is the owner, atomically drop @mutex and wait on @cond until
19768951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor * that owner releases ownership or until @cond is signaled, then
19778951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor * try again (once) to become the owner.
19788951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor *
19798951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor * Return value: %TRUE if the operation succeeded, and
19805cdbc63e478a0432f3c5359043b02542de87347fSebastian Wilhelmi *   this thread is now the owner of @context.
19818951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor **/
19828951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylorgboolean
19838951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylorg_main_context_wait (GMainContext *context,
19848951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor		     GCond        *cond,
19858951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor		     GMutex       *mutex)
19868951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor{
19878951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor#ifdef G_THREADS_ENABLED
19888951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  gboolean result = FALSE;
19898951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  GThread *self = G_THREAD_SELF;
19908951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  gboolean loop_internal_waiter;
19918951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor
19928951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  if (context == NULL)
19938951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor    context = g_main_context_default ();
19948951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor
19958951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  loop_internal_waiter = (mutex == g_static_mutex_get_mutex (&context->mutex));
19968951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor
19978951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  if (!loop_internal_waiter)
19988951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor    LOCK_CONTEXT (context);
19998951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor
20008951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  if (context->owner && context->owner != self)
20018951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor    {
20028951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor      GMainWaiter waiter;
20038951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor
20048951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor      waiter.cond = cond;
20058951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor      waiter.mutex = mutex;
20068951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor
20078951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor      context->waiters = g_slist_append (context->waiters, &waiter);
20088951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor
20098951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor      if (!loop_internal_waiter)
20108951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor	UNLOCK_CONTEXT (context);
20118951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor      g_cond_wait (cond, mutex);
20121107552617653b80ef9fff77437569e1ac8e2408Sebastian Wilhelmi      if (!loop_internal_waiter)
20131107552617653b80ef9fff77437569e1ac8e2408Sebastian Wilhelmi	LOCK_CONTEXT (context);
20141107552617653b80ef9fff77437569e1ac8e2408Sebastian Wilhelmi
20151107552617653b80ef9fff77437569e1ac8e2408Sebastian Wilhelmi      context->waiters = g_slist_remove (context->waiters, &waiter);
20168951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor    }
20178951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor
20188951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  if (!context->owner)
20198951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor    {
20208951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor      context->owner = self;
20218951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor      g_assert (context->owner_count == 0);
20228951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor    }
20238951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor
20248951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  if (context->owner == self)
20258951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor    {
20268951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor      context->owner_count++;
20275cdbc63e478a0432f3c5359043b02542de87347fSebastian Wilhelmi      result = TRUE;
20288951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor    }
20295cdbc63e478a0432f3c5359043b02542de87347fSebastian Wilhelmi
20308951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  if (!loop_internal_waiter)
2031e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    UNLOCK_CONTEXT (context);
2032e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2033e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  return result;
2034e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor#else /* !G_THREADS_ENABLED */
2035e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  return TRUE;
2036e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor#endif /* G_THREADS_ENABLED */
2037e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor}
2038e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2039e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor/**
2040e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * g_main_context_prepare:
2041e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * @context: a #GMainContext
2042e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * @priority: location to store priority of highest priority
2043e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *            source already ready.
2044e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *
2045e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * Prepares to poll sources within a main loop. The resulting information
2046e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * for polling is determined by calling g_main_context_query ().
2047e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *
2048c55b9a4f44eb7e01ec5fa93fc63b0f34cceabc37Owen Taylor * Return value: %TRUE if some source is ready to be dispatched
2049e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *               prior to polling.
2050e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor **/
2051e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorgboolean
2052e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorg_main_context_prepare (GMainContext *context,
2053e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor			gint         *priority)
2054e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor{
2055e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  gint i;
2056e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  gint n_ready = 0;
2057e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  gint current_priority = G_MAXINT;
2058e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  GSource *source;
2059e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2060e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  if (context == NULL)
2061e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    context = g_main_context_default ();
2062e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2063e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  LOCK_CONTEXT (context);
2064e28e398eb03fcfc467524d17fed666d1afc6dc82Tim Janik
2065e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  context->time_is_current = FALSE;
2066e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2067e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  if (context->in_check_or_prepare)
2068e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    {
2069e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      g_warning ("g_main_context_prepare() called recursively from within a source's check() or "
2070e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor		 "prepare() member.");
2071e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      UNLOCK_CONTEXT (context);
2072e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      return FALSE;
2073e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    }
2074e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2075e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor#ifdef G_THREADS_ENABLED
2076e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  if (context->poll_waiting)
2077dc7d6c24645656ea1fb55d23a107e5e747b841beRaja R Harinath    {
2078e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      g_warning("g_main_context_prepare(): main loop already active in another thread");
2079e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      UNLOCK_CONTEXT (context);
2080e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      return FALSE;
2081e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    }
2082e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2083e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  context->poll_waiting = TRUE;
2084e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor#endif /* G_THREADS_ENABLED */
2085e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2086e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor#if 0
2087e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  /* If recursing, finish up current dispatch, before starting over */
2088e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  if (context->pending_dispatches)
2089e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    {
2090e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      if (dispatch)
2091e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	g_main_dispatch (context, &current_time);
2092c55b9a4f44eb7e01ec5fa93fc63b0f34cceabc37Owen Taylor
2093c55b9a4f44eb7e01ec5fa93fc63b0f34cceabc37Owen Taylor      UNLOCK_CONTEXT (context);
2094a3d982007e38310b4e2b15147793ae767fcaba59Owen Taylor      return TRUE;
2095a3d982007e38310b4e2b15147793ae767fcaba59Owen Taylor    }
2096a3d982007e38310b4e2b15147793ae767fcaba59Owen Taylor#endif
2097a3d982007e38310b4e2b15147793ae767fcaba59Owen Taylor
2098e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  /* If recursing, clear list of pending dispatches */
2099e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2100e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  for (i = 0; i < context->pending_dispatches->len; i++)
2101e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    {
2102e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      if (context->pending_dispatches->pdata[i])
2103e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	SOURCE_UNREF ((GSource *)context->pending_dispatches->pdata[i], context);
2104e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    }
2105e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  g_ptr_array_set_size (context->pending_dispatches, 0);
2106e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2107e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  /* Prepare all sources */
2108e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2109e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  context->timeout = -1;
2110e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2111e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  source = next_valid_source (context, NULL);
2112e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  while (source)
2113e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    {
21149753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor      gint source_timeout = -1;
2115e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2116e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      if ((n_ready > 0) && (source->priority > current_priority))
2117e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	{
2118e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	  SOURCE_UNREF (source, context);
2119e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	  break;
2120e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	}
2121e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      if (SOURCE_BLOCKED (source))
2122e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	goto next;
2123e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2124e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      if (!(source->flags & G_SOURCE_READY))
2125e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	{
2126e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	  gboolean result;
2127e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	  gboolean (*prepare)  (GSource  *source,
2128e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor				gint     *timeout);
2129e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2130e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	  prepare = source->source_funcs->prepare;
2131e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	  context->in_check_or_prepare++;
2132e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	  UNLOCK_CONTEXT (context);
2133e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2134e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	  result = (*prepare) (source, &source_timeout);
2135e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2136e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	  LOCK_CONTEXT (context);
2137e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	  context->in_check_or_prepare--;
2138e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2139e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	  if (result)
2140e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	    source->flags |= G_SOURCE_READY;
2141e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	}
2142beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
2143beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor      if (source->flags & G_SOURCE_READY)
2144beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor	{
2145e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	  n_ready++;
2146e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	  current_priority = source->priority;
2147beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor	  context->timeout = 0;
2148e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	}
2149beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
2150beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor      if (source_timeout >= 0)
2151e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	{
2152e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	  if (context->timeout < 0)
2153e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	    context->timeout = source_timeout;
2154e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	  else
2155e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	    context->timeout = MIN (context->timeout, source_timeout);
2156e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	}
2157e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2158e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    next:
2159e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      source = next_valid_source (context, source);
2160e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    }
2161e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2162e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  UNLOCK_CONTEXT (context);
2163e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2164e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  if (priority)
2165e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    *priority = current_priority;
2166e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2167d201974f56d7b805f70b5c5703be79e8db73526eSoeren Sandmann  return (n_ready > 0);
2168e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor}
2169e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2170e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor/**
2171e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * g_main_context_query:
2172e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * @context: a #GMainContext
21738079eb3456914a03618b92b48f75a71b25331acbOwen Taylor * @max_priority: maximum priority source to check
21748079eb3456914a03618b92b48f75a71b25331acbOwen Taylor * @timeout_: location to store timeout to be used in polling
21758079eb3456914a03618b92b48f75a71b25331acbOwen Taylor * @fds: location to store #GPollFD records that need to be polled.
2176e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * @n_fds: length of @fds.
2177e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *
2178e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * Determines information necessary to poll this main loop.
2179e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *
2180e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * Return value: the number of records actually stored in @fds,
2181e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *   or, if more than @n_fds records need to be stored, the number
2182e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *   of records that need to be stored.
2183e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor **/
2184e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorgint
2185e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorg_main_context_query (GMainContext *context,
2186e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor		      gint          max_priority,
2187e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor		      gint         *timeout,
2188e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor		      GPollFD      *fds,
2189e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor		      gint          n_fds)
2190e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor{
2191e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  gint n_poll;
2192e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  GPollRec *pollrec;
2193b36ea0b1c7f5f1b3bd4ced309250124ce711fe59Matthias Clasen
2194b36ea0b1c7f5f1b3bd4ced309250124ce711fe59Matthias Clasen  LOCK_CONTEXT (context);
2195b36ea0b1c7f5f1b3bd4ced309250124ce711fe59Matthias Clasen
2196b36ea0b1c7f5f1b3bd4ced309250124ce711fe59Matthias Clasen  pollrec = context->poll_records;
2197b36ea0b1c7f5f1b3bd4ced309250124ce711fe59Matthias Clasen  n_poll = 0;
2198b36ea0b1c7f5f1b3bd4ced309250124ce711fe59Matthias Clasen  while (pollrec && max_priority >= pollrec->priority)
2199e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    {
2200b36ea0b1c7f5f1b3bd4ced309250124ce711fe59Matthias Clasen      /* We need to include entries with fd->events == 0 in the array because
2201b36ea0b1c7f5f1b3bd4ced309250124ce711fe59Matthias Clasen       * otherwise if the application changes fd->events behind our back and
2202b36ea0b1c7f5f1b3bd4ced309250124ce711fe59Matthias Clasen       * makes it non-zero, we'll be out of sync when we check the fds[] array.
2203b36ea0b1c7f5f1b3bd4ced309250124ce711fe59Matthias Clasen       * (Changing fd->events after adding an FD wasn't an anticipated use of
2204b36ea0b1c7f5f1b3bd4ced309250124ce711fe59Matthias Clasen       * this API, but it occurs in practice.) */
2205b36ea0b1c7f5f1b3bd4ced309250124ce711fe59Matthias Clasen      if (n_poll < n_fds)
2206b36ea0b1c7f5f1b3bd4ced309250124ce711fe59Matthias Clasen	{
2207b36ea0b1c7f5f1b3bd4ced309250124ce711fe59Matthias Clasen	  fds[n_poll].fd = pollrec->fd->fd;
2208e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	  /* In direct contradiction to the Unix98 spec, IRIX runs into
2209b36ea0b1c7f5f1b3bd4ced309250124ce711fe59Matthias Clasen	   * difficulty if you pass in POLLERR, POLLHUP or POLLNVAL
2210e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	   * flags in the events field of the pollfd while it should
2211b36ea0b1c7f5f1b3bd4ced309250124ce711fe59Matthias Clasen	   * just ignoring them. So we mask them out here.
2212beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor	   */
2213beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor	  fds[n_poll].events = pollrec->fd->events & ~(G_IO_ERR|G_IO_HUP|G_IO_NVAL);
22149edb08492d09a36caf389f639f45c8c1c8315f10Havoc Pennington	  fds[n_poll].revents = 0;
2215e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	}
22169edb08492d09a36caf389f639f45c8c1c8315f10Havoc Pennington
22179edb08492d09a36caf389f639f45c8c1c8315f10Havoc Pennington      pollrec = pollrec->next;
2218e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      n_poll++;
2219e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    }
2220e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2221cbfb32bcff83eeb9d792eee824c7d5fa01e1e1f3Matthias Clasen#ifdef G_THREADS_ENABLED
2222e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  context->poll_changed = FALSE;
2223e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor#endif
2224e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2225e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  if (timeout)
2226beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor    {
2227e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      *timeout = context->timeout;
2228e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      if (*timeout != 0)
2229beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor	context->time_is_current = FALSE;
2230e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    }
2231e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2232e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  UNLOCK_CONTEXT (context);
2233e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2234e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  return n_poll;
2235e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor}
2236e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2237e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor/**
2238a52e2986cd4a2147cfc8d41ae23d98907caaf3a0Matthias Clasen * g_main_context_check:
2239e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * @context: a #GMainContext
2240e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * @max_priority: the maximum numerical priority of sources to check
2241e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * @fds: array of #GPollFD's that was passed to the last call to
2242e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *       g_main_context_query()
2243e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * @n_fds: return value of g_main_context_query()
2244e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *
2245e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * Passes the results of polling back to the main loop.
2246e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *
2247e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * Return value: %TRUE if some sources are ready to be dispatched.
2248e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor **/
2249e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorgboolean
2250e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorg_main_context_check (GMainContext *context,
2251e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor		      gint          max_priority,
2252b36ea0b1c7f5f1b3bd4ced309250124ce711fe59Matthias Clasen		      GPollFD      *fds,
2253e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor		      gint          n_fds)
2254beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor{
2255e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  GSource *source;
2256e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  GPollRec *pollrec;
2257e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  gint n_ready = 0;
2258e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  gint i;
2259e28e398eb03fcfc467524d17fed666d1afc6dc82Tim Janik
2260e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  LOCK_CONTEXT (context);
2261e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2262beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  if (context->in_check_or_prepare)
2263e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    {
2264e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      g_warning ("g_main_context_check() called recursively from within a source's check() or "
2265beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor		 "prepare() member.");
2266e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      UNLOCK_CONTEXT (context);
2267540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen      return FALSE;
2268540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen    }
2269e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2270e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor#ifdef G_THREADS_ENABLED
2271e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  if (!context->poll_waiting)
2272e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    {
2273beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor#ifndef G_OS_WIN32
2274e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      gchar a;
2275e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      read (context->wake_up_pipe[0], &a, 1);
2276e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor#endif
2277e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    }
2278e28e398eb03fcfc467524d17fed666d1afc6dc82Tim Janik  else
2279e28e398eb03fcfc467524d17fed666d1afc6dc82Tim Janik    context->poll_waiting = FALSE;
22809df1f4fcc73807dc0ff4bad96caaba36b97c5a15Behdad Esfahbod
2281e28e398eb03fcfc467524d17fed666d1afc6dc82Tim Janik  /* If the set of poll file descriptors changed, bail out
22829edb08492d09a36caf389f639f45c8c1c8315f10Havoc Pennington   * and let the main loop rerun
22839edb08492d09a36caf389f639f45c8c1c8315f10Havoc Pennington   */
2284e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  if (context->poll_changed)
2285e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    {
2286e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      UNLOCK_CONTEXT (context);
2287e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      return FALSE;
2288e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    }
2289b36ea0b1c7f5f1b3bd4ced309250124ce711fe59Matthias Clasen#endif /* G_THREADS_ENABLED */
2290b36ea0b1c7f5f1b3bd4ced309250124ce711fe59Matthias Clasen
2291e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  pollrec = context->poll_records;
2292b36ea0b1c7f5f1b3bd4ced309250124ce711fe59Matthias Clasen  i = 0;
2293e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  while (i < n_fds)
2294e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    {
2295e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      if (pollrec->fd->events)
2296e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	pollrec->fd->revents = fds[i].revents;
2297e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2298e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      pollrec = pollrec->next;
2299beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor      i++;
2300e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    }
2301e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2302beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  source = next_valid_source (context, NULL);
23039753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor  while (source)
2304e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    {
2305beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor      if ((n_ready > 0) && (source->priority > max_priority))
2306e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	{
2307beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor	  SOURCE_UNREF (source, context);
2308e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	  break;
2309e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	}
2310f26256fe182bc1249d3058d9f18402d0ac26974cOwen Taylor      if (SOURCE_BLOCKED (source))
2311e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	goto next;
2312f26256fe182bc1249d3058d9f18402d0ac26974cOwen Taylor
2313e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      if (!(source->flags & G_SOURCE_READY))
2314e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	{
2315e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	  gboolean result;
2316e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	  gboolean (*check) (GSource  *source);
2317e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2318e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	  check = source->source_funcs->check;
2319e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2320e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	  context->in_check_or_prepare++;
2321e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	  UNLOCK_CONTEXT (context);
2322e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2323f26256fe182bc1249d3058d9f18402d0ac26974cOwen Taylor	  result = (*check) (source);
2324f26256fe182bc1249d3058d9f18402d0ac26974cOwen Taylor
2325e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	  LOCK_CONTEXT (context);
2326f26256fe182bc1249d3058d9f18402d0ac26974cOwen Taylor	  context->in_check_or_prepare--;
2327e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2328e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	  if (result)
23298be41eae4d0077069ecf77a8904b5f624d5ea5ffTim Janik	    source->flags |= G_SOURCE_READY;
2330e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	}
2331ad24759fc104d4c3b155c70394179708dd85d8a1Havoc Pennington
2332ad24759fc104d4c3b155c70394179708dd85d8a1Havoc Pennington      if (source->flags & G_SOURCE_READY)
2333ad24759fc104d4c3b155c70394179708dd85d8a1Havoc Pennington	{
2334ad24759fc104d4c3b155c70394179708dd85d8a1Havoc Pennington	  source->ref_count++;
2335ad24759fc104d4c3b155c70394179708dd85d8a1Havoc Pennington	  g_ptr_array_add (context->pending_dispatches, source);
2336beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
2337e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	  n_ready++;
2338e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2339e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor          /* never dispatch sources with less priority than the first
2340beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor           * one we choose to dispatch
2341beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor           */
2342e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor          max_priority = source->priority;
2343e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	}
2344e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2345e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    next:
2346e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      source = next_valid_source (context, source);
2347e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    }
2348e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2349e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  UNLOCK_CONTEXT (context);
2350e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2351a52e2986cd4a2147cfc8d41ae23d98907caaf3a0Matthias Clasen  return n_ready > 0;
2352e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor}
2353e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2354e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor/**
2355e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * g_main_context_dispatch:
2356e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * @context: a #GMainContext
2357e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *
2358e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * Dispatches all pending sources.
2359beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor **/
2360e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorvoid
2361beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylorg_main_context_dispatch (GMainContext *context)
2362931ea952650b013b834041b91b0c37a748ffd449Owen Taylor{
2363e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  LOCK_CONTEXT (context);
2364e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2365e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  if (context->pending_dispatches->len > 0)
23668951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor    {
2367e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      g_main_dispatch (context);
2368e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    }
2369e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
23708951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  UNLOCK_CONTEXT (context);
23718951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor}
2372e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2373e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor/* HOLDS context lock */
2374e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorstatic gboolean
2375e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorg_main_context_iterate (GMainContext *context,
23768951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor			gboolean      block,
23778951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor			gboolean      dispatch,
23781f32eb927e2b404d4a697fa55282425ccb4d1784Matthias Clasen			GThread      *self)
23798951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor{
2380e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  gint max_priority;
23818951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  gint timeout;
23828951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  gboolean some_ready;
2383e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  gint nfds, allocated_nfds;
23848951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  GPollFD *fds = NULL;
23851f32eb927e2b404d4a697fa55282425ccb4d1784Matthias Clasen
23861f32eb927e2b404d4a697fa55282425ccb4d1784Matthias Clasen  UNLOCK_CONTEXT (context);
23871f32eb927e2b404d4a697fa55282425ccb4d1784Matthias Clasen
23888951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor#ifdef G_THREADS_ENABLED
2389e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  if (!g_main_context_acquire (context))
23908951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor    {
23918951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor      gboolean got_ownership;
23928951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor
23938951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor      LOCK_CONTEXT (context);
23948951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor
23951f32eb927e2b404d4a697fa55282425ccb4d1784Matthias Clasen      g_return_val_if_fail (g_thread_supported (), FALSE);
23968951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor
23978951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor      if (!block)
23988951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor	return FALSE;
23998951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor
24008951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor      if (!context->cond)
24011f32eb927e2b404d4a697fa55282425ccb4d1784Matthias Clasen	context->cond = g_cond_new ();
24028951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor
24038951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor      got_ownership = g_main_context_wait (context,
24048951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor					   context->cond,
2405624a3c9689a9538af7df04aab389423edc82b51aDarin Adler					   g_static_mutex_get_mutex (&context->mutex));
24068951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor
24078951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor      if (!got_ownership)
24088951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor	return FALSE;
24098951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor    }
24108951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  else
24118951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor    LOCK_CONTEXT (context);
2412e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor#endif /* G_THREADS_ENABLED */
24138951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor
24148951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  if (!context->cached_poll_array)
2415e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    {
24168951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor      context->cached_poll_array_size = context->n_poll_records;
24178951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor      context->cached_poll_array = g_new (GPollFD, context->n_poll_records);
24183f1a49ea41a20dacbabea33d4dbcbd62c8c4bb2bOwen Taylor    }
24198951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor
24208951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  allocated_nfds = context->cached_poll_array_size;
24218951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  fds = context->cached_poll_array;
24228951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor
24238951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  UNLOCK_CONTEXT (context);
24248951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor
24258951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  g_main_context_prepare (context, &max_priority);
24268951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor
24278951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  while ((nfds = g_main_context_query (context, max_priority, &timeout, fds,
2428e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor				       allocated_nfds)) > allocated_nfds)
2429e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    {
2430e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      LOCK_CONTEXT (context);
2431e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      g_free (fds);
2432e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      context->cached_poll_array_size = allocated_nfds = nfds;
24338951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor      context->cached_poll_array = fds = g_new (GPollFD, nfds);
2434e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      UNLOCK_CONTEXT (context);
24353f1a49ea41a20dacbabea33d4dbcbd62c8c4bb2bOwen Taylor    }
2436e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2437e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  if (!block)
2438e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    timeout = 0;
24398951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor
24408951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  g_main_context_poll (context, timeout, max_priority, fds, nfds);
24418951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor
24428951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  some_ready = g_main_context_check (context, max_priority, fds, nfds);
24438951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor
24448951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  if (dispatch)
2445e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    g_main_context_dispatch (context);
2446e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2447beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor#ifdef G_THREADS_ENABLED
2448beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  g_main_context_release (context);
2449e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor#endif /* G_THREADS_ENABLED */
2450e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2451e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  LOCK_CONTEXT (context);
2452e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2453a52e2986cd4a2147cfc8d41ae23d98907caaf3a0Matthias Clasen  return some_ready;
2454e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor}
2455e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2456e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor/**
2457beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor * g_main_context_pending:
2458e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * @context: a #GMainContext (if %NULL, the default context will be used)
2459beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor *
24608951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor * Checks if any sources have pending events for the given context.
24618951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor *
2462e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * Return value: %TRUE if events are pending.
2463e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor **/
24648951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylorgboolean
24658951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylorg_main_context_pending (GMainContext *context)
24668951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor{
24678951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  gboolean retval;
2468e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
24698951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  if (!context)
2470beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor    context = g_main_context_default();
2471beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
2472e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  LOCK_CONTEXT (context);
2473e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  retval = g_main_context_iterate (context, FALSE, FALSE, G_THREAD_SELF);
2474e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  UNLOCK_CONTEXT (context);
2475e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2476e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  return retval;
2477a52e2986cd4a2147cfc8d41ae23d98907caaf3a0Matthias Clasen}
2478e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2479e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor/**
2480e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * g_main_context_iteration:
24814abb6c13bed8ad398c124e8880b8743617f8bee1Matthias Clasen * @context: a #GMainContext (if %NULL, the default context will be used)
24824abb6c13bed8ad398c124e8880b8743617f8bee1Matthias Clasen * @may_block: whether the call may block.
24834abb6c13bed8ad398c124e8880b8743617f8bee1Matthias Clasen *
24844abb6c13bed8ad398c124e8880b8743617f8bee1Matthias Clasen * Runs a single iteration for the given main loop. This involves
24854abb6c13bed8ad398c124e8880b8743617f8bee1Matthias Clasen * checking to see if any event sources are ready to be processed,
24864abb6c13bed8ad398c124e8880b8743617f8bee1Matthias Clasen * then if no events sources are ready and @may_block is %TRUE, waiting
24874abb6c13bed8ad398c124e8880b8743617f8bee1Matthias Clasen * for a source to become ready, then dispatching the highest priority
24884abb6c13bed8ad398c124e8880b8743617f8bee1Matthias Clasen * events sources that are ready. Otherwise, if @may_block is %FALSE
2489e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * sources are not waited to become ready, only those highest priority
2490e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * events sources will be dispatched (if any), that are ready at this
2491e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * given moment without further waiting.
2492beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor *
2493e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * Note that even when @may_block is %TRUE, it is still possible for
2494beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor * g_main_context_iteration() to return %FALSE, since the the wait may
24958951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor * be interrupted for other reasons than an event source becoming ready.
24968951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor *
2497e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * Return value: %TRUE if events were dispatched.
2498e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor **/
2499e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorgboolean
25008951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylorg_main_context_iteration (GMainContext *context, gboolean may_block)
25018951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor{
25028951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  gboolean retval;
25038951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor
25048951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  if (!context)
2505beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor    context = g_main_context_default();
2506beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
2507e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  LOCK_CONTEXT (context);
2508e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  retval = g_main_context_iterate (context, may_block, TRUE, G_THREAD_SELF);
2509e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  UNLOCK_CONTEXT (context);
2510a52e2986cd4a2147cfc8d41ae23d98907caaf3a0Matthias Clasen
251109a6f7be5382444d472be2974eeede94ecb1df51Manish Singh  return retval;
2512a52e2986cd4a2147cfc8d41ae23d98907caaf3a0Matthias Clasen}
2513e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2514a52e2986cd4a2147cfc8d41ae23d98907caaf3a0Matthias Clasen/**
2515e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * g_main_loop_new:
2516a52e2986cd4a2147cfc8d41ae23d98907caaf3a0Matthias Clasen * @context: a #GMainContext  (if %NULL, the default context will be used).
2517e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * @is_running: set to %TRUE to indicate that the loop is running. This
2518e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * is not very important since calling g_main_loop_run() will set this to
2519e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * %TRUE anyway.
2520e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *
2521beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor * Creates a new #GMainLoop structure.
25228be41eae4d0077069ecf77a8904b5f624d5ea5ffTim Janik *
25232ded70ee9463ef0a24eeecb85074378c5c896500Tor Lillqvist * Return value: a new #GMainLoop.
2524e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor **/
2525e2fd4e2bd0589b159f87b491095565d16fac2789Owen TaylorGMainLoop *
2526e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorg_main_loop_new (GMainContext *context,
25278951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor		 gboolean      is_running)
25288951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor{
25298be41eae4d0077069ecf77a8904b5f624d5ea5ffTim Janik  GMainLoop *loop;
2530e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
25318be41eae4d0077069ecf77a8904b5f624d5ea5ffTim Janik  if (!context)
25323ae4c59e3f9a155436970a7d97d64676178a709cOwen Taylor    context = g_main_context_default();
25333ae4c59e3f9a155436970a7d97d64676178a709cOwen Taylor
25348be41eae4d0077069ecf77a8904b5f624d5ea5ffTim Janik  g_main_context_ref (context);
2535beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
2536beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  loop = g_new0 (GMainLoop, 1);
2537e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  loop->context = context;
25383ae4c59e3f9a155436970a7d97d64676178a709cOwen Taylor  loop->is_running = is_running != FALSE;
25393ae4c59e3f9a155436970a7d97d64676178a709cOwen Taylor  loop->ref_count = 1;
25403ae4c59e3f9a155436970a7d97d64676178a709cOwen Taylor
2541a52e2986cd4a2147cfc8d41ae23d98907caaf3a0Matthias Clasen  return loop;
25423ae4c59e3f9a155436970a7d97d64676178a709cOwen Taylor}
25433ae4c59e3f9a155436970a7d97d64676178a709cOwen Taylor
25443ae4c59e3f9a155436970a7d97d64676178a709cOwen Taylor/**
25453ae4c59e3f9a155436970a7d97d64676178a709cOwen Taylor * g_main_loop_ref:
25463ae4c59e3f9a155436970a7d97d64676178a709cOwen Taylor * @loop: a #GMainLoop
25473ae4c59e3f9a155436970a7d97d64676178a709cOwen Taylor *
25483ae4c59e3f9a155436970a7d97d64676178a709cOwen Taylor * Increases the reference count on a #GMainLoop object by one.
2549c40b15fc6b37d152d67c2d2ec18d0e635ea70f90Sebastian Wilhelmi *
25503ae4c59e3f9a155436970a7d97d64676178a709cOwen Taylor * Return value: @loop
2551c40b15fc6b37d152d67c2d2ec18d0e635ea70f90Sebastian Wilhelmi **/
25523ae4c59e3f9a155436970a7d97d64676178a709cOwen TaylorGMainLoop *
25533ae4c59e3f9a155436970a7d97d64676178a709cOwen Taylorg_main_loop_ref (GMainLoop *loop)
25543ae4c59e3f9a155436970a7d97d64676178a709cOwen Taylor{
25553ae4c59e3f9a155436970a7d97d64676178a709cOwen Taylor  g_return_val_if_fail (loop != NULL, NULL);
25563ae4c59e3f9a155436970a7d97d64676178a709cOwen Taylor  g_return_val_if_fail (g_atomic_int_get (&loop->ref_count) > 0, NULL);
25573ae4c59e3f9a155436970a7d97d64676178a709cOwen Taylor
25583ae4c59e3f9a155436970a7d97d64676178a709cOwen Taylor  g_atomic_int_inc (&loop->ref_count);
25593ae4c59e3f9a155436970a7d97d64676178a709cOwen Taylor
25603ae4c59e3f9a155436970a7d97d64676178a709cOwen Taylor  return loop;
25613ae4c59e3f9a155436970a7d97d64676178a709cOwen Taylor}
25623ae4c59e3f9a155436970a7d97d64676178a709cOwen Taylor
25633ae4c59e3f9a155436970a7d97d64676178a709cOwen Taylor/**
25643ae4c59e3f9a155436970a7d97d64676178a709cOwen Taylor * g_main_loop_unref:
25653ae4c59e3f9a155436970a7d97d64676178a709cOwen Taylor * @loop: a #GMainLoop
25663ae4c59e3f9a155436970a7d97d64676178a709cOwen Taylor *
2567c40b15fc6b37d152d67c2d2ec18d0e635ea70f90Sebastian Wilhelmi * Decreases the reference count on a #GMainLoop object by one. If
25683ae4c59e3f9a155436970a7d97d64676178a709cOwen Taylor * the result is zero, free the loop and free all associated memory.
2569c40b15fc6b37d152d67c2d2ec18d0e635ea70f90Sebastian Wilhelmi **/
2570c40b15fc6b37d152d67c2d2ec18d0e635ea70f90Sebastian Wilhelmivoid
2571c40b15fc6b37d152d67c2d2ec18d0e635ea70f90Sebastian Wilhelmig_main_loop_unref (GMainLoop *loop)
2572c40b15fc6b37d152d67c2d2ec18d0e635ea70f90Sebastian Wilhelmi{
2573c40b15fc6b37d152d67c2d2ec18d0e635ea70f90Sebastian Wilhelmi  g_return_if_fail (loop != NULL);
25743ae4c59e3f9a155436970a7d97d64676178a709cOwen Taylor  g_return_if_fail (g_atomic_int_get (&loop->ref_count) > 0);
25753ae4c59e3f9a155436970a7d97d64676178a709cOwen Taylor
25763ae4c59e3f9a155436970a7d97d64676178a709cOwen Taylor  if (!g_atomic_int_dec_and_test (&loop->ref_count))
2577e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    return;
2578e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2579e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  g_main_context_unref (loop->context);
258009a6f7be5382444d472be2974eeede94ecb1df51Manish Singh  g_free (loop);
2581e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor}
2582e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2583e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor/**
2584e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * g_main_loop_run:
2585beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor * @loop: a #GMainLoop
2586e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *
2587beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor * Runs a main loop until g_main_loop_quit() is called on the loop.
25888951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor * If this is called for the thread of the loop's #GMainContext,
25898951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor * it will process events from the loop, otherwise it will
25908be41eae4d0077069ecf77a8904b5f624d5ea5ffTim Janik * simply wait.
2591c40b15fc6b37d152d67c2d2ec18d0e635ea70f90Sebastian Wilhelmi **/
25928be41eae4d0077069ecf77a8904b5f624d5ea5ffTim Janikvoid
2593e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorg_main_loop_run (GMainLoop *loop)
25948951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor{
2595e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  GThread *self = G_THREAD_SELF;
25968951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor
25973ae4c59e3f9a155436970a7d97d64676178a709cOwen Taylor  g_return_if_fail (loop != NULL);
25988951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  g_return_if_fail (g_atomic_int_get (&loop->ref_count) > 0);
2599e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2600e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor#ifdef G_THREADS_ENABLED
2601cf67c99825f7da76636451c70b48b077236337afManish Singh  if (!g_main_context_acquire (loop->context))
2602e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    {
2603e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      gboolean got_ownership = FALSE;
2604e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2605e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      /* Another thread owns this context */
26068951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor      if (!g_thread_supported ())
2607e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	{
2608c40b15fc6b37d152d67c2d2ec18d0e635ea70f90Sebastian Wilhelmi	  g_warning ("g_main_loop_run() was called from second thread but "
26098951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor		     "g_thread_init() was never called.");
26108951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor	  return;
26118951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor	}
26128951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor
26138951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor      LOCK_CONTEXT (loop->context);
26148951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor
26158951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor      g_atomic_int_inc (&loop->ref_count);
26165b4af3060f292551e189f458406251319a54501dOwen Taylor
26178951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor      if (!loop->is_running)
26188951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor	loop->is_running = TRUE;
26198951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor
26208951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor      if (!loop->context->cond)
26218951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor	loop->context->cond = g_cond_new ();
2622e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
26231107552617653b80ef9fff77437569e1ac8e2408Sebastian Wilhelmi      while (loop->is_running && !got_ownership)
26248951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor	got_ownership = g_main_context_wait (loop->context,
26258951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor					     loop->context->cond,
26261107552617653b80ef9fff77437569e1ac8e2408Sebastian Wilhelmi					     g_static_mutex_get_mutex (&loop->context->mutex));
26278951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor
2628e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      if (!loop->is_running)
26298951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor	{
26308951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor	  UNLOCK_CONTEXT (loop->context);
26313ae4c59e3f9a155436970a7d97d64676178a709cOwen Taylor	  if (got_ownership)
26328951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor	    g_main_context_release (loop->context);
26338951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor	  g_main_loop_unref (loop);
26348951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor	  return;
26353ae4c59e3f9a155436970a7d97d64676178a709cOwen Taylor	}
26368951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor
26373ae4c59e3f9a155436970a7d97d64676178a709cOwen Taylor      g_assert (got_ownership);
2638cf67c99825f7da76636451c70b48b077236337afManish Singh    }
263909a6f7be5382444d472be2974eeede94ecb1df51Manish Singh  else
26408951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor    LOCK_CONTEXT (loop->context);
264108425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik#endif /* G_THREADS_ENABLED */
26428951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor
2643c40b15fc6b37d152d67c2d2ec18d0e635ea70f90Sebastian Wilhelmi  if (loop->context->in_check_or_prepare)
26448951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor    {
26458951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor      g_warning ("g_main_loop_run(): called recursively from within a source's "
26468951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor		 "check() or prepare() member, iteration not possible.");
26478951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor      return;
264824915b9a10e21b38dceaf3c493d117c79509990dHavoc Pennington    }
264924915b9a10e21b38dceaf3c493d117c79509990dHavoc Pennington
26508951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  g_atomic_int_inc (&loop->ref_count);
26518951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  loop->is_running = TRUE;
26528951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  while (loop->is_running)
26538951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor    g_main_context_iterate (loop->context, TRUE, TRUE, self);
265424915b9a10e21b38dceaf3c493d117c79509990dHavoc Pennington
2655beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  UNLOCK_CONTEXT (loop->context);
2656beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
2657e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor#ifdef G_THREADS_ENABLED
2658e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  g_main_context_release (loop->context);
2659e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor#endif /* G_THREADS_ENABLED */
2660e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2661e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  g_main_loop_unref (loop);
2662ed7e9b24594febb40708ee0b64f7298bd037b4caMatthias Clasen}
2663ed7e9b24594febb40708ee0b64f7298bd037b4caMatthias Clasen
2664ed7e9b24594febb40708ee0b64f7298bd037b4caMatthias Clasen/**
2665ed7e9b24594febb40708ee0b64f7298bd037b4caMatthias Clasen * g_main_loop_quit:
2666e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * @loop: a #GMainLoop
2667beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor *
2668e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * Stops a #GMainLoop from running. Any calls to g_main_loop_run()
2669beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor * for the loop will return.
26708be41eae4d0077069ecf77a8904b5f624d5ea5ffTim Janik *
2671c40b15fc6b37d152d67c2d2ec18d0e635ea70f90Sebastian Wilhelmi * Note that sources that have already been dispatched when
26728be41eae4d0077069ecf77a8904b5f624d5ea5ffTim Janik * g_main_loop_quit() is called will still be executed.
26738951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor **/
26748be41eae4d0077069ecf77a8904b5f624d5ea5ffTim Janikvoid
26758951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylorg_main_loop_quit (GMainLoop *loop)
2676e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor{
26777f7a422ce55725b312030cbe05e8fa4236583483Sebastian Wilhelmi  g_return_if_fail (loop != NULL);
26788951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  g_return_if_fail (g_atomic_int_get (&loop->ref_count) > 0);
26798951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor
26807f7a422ce55725b312030cbe05e8fa4236583483Sebastian Wilhelmi  LOCK_CONTEXT (loop->context);
26817f7a422ce55725b312030cbe05e8fa4236583483Sebastian Wilhelmi  loop->is_running = FALSE;
2682e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  g_main_context_wakeup_unlocked (loop->context);
2683beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
2684beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor#ifdef G_THREADS_ENABLED
2685e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  if (loop->context->cond)
2686e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    g_cond_broadcast (loop->context->cond);
2687e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor#endif /* G_THREADS_ENABLED */
2688e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
268909a6f7be5382444d472be2974eeede94ecb1df51Manish Singh  UNLOCK_CONTEXT (loop->context);
2690e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor}
2691e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2692e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor/**
26938be41eae4d0077069ecf77a8904b5f624d5ea5ffTim Janik * g_main_loop_is_running:
2694e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * @loop: a #GMainLoop.
26958be41eae4d0077069ecf77a8904b5f624d5ea5ffTim Janik *
26968be41eae4d0077069ecf77a8904b5f624d5ea5ffTim Janik * Checks to see if the main loop is currently being run via g_main_loop_run().
2697c40b15fc6b37d152d67c2d2ec18d0e635ea70f90Sebastian Wilhelmi *
26988be41eae4d0077069ecf77a8904b5f624d5ea5ffTim Janik * Return value: %TRUE if the mainloop is currently being run.
26998951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor **/
27008951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylorgboolean
2701e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorg_main_loop_is_running (GMainLoop *loop)
27028951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor{
27038951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  g_return_val_if_fail (loop != NULL, FALSE);
27048951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  g_return_val_if_fail (g_atomic_int_get (&loop->ref_count) > 0, FALSE);
27058951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor
27068951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  return loop->is_running;
27078951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor}
27088951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor
27098951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor/**
27108951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor * g_main_loop_get_context:
27118951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor * @loop: a #GMainLoop.
27128951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor *
27138951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor * Returns the #GMainContext of @loop.
2714c40b15fc6b37d152d67c2d2ec18d0e635ea70f90Sebastian Wilhelmi *
27158951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor * Return value: the #GMainContext of @loop
27168951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor **/
27178be41eae4d0077069ecf77a8904b5f624d5ea5ffTim JanikGMainContext *
27188be41eae4d0077069ecf77a8904b5f624d5ea5ffTim Janikg_main_loop_get_context (GMainLoop *loop)
2719e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor{
2720beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  g_return_val_if_fail (loop != NULL, NULL);
2721e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  g_return_val_if_fail (g_atomic_int_get (&loop->ref_count) > 0, NULL);
2722e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2723e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  return loop->context;
2724e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor}
2725e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2726beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor/* HOLDS: context's lock */
272787c7aeb93bd654776f59805a342ad913031034f3Tim Janikstatic void
272887c7aeb93bd654776f59805a342ad913031034f3Tim Janikg_main_context_poll (GMainContext *context,
2729beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor		     gint          timeout,
2730beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor		     gint          priority,
2731e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor		     GPollFD      *fds,
273287c7aeb93bd654776f59805a342ad913031034f3Tim Janik		     gint          n_fds)
2733e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor{
2734931ea952650b013b834041b91b0c37a748ffd449Owen Taylor#ifdef  G_MAIN_POLL_DEBUG
2735e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  GTimer *poll_timer;
273687c7aeb93bd654776f59805a342ad913031034f3Tim Janik  GPollRec *pollrec;
273787c7aeb93bd654776f59805a342ad913031034f3Tim Janik  gint i;
2738fc542a462a750f19b8fb06fcecc6f2034ec86d59Tor Lillqvist#endif
27392ded70ee9463ef0a24eeecb85074378c5c896500Tor Lillqvist
27402ded70ee9463ef0a24eeecb85074378c5c896500Tor Lillqvist  GPollFunc poll_func;
27412ded70ee9463ef0a24eeecb85074378c5c896500Tor Lillqvist
27422ded70ee9463ef0a24eeecb85074378c5c896500Tor Lillqvist  if (n_fds || timeout != 0)
27432ded70ee9463ef0a24eeecb85074378c5c896500Tor Lillqvist    {
274487c7aeb93bd654776f59805a342ad913031034f3Tim Janik#ifdef	G_MAIN_POLL_DEBUG
2745e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      if (_g_main_poll_debug)
2746e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	{
2747e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	  g_print ("polling context=%p n=%d timeout=%d\n",
2748e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor		   context, n_fds, timeout);
274987c7aeb93bd654776f59805a342ad913031034f3Tim Janik	  poll_timer = g_timer_new ();
2750e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	}
2751e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor#endif
27521cf610e216072fdb49d170d898bd4b7178ea3d2bTor Lillqvist
27531cf610e216072fdb49d170d898bd4b7178ea3d2bTor Lillqvist      LOCK_CONTEXT (context);
27541cf610e216072fdb49d170d898bd4b7178ea3d2bTor Lillqvist
27551cf610e216072fdb49d170d898bd4b7178ea3d2bTor Lillqvist      poll_func = context->poll_func;
27561cf610e216072fdb49d170d898bd4b7178ea3d2bTor Lillqvist
27571cf610e216072fdb49d170d898bd4b7178ea3d2bTor Lillqvist      UNLOCK_CONTEXT (context);
27581cf610e216072fdb49d170d898bd4b7178ea3d2bTor Lillqvist      if ((*poll_func) (fds, n_fds, timeout) < 0 && errno != EINTR)
27591cf610e216072fdb49d170d898bd4b7178ea3d2bTor Lillqvist	{
276087c7aeb93bd654776f59805a342ad913031034f3Tim Janik#ifndef G_OS_WIN32
276187c7aeb93bd654776f59805a342ad913031034f3Tim Janik	  g_warning ("poll(2) failed due to: %s.",
2762fc542a462a750f19b8fb06fcecc6f2034ec86d59Tor Lillqvist		     g_strerror (errno));
276387c7aeb93bd654776f59805a342ad913031034f3Tim Janik#else
27642ded70ee9463ef0a24eeecb85074378c5c896500Tor Lillqvist	  /* If g_poll () returns -1, it has already called g_warning() */
27652ded70ee9463ef0a24eeecb85074378c5c896500Tor Lillqvist#endif
27662ded70ee9463ef0a24eeecb85074378c5c896500Tor Lillqvist	}
27672ded70ee9463ef0a24eeecb85074378c5c896500Tor Lillqvist
27682ded70ee9463ef0a24eeecb85074378c5c896500Tor Lillqvist#ifdef	G_MAIN_POLL_DEBUG
27692ded70ee9463ef0a24eeecb85074378c5c896500Tor Lillqvist      if (_g_main_poll_debug)
27702ded70ee9463ef0a24eeecb85074378c5c896500Tor Lillqvist	{
27712ded70ee9463ef0a24eeecb85074378c5c896500Tor Lillqvist	  LOCK_CONTEXT (context);
27722ded70ee9463ef0a24eeecb85074378c5c896500Tor Lillqvist
27732ded70ee9463ef0a24eeecb85074378c5c896500Tor Lillqvist	  g_print ("g_main_poll(%d) timeout: %d - elapsed %12.10f seconds",
277487c7aeb93bd654776f59805a342ad913031034f3Tim Janik		   n_fds,
27752ded70ee9463ef0a24eeecb85074378c5c896500Tor Lillqvist		   timeout,
27762ded70ee9463ef0a24eeecb85074378c5c896500Tor Lillqvist		   g_timer_elapsed (poll_timer, NULL));
277787c7aeb93bd654776f59805a342ad913031034f3Tim Janik	  g_timer_destroy (poll_timer);
27782ded70ee9463ef0a24eeecb85074378c5c896500Tor Lillqvist	  pollrec = context->poll_records;
27792ded70ee9463ef0a24eeecb85074378c5c896500Tor Lillqvist
27802ded70ee9463ef0a24eeecb85074378c5c896500Tor Lillqvist	  while (pollrec != NULL)
27812ded70ee9463ef0a24eeecb85074378c5c896500Tor Lillqvist	    {
2782ac68024ec1a476871111522e5ce48945b18ce9f7Dan Winship	      i = 0;
27832ded70ee9463ef0a24eeecb85074378c5c896500Tor Lillqvist	      while (i < n_fds)
27842ded70ee9463ef0a24eeecb85074378c5c896500Tor Lillqvist		{
27852ded70ee9463ef0a24eeecb85074378c5c896500Tor Lillqvist		  if (fds[i].fd == pollrec->fd->fd &&
27862ded70ee9463ef0a24eeecb85074378c5c896500Tor Lillqvist		      pollrec->fd->events &&
27872ded70ee9463ef0a24eeecb85074378c5c896500Tor Lillqvist		      fds[i].revents)
27882ded70ee9463ef0a24eeecb85074378c5c896500Tor Lillqvist		    {
27892ded70ee9463ef0a24eeecb85074378c5c896500Tor Lillqvist		      g_print (" [" G_POLLFD_FORMAT " :", fds[i].fd);
27902ded70ee9463ef0a24eeecb85074378c5c896500Tor Lillqvist		      if (fds[i].revents & G_IO_IN)
27912ded70ee9463ef0a24eeecb85074378c5c896500Tor Lillqvist			g_print ("i");
27922ded70ee9463ef0a24eeecb85074378c5c896500Tor Lillqvist		      if (fds[i].revents & G_IO_OUT)
27932ded70ee9463ef0a24eeecb85074378c5c896500Tor Lillqvist			g_print ("o");
27942ded70ee9463ef0a24eeecb85074378c5c896500Tor Lillqvist		      if (fds[i].revents & G_IO_PRI)
27952ded70ee9463ef0a24eeecb85074378c5c896500Tor Lillqvist			g_print ("p");
27962ded70ee9463ef0a24eeecb85074378c5c896500Tor Lillqvist		      if (fds[i].revents & G_IO_ERR)
27972ded70ee9463ef0a24eeecb85074378c5c896500Tor Lillqvist			g_print ("e");
279887c7aeb93bd654776f59805a342ad913031034f3Tim Janik		      if (fds[i].revents & G_IO_HUP)
27992ded70ee9463ef0a24eeecb85074378c5c896500Tor Lillqvist			g_print ("h");
280087c7aeb93bd654776f59805a342ad913031034f3Tim Janik		      if (fds[i].revents & G_IO_NVAL)
28012ded70ee9463ef0a24eeecb85074378c5c896500Tor Lillqvist			g_print ("n");
28022ded70ee9463ef0a24eeecb85074378c5c896500Tor Lillqvist		      g_print ("]");
28032ded70ee9463ef0a24eeecb85074378c5c896500Tor Lillqvist		    }
280487c7aeb93bd654776f59805a342ad913031034f3Tim Janik		  i++;
280587c7aeb93bd654776f59805a342ad913031034f3Tim Janik		}
2806e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	      pollrec = pollrec->next;
2807beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor	    }
2808beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor	  g_print ("\n");
2809e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2810e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	  UNLOCK_CONTEXT (context);
2811e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	}
2812e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor#endif
2813e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    } /* if (n_fds || timeout != 0) */
2814e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor}
2815e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2816e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor/**
2817e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * g_main_context_add_poll:
2818a52e2986cd4a2147cfc8d41ae23d98907caaf3a0Matthias Clasen * @context: a #GMainContext (or %NULL for the default context)
2819a52e2986cd4a2147cfc8d41ae23d98907caaf3a0Matthias Clasen * @fd: a #GPollFD structure holding information about a file
2820e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *      descriptor to watch.
2821e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * @priority: the priority for this file descriptor which should be
2822e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *      the same as the priority used for g_source_attach() to ensure that the
2823e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *      file descriptor is polled whenever the results may be needed.
2824e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *
2825e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * Adds a file descriptor to the set of file descriptors polled for
2826beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor * this context. This will very seldomly be used directly. Instead
2827e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * a typical event source will use g_source_add_poll() instead.
2828e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor **/
2829e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorvoid
2830c40b15fc6b37d152d67c2d2ec18d0e635ea70f90Sebastian Wilhelmig_main_context_add_poll (GMainContext *context,
28318951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor			 GPollFD      *fd,
28328951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor			 gint          priority)
2833e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor{
2834e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  if (!context)
2835e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    context = g_main_context_default ();
2836931ea952650b013b834041b91b0c37a748ffd449Owen Taylor
2837931ea952650b013b834041b91b0c37a748ffd449Owen Taylor  g_return_if_fail (g_atomic_int_get (&context->ref_count) > 0);
28382e57a3643891f41c238c5ee3793afcd8706a4060Sebastian Wilhelmi  g_return_if_fail (fd);
2839931ea952650b013b834041b91b0c37a748ffd449Owen Taylor
2840e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  LOCK_CONTEXT (context);
2841e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  g_main_context_add_poll_unlocked (context, priority, fd);
2842e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  UNLOCK_CONTEXT (context);
2843931ea952650b013b834041b91b0c37a748ffd449Owen Taylor}
28440cba1b531d5d28890fa4f48359d4e7adacf2a603Tim Janik
28450cba1b531d5d28890fa4f48359d4e7adacf2a603Tim Janik/* HOLDS: main_loop_lock */
2846931ea952650b013b834041b91b0c37a748ffd449Owen Taylorstatic void
2847e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorg_main_context_add_poll_unlocked (GMainContext *context,
2848e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor				  gint          priority,
2849beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor				  GPollFD      *fd)
2850beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor{
2851beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  GPollRec *lastrec, *pollrec;
2852beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  GPollRec *newrec = g_slice_new (GPollRec);
2853e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2854beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  /* This file descriptor may be checked before we ever poll */
2855beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  fd->revents = 0;
2856beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  newrec->fd = fd;
2857beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  newrec->priority = priority;
2858beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
2859beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  lastrec = NULL;
2860beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  pollrec = context->poll_records;
2861beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  while (pollrec && priority >= pollrec->priority)
2862beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor    {
2863e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      lastrec = pollrec;
2864beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor      pollrec = pollrec->next;
2865beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor    }
2866beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
2867e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  if (lastrec)
286887c7aeb93bd654776f59805a342ad913031034f3Tim Janik    lastrec->next = newrec;
286987c7aeb93bd654776f59805a342ad913031034f3Tim Janik  else
2870e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    context->poll_records = newrec;
287187c7aeb93bd654776f59805a342ad913031034f3Tim Janik
287287c7aeb93bd654776f59805a342ad913031034f3Tim Janik  newrec->next = pollrec;
28738951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor
287487c7aeb93bd654776f59805a342ad913031034f3Tim Janik  context->n_poll_records++;
2875beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
2876beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor#ifdef G_THREADS_ENABLED
2877e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  context->poll_changed = TRUE;
2878e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2879e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  /* Now wake up the main loop if it is waiting in the poll() */
2880e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  g_main_context_wakeup_unlocked (context);
2881e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor#endif
2882a52e2986cd4a2147cfc8d41ae23d98907caaf3a0Matthias Clasen}
2883e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2884e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor/**
2885e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * g_main_context_remove_poll:
2886e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * @context:a #GMainContext
2887e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * @fd: a #GPollFD descriptor previously added with g_main_context_add_poll()
2888beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor *
2889e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * Removes file descriptor from the set of file descriptors to be
2890e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * polled for a particular context.
2891e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor **/
2892c40b15fc6b37d152d67c2d2ec18d0e635ea70f90Sebastian Wilhelmivoid
28938951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylorg_main_context_remove_poll (GMainContext *context,
2894beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor			    GPollFD      *fd)
28958951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor{
2896e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  if (!context)
2897e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    context = g_main_context_default ();
2898e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2899e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  g_return_if_fail (g_atomic_int_get (&context->ref_count) > 0);
2900e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  g_return_if_fail (fd);
2901e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2902e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  LOCK_CONTEXT (context);
2903e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  g_main_context_remove_poll_unlocked (context, fd);
2904e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  UNLOCK_CONTEXT (context);
2905e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor}
2906beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
2907e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorstatic void
2908beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylorg_main_context_remove_poll_unlocked (GMainContext *context,
2909beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor				     GPollFD      *fd)
2910beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor{
2911beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  GPollRec *pollrec, *lastrec;
2912beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
2913beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  lastrec = NULL;
2914beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  pollrec = context->poll_records;
2915beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
2916e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  while (pollrec)
2917beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor    {
29180cba1b531d5d28890fa4f48359d4e7adacf2a603Tim Janik      if (pollrec->fd == fd)
2919931ea952650b013b834041b91b0c37a748ffd449Owen Taylor	{
2920e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	  if (lastrec != NULL)
2921931ea952650b013b834041b91b0c37a748ffd449Owen Taylor	    lastrec->next = pollrec->next;
2922beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor	  else
2923beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor	    context->poll_records = pollrec->next;
2924beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
2925beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor	  g_slice_free (GPollRec, pollrec);
2926beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
292787c7aeb93bd654776f59805a342ad913031034f3Tim Janik	  context->n_poll_records--;
2928e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	  break;
292987c7aeb93bd654776f59805a342ad913031034f3Tim Janik	}
293087c7aeb93bd654776f59805a342ad913031034f3Tim Janik      lastrec = pollrec;
29318951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor      pollrec = pollrec->next;
293287c7aeb93bd654776f59805a342ad913031034f3Tim Janik    }
2933e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
293487c7aeb93bd654776f59805a342ad913031034f3Tim Janik#ifdef G_THREADS_ENABLED
2935e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  context->poll_changed = TRUE;
2936e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2937e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  /* Now wake up the main loop if it is waiting in the poll() */
2938e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  g_main_context_wakeup_unlocked (context);
2939e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor#endif
2940e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor}
2941e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2942e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor/**
2943e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * g_source_get_current_time:
2944e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * @source:  a #GSource
2945e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * @timeval: #GTimeVal structure in which to store current time.
2946e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *
2947e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * Gets the "current time" to be used when checking
2948e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * this source. The advantage of calling this function over
2949e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * calling g_get_current_time() directly is that when
2950e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * checking multiple sources, GLib can cache a single value
2951e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * instead of having to repeatedly get the system time.
2952e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor **/
2953e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorvoid
2954e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorg_source_get_current_time (GSource  *source,
2955e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor			   GTimeVal *timeval)
2956e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor{
2957e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  GMainContext *context;
2958e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2959e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  g_return_if_fail (source->context != NULL);
2960e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2961e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  context = source->context;
2962e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2963e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  LOCK_CONTEXT (context);
2964e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2965e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  if (!context->time_is_current)
2966e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    {
2967beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor      g_get_current_time (&context->current_time);
2968beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor      context->time_is_current = TRUE;
2969e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    }
2970e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2971e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  *timeval = context->current_time;
2972e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2973e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  UNLOCK_CONTEXT (context);
2974e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor}
2975a412fb16541620ed72da86daac0774afe4703d9dMatthias Clasen
2976a52e2986cd4a2147cfc8d41ae23d98907caaf3a0Matthias Clasen/**
2977a412fb16541620ed72da86daac0774afe4703d9dMatthias Clasen * g_main_context_set_poll_func:
2978e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * @context: a #GMainContext
2979e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * @func: the function to call to poll all file descriptors
2980e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *
2981e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * Sets the function to use to handle polling of file descriptors. It
2982e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * will be used instead of the poll() system call
2983e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * (or GLib's replacement function, which is used where
2984e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * poll() isn't available).
2985beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor *
2986e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * This function could possibly be used to integrate the GLib event
2987e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * loop with an external event loop.
2988e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor **/
2989c40b15fc6b37d152d67c2d2ec18d0e635ea70f90Sebastian Wilhelmivoid
29908951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylorg_main_context_set_poll_func (GMainContext *context,
2991e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor			      GPollFunc     func)
2992e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor{
2993beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  if (!context)
2994e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    context = g_main_context_default ();
2995beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
2996ac68024ec1a476871111522e5ce48945b18ce9f7Dan Winship  g_return_if_fail (g_atomic_int_get (&context->ref_count) > 0);
2997e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2998e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  LOCK_CONTEXT (context);
2999beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
3000beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  if (func)
3001e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    context->poll_func = func;
3002e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  else
3003e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    context->poll_func = g_poll;
3004e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
3005a52e2986cd4a2147cfc8d41ae23d98907caaf3a0Matthias Clasen  UNLOCK_CONTEXT (context);
3006e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor}
3007e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
3008e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor/**
3009b965bb5db1732cee8e0ed92d6484921a1431d6a9Tor Lillqvist * g_main_context_get_poll_func:
3010e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * @context: a #GMainContext
3011b965bb5db1732cee8e0ed92d6484921a1431d6a9Tor Lillqvist *
3012b74e7d2f4780c159f7583bd4eecd07ee222d1d9cTor Lillqvist * Gets the poll function set by g_main_context_set_poll_func().
3013e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *
3014e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * Return value: the poll function
3015e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor **/
3016e2fd4e2bd0589b159f87b491095565d16fac2789Owen TaylorGPollFunc
3017c40b15fc6b37d152d67c2d2ec18d0e635ea70f90Sebastian Wilhelmig_main_context_get_poll_func (GMainContext *context)
30188951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor{
3019e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  GPollFunc result;
3020e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
3021e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  if (!context)
3022b965bb5db1732cee8e0ed92d6484921a1431d6a9Tor Lillqvist    context = g_main_context_default ();
3023b74e7d2f4780c159f7583bd4eecd07ee222d1d9cTor Lillqvist
3024b74e7d2f4780c159f7583bd4eecd07ee222d1d9cTor Lillqvist  g_return_val_if_fail (g_atomic_int_get (&context->ref_count) > 0, NULL);
3025b965bb5db1732cee8e0ed92d6484921a1431d6a9Tor Lillqvist
3026e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  LOCK_CONTEXT (context);
302787c7aeb93bd654776f59805a342ad913031034f3Tim Janik  result = context->poll_func;
302887c7aeb93bd654776f59805a342ad913031034f3Tim Janik  UNLOCK_CONTEXT (context);
30298951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor
303087c7aeb93bd654776f59805a342ad913031034f3Tim Janik  return result;
303187c7aeb93bd654776f59805a342ad913031034f3Tim Janik}
3032e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
303387c7aeb93bd654776f59805a342ad913031034f3Tim Janik/* HOLDS: context's lock */
3034e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor/* Wake the main loop up from a poll() */
30357ea73a019935e1118935433c86480acc5eee2e05Manish Singhstatic void
3036e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorg_main_context_wakeup_unlocked (GMainContext *context)
303787c7aeb93bd654776f59805a342ad913031034f3Tim Janik{
3038b74e7d2f4780c159f7583bd4eecd07ee222d1d9cTor Lillqvist#ifdef G_THREADS_ENABLED
303987c7aeb93bd654776f59805a342ad913031034f3Tim Janik  if (g_thread_supported() && context->poll_waiting)
304087c7aeb93bd654776f59805a342ad913031034f3Tim Janik    {
304187c7aeb93bd654776f59805a342ad913031034f3Tim Janik      context->poll_waiting = FALSE;
304287c7aeb93bd654776f59805a342ad913031034f3Tim Janik#ifndef G_OS_WIN32
304387c7aeb93bd654776f59805a342ad913031034f3Tim Janik      write (context->wake_up_pipe[1], "A", 1);
30448951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor#else
30458951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor      ReleaseSemaphore (context->wake_up_semaphore, 1, NULL);
30468951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor#endif
30478951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor    }
3048a412fb16541620ed72da86daac0774afe4703d9dMatthias Clasen#endif
3049a412fb16541620ed72da86daac0774afe4703d9dMatthias Clasen}
30508951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor
30518951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor/**
30528951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor * g_main_context_wakeup:
30538951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor * @context: a #GMainContext
30548951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor *
30558951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor * If @context is currently waiting in a poll(), interrupt
30568951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor * the poll(), and continue the iteration process.
3057c40b15fc6b37d152d67c2d2ec18d0e635ea70f90Sebastian Wilhelmi **/
30588951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylorvoid
30598951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylorg_main_context_wakeup (GMainContext *context)
30608951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor{
30618951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  if (!context)
30628951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor    context = g_main_context_default ();
30638951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor
3064d2555b65ee8d686c185a17e488bdbdb9753f1269Michael Meeks  g_return_if_fail (g_atomic_int_get (&context->ref_count) > 0);
3065d2555b65ee8d686c185a17e488bdbdb9753f1269Michael Meeks
3066d2555b65ee8d686c185a17e488bdbdb9753f1269Michael Meeks  LOCK_CONTEXT (context);
3067d2555b65ee8d686c185a17e488bdbdb9753f1269Michael Meeks  g_main_context_wakeup_unlocked (context);
3068d2555b65ee8d686c185a17e488bdbdb9753f1269Michael Meeks  UNLOCK_CONTEXT (context);
3069d2555b65ee8d686c185a17e488bdbdb9753f1269Michael Meeks}
3070d2555b65ee8d686c185a17e488bdbdb9753f1269Michael Meeks
3071d2555b65ee8d686c185a17e488bdbdb9753f1269Michael Meeks/**
3072d2555b65ee8d686c185a17e488bdbdb9753f1269Michael Meeks * g_main_context_is_owner:
3073796aa7e06ec2359cec2e50f84749fc6ec6a31f99Matthias Clasen * @context: a #GMainContext
3074796aa7e06ec2359cec2e50f84749fc6ec6a31f99Matthias Clasen *
3075796aa7e06ec2359cec2e50f84749fc6ec6a31f99Matthias Clasen * Determines whether this thread holds the (recursive)
3076d2555b65ee8d686c185a17e488bdbdb9753f1269Michael Meeks * ownership of this #GMaincontext. This is useful to
3077d2555b65ee8d686c185a17e488bdbdb9753f1269Michael Meeks * know before waiting on another thread that may be
3078d2555b65ee8d686c185a17e488bdbdb9753f1269Michael Meeks * blocking to get ownership of @context.
3079d2555b65ee8d686c185a17e488bdbdb9753f1269Michael Meeks *
3080d2555b65ee8d686c185a17e488bdbdb9753f1269Michael Meeks * Returns: %TRUE if current thread is owner of @context.
3081d2555b65ee8d686c185a17e488bdbdb9753f1269Michael Meeks *
3082d2555b65ee8d686c185a17e488bdbdb9753f1269Michael Meeks * Since: 2.10
3083d2555b65ee8d686c185a17e488bdbdb9753f1269Michael Meeks **/
3084d2555b65ee8d686c185a17e488bdbdb9753f1269Michael Meeksgboolean
3085d2555b65ee8d686c185a17e488bdbdb9753f1269Michael Meeksg_main_context_is_owner (GMainContext *context)
3086d2555b65ee8d686c185a17e488bdbdb9753f1269Michael Meeks{
3087d2555b65ee8d686c185a17e488bdbdb9753f1269Michael Meeks  gboolean is_owner;
3088d2555b65ee8d686c185a17e488bdbdb9753f1269Michael Meeks
3089d2555b65ee8d686c185a17e488bdbdb9753f1269Michael Meeks  if (!context)
3090d2555b65ee8d686c185a17e488bdbdb9753f1269Michael Meeks    context = g_main_context_default ();
3091d2555b65ee8d686c185a17e488bdbdb9753f1269Michael Meeks
3092d2555b65ee8d686c185a17e488bdbdb9753f1269Michael Meeks#ifdef G_THREADS_ENABLED
3093d2555b65ee8d686c185a17e488bdbdb9753f1269Michael Meeks  LOCK_CONTEXT (context);
3094d2555b65ee8d686c185a17e488bdbdb9753f1269Michael Meeks  is_owner = context->owner == G_THREAD_SELF;
3095d2555b65ee8d686c185a17e488bdbdb9753f1269Michael Meeks  UNLOCK_CONTEXT (context);
3096beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor#else
3097beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  is_owner = TRUE;
3098db8baf697889c80c0632d7cc91343c18a2647429Tim Janik#endif
3099e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
3100e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  return is_owner;
3101db8baf697889c80c0632d7cc91343c18a2647429Tim Janik}
3102e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
3103e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor/* Timeouts */
3104db8baf697889c80c0632d7cc91343c18a2647429Tim Janik
3105e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorstatic void
3106e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorg_timeout_set_expiration (GTimeoutSource *timeout_source,
3107e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor			  GTimeVal       *current_time)
3108db8baf697889c80c0632d7cc91343c18a2647429Tim Janik{
3109e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  guint seconds = timeout_source->interval / 1000;
3110e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  guint msecs = timeout_source->interval - seconds * 1000;
3111db8baf697889c80c0632d7cc91343c18a2647429Tim Janik
3112f8c1c1f9e019d8fd2d5e56e3aa44183d0e752130Matthias Clasen  timeout_source->expiration.tv_sec = current_time->tv_sec + seconds;
3113f8c1c1f9e019d8fd2d5e56e3aa44183d0e752130Matthias Clasen  timeout_source->expiration.tv_usec = current_time->tv_usec + msecs * 1000;
3114f8c1c1f9e019d8fd2d5e56e3aa44183d0e752130Matthias Clasen  if (timeout_source->expiration.tv_usec >= 1000000)
3115f8c1c1f9e019d8fd2d5e56e3aa44183d0e752130Matthias Clasen    {
3116f8c1c1f9e019d8fd2d5e56e3aa44183d0e752130Matthias Clasen      timeout_source->expiration.tv_usec -= 1000000;
3117f8c1c1f9e019d8fd2d5e56e3aa44183d0e752130Matthias Clasen      timeout_source->expiration.tv_sec++;
3118f8c1c1f9e019d8fd2d5e56e3aa44183d0e752130Matthias Clasen    }
311923cb7803c2d7bfc9045acfa571bd0a50506a115aMatthias Clasen  if (timer_perturb==-1)
3120f8c1c1f9e019d8fd2d5e56e3aa44183d0e752130Matthias Clasen    {
312123cb7803c2d7bfc9045acfa571bd0a50506a115aMatthias Clasen      /*
3122f8c1c1f9e019d8fd2d5e56e3aa44183d0e752130Matthias Clasen       * we want a per machine/session unique 'random' value; try the dbus
3123ccd3ec90bf68c9b89e4582224099f7ff491d814bMatthias Clasen       * address first, that has a UUID in it. If there is no dbus, use the
3124f8c1c1f9e019d8fd2d5e56e3aa44183d0e752130Matthias Clasen       * hostname for hashing.
312523cb7803c2d7bfc9045acfa571bd0a50506a115aMatthias Clasen       */
3126f8c1c1f9e019d8fd2d5e56e3aa44183d0e752130Matthias Clasen      const char *session_bus_address = g_getenv ("DBUS_SESSION_BUS_ADDRESS");
3127f8c1c1f9e019d8fd2d5e56e3aa44183d0e752130Matthias Clasen      if (!session_bus_address)
3128f8c1c1f9e019d8fd2d5e56e3aa44183d0e752130Matthias Clasen        session_bus_address = g_getenv ("HOSTNAME");
3129f8c1c1f9e019d8fd2d5e56e3aa44183d0e752130Matthias Clasen      if (session_bus_address)
3130f8c1c1f9e019d8fd2d5e56e3aa44183d0e752130Matthias Clasen        timer_perturb = ABS ((gint) g_str_hash (session_bus_address));
3131f8c1c1f9e019d8fd2d5e56e3aa44183d0e752130Matthias Clasen      else
3132f8c1c1f9e019d8fd2d5e56e3aa44183d0e752130Matthias Clasen        timer_perturb = 0;
3133f8c1c1f9e019d8fd2d5e56e3aa44183d0e752130Matthias Clasen    }
3134f8c1c1f9e019d8fd2d5e56e3aa44183d0e752130Matthias Clasen  if (timeout_source->granularity)
3135f8c1c1f9e019d8fd2d5e56e3aa44183d0e752130Matthias Clasen    {
3136f8c1c1f9e019d8fd2d5e56e3aa44183d0e752130Matthias Clasen      gint remainder;
3137f8c1c1f9e019d8fd2d5e56e3aa44183d0e752130Matthias Clasen      gint gran; /* in usecs */
3138f8c1c1f9e019d8fd2d5e56e3aa44183d0e752130Matthias Clasen      gint perturb;
3139f8c1c1f9e019d8fd2d5e56e3aa44183d0e752130Matthias Clasen
3140f8c1c1f9e019d8fd2d5e56e3aa44183d0e752130Matthias Clasen      gran = timeout_source->granularity * 1000;
3141f8c1c1f9e019d8fd2d5e56e3aa44183d0e752130Matthias Clasen      perturb = timer_perturb % gran;
314223cb7803c2d7bfc9045acfa571bd0a50506a115aMatthias Clasen      /*
3143f8c1c1f9e019d8fd2d5e56e3aa44183d0e752130Matthias Clasen       * We want to give each machine a per machine pertubation;
3144f8c1c1f9e019d8fd2d5e56e3aa44183d0e752130Matthias Clasen       * shift time back first, and forward later after the rounding
314523cb7803c2d7bfc9045acfa571bd0a50506a115aMatthias Clasen       */
3146f8c1c1f9e019d8fd2d5e56e3aa44183d0e752130Matthias Clasen
3147f8c1c1f9e019d8fd2d5e56e3aa44183d0e752130Matthias Clasen      timeout_source->expiration.tv_usec -= perturb;
3148f8c1c1f9e019d8fd2d5e56e3aa44183d0e752130Matthias Clasen      if (timeout_source->expiration.tv_usec < 0)
3149f8c1c1f9e019d8fd2d5e56e3aa44183d0e752130Matthias Clasen        {
3150f8c1c1f9e019d8fd2d5e56e3aa44183d0e752130Matthias Clasen          timeout_source->expiration.tv_usec += 1000000;
3151f8c1c1f9e019d8fd2d5e56e3aa44183d0e752130Matthias Clasen          timeout_source->expiration.tv_sec--;
3152f8c1c1f9e019d8fd2d5e56e3aa44183d0e752130Matthias Clasen        }
3153f8c1c1f9e019d8fd2d5e56e3aa44183d0e752130Matthias Clasen
3154f8c1c1f9e019d8fd2d5e56e3aa44183d0e752130Matthias Clasen      remainder = timeout_source->expiration.tv_usec % gran;
3155f8c1c1f9e019d8fd2d5e56e3aa44183d0e752130Matthias Clasen      if (remainder >= gran/4) /* round up */
3156f8c1c1f9e019d8fd2d5e56e3aa44183d0e752130Matthias Clasen        timeout_source->expiration.tv_usec += gran;
3157f8c1c1f9e019d8fd2d5e56e3aa44183d0e752130Matthias Clasen      timeout_source->expiration.tv_usec -= remainder;
3158f8c1c1f9e019d8fd2d5e56e3aa44183d0e752130Matthias Clasen      /* shift back */
3159f8c1c1f9e019d8fd2d5e56e3aa44183d0e752130Matthias Clasen      timeout_source->expiration.tv_usec += perturb;
3160f8c1c1f9e019d8fd2d5e56e3aa44183d0e752130Matthias Clasen
3161db8baf697889c80c0632d7cc91343c18a2647429Tim Janik      /* the rounding may have overflown tv_usec */
3162db8baf697889c80c0632d7cc91343c18a2647429Tim Janik      while (timeout_source->expiration.tv_usec > 1000000)
3163db8baf697889c80c0632d7cc91343c18a2647429Tim Janik        {
316423cb7803c2d7bfc9045acfa571bd0a50506a115aMatthias Clasen          timeout_source->expiration.tv_usec -= 1000000;
316523cb7803c2d7bfc9045acfa571bd0a50506a115aMatthias Clasen          timeout_source->expiration.tv_sec++;
3166beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor        }
3167f5c28ce4ab8e8015a1432060b6cfe547183b2f9eOwen Taylor    }
3168beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor}
3169e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
3170db8baf697889c80c0632d7cc91343c18a2647429Tim Janikstatic gboolean
3171e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorg_timeout_prepare (GSource *source,
3172e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor		   gint    *timeout)
3173e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor{
3174e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  glong sec;
3175f5c28ce4ab8e8015a1432060b6cfe547183b2f9eOwen Taylor  glong msec;
3176f5c28ce4ab8e8015a1432060b6cfe547183b2f9eOwen Taylor  GTimeVal current_time;
3177f5c28ce4ab8e8015a1432060b6cfe547183b2f9eOwen Taylor
3178f5c28ce4ab8e8015a1432060b6cfe547183b2f9eOwen Taylor  GTimeoutSource *timeout_source = (GTimeoutSource *)source;
3179f5c28ce4ab8e8015a1432060b6cfe547183b2f9eOwen Taylor
3180f5c28ce4ab8e8015a1432060b6cfe547183b2f9eOwen Taylor  g_source_get_current_time (source, &current_time);
3181f5c28ce4ab8e8015a1432060b6cfe547183b2f9eOwen Taylor
3182f5c28ce4ab8e8015a1432060b6cfe547183b2f9eOwen Taylor  sec = timeout_source->expiration.tv_sec - current_time.tv_sec;
3183db8baf697889c80c0632d7cc91343c18a2647429Tim Janik  msec = (timeout_source->expiration.tv_usec - current_time.tv_usec) / 1000;
3184f5c28ce4ab8e8015a1432060b6cfe547183b2f9eOwen Taylor
3185db8baf697889c80c0632d7cc91343c18a2647429Tim Janik  /* We do the following in a rather convoluted fashion to deal with
3186f5c28ce4ab8e8015a1432060b6cfe547183b2f9eOwen Taylor   * the fact that we don't have an integral type big enough to hold
3187f5c28ce4ab8e8015a1432060b6cfe547183b2f9eOwen Taylor   * the difference of two timevals in millseconds.
3188f5c28ce4ab8e8015a1432060b6cfe547183b2f9eOwen Taylor   */
3189f5c28ce4ab8e8015a1432060b6cfe547183b2f9eOwen Taylor  if (sec < 0 || (sec == 0 && msec < 0))
3190f5c28ce4ab8e8015a1432060b6cfe547183b2f9eOwen Taylor    msec = 0;
3191f5c28ce4ab8e8015a1432060b6cfe547183b2f9eOwen Taylor  else
3192f5c28ce4ab8e8015a1432060b6cfe547183b2f9eOwen Taylor    {
3193f5c28ce4ab8e8015a1432060b6cfe547183b2f9eOwen Taylor      glong interval_sec = timeout_source->interval / 1000;
3194f5c28ce4ab8e8015a1432060b6cfe547183b2f9eOwen Taylor      glong interval_msec = timeout_source->interval % 1000;
3195f5c28ce4ab8e8015a1432060b6cfe547183b2f9eOwen Taylor
3196f5c28ce4ab8e8015a1432060b6cfe547183b2f9eOwen Taylor      if (msec < 0)
3197f5c28ce4ab8e8015a1432060b6cfe547183b2f9eOwen Taylor	{
3198f5c28ce4ab8e8015a1432060b6cfe547183b2f9eOwen Taylor	  msec += 1000;
3199f5c28ce4ab8e8015a1432060b6cfe547183b2f9eOwen Taylor	  sec -= 1;
3200f5c28ce4ab8e8015a1432060b6cfe547183b2f9eOwen Taylor	}
3201f5c28ce4ab8e8015a1432060b6cfe547183b2f9eOwen Taylor
3202f5c28ce4ab8e8015a1432060b6cfe547183b2f9eOwen Taylor      if (sec > interval_sec ||
320352644b08e77ddb3c146556451982dd3ff53bc1efOwen Taylor	  (sec == interval_sec && msec > interval_msec))
3204f5c28ce4ab8e8015a1432060b6cfe547183b2f9eOwen Taylor	{
3205f5c28ce4ab8e8015a1432060b6cfe547183b2f9eOwen Taylor	  /* The system time has been set backwards, so we
3206f5c28ce4ab8e8015a1432060b6cfe547183b2f9eOwen Taylor	   * reset the expiration time to now + timeout_source->interval;
320752644b08e77ddb3c146556451982dd3ff53bc1efOwen Taylor	   * this at least avoids hanging for long periods of time.
3208f5c28ce4ab8e8015a1432060b6cfe547183b2f9eOwen Taylor	   */
3209db8baf697889c80c0632d7cc91343c18a2647429Tim Janik	  g_timeout_set_expiration (timeout_source, &current_time);
3210f5c28ce4ab8e8015a1432060b6cfe547183b2f9eOwen Taylor	  msec = MIN (G_MAXINT, timeout_source->interval);
3211f5c28ce4ab8e8015a1432060b6cfe547183b2f9eOwen Taylor	}
3212db8baf697889c80c0632d7cc91343c18a2647429Tim Janik      else
3213db8baf697889c80c0632d7cc91343c18a2647429Tim Janik	{
3214beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor	  msec = MIN (G_MAXINT, (guint)msec + 1000 * (guint)sec);
3215beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor	}
3216beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor    }
321723cb7803c2d7bfc9045acfa571bd0a50506a115aMatthias Clasen
3218beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  *timeout = (gint)msec;
3219e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
3220e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  return msec == 0;
3221e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor}
3222e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
3223db8baf697889c80c0632d7cc91343c18a2647429Tim Janikstatic gboolean
3224e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorg_timeout_check (GSource *source)
3225e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor{
3226e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  GTimeVal current_time;
3227beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  GTimeoutSource *timeout_source = (GTimeoutSource *)source;
3228beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
3229beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  g_source_get_current_time (source, &current_time);
323023cb7803c2d7bfc9045acfa571bd0a50506a115aMatthias Clasen
323123cb7803c2d7bfc9045acfa571bd0a50506a115aMatthias Clasen  return ((timeout_source->expiration.tv_sec < current_time.tv_sec) ||
323223cb7803c2d7bfc9045acfa571bd0a50506a115aMatthias Clasen	  ((timeout_source->expiration.tv_sec == current_time.tv_sec) &&
3233beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor	   (timeout_source->expiration.tv_usec <= current_time.tv_usec)));
3234e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor}
3235beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
3236e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorstatic gboolean
3237e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorg_timeout_dispatch (GSource     *source,
3238e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor		    GSourceFunc  callback,
3239e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor		    gpointer     user_data)
3240e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor{
3241e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  GTimeoutSource *timeout_source = (GTimeoutSource *)source;
3242e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
3243e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  if (!callback)
3244beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor    {
3245e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      g_warning ("Timeout source dispatched without callback\n"
3246e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor		 "You must call g_source_set_callback().");
3247e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      return FALSE;
3248e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    }
32492623d2831ab006459da71d8a869a7a9a55869df2Owen Taylor
3250beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  if (callback (user_data))
3251beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor    {
3252beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor      GTimeVal current_time;
3253beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
3254beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor      g_source_get_current_time (source, &current_time);
3255beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor      g_timeout_set_expiration (timeout_source, &current_time);
3256e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
3257e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      return TRUE;
3258e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    }
3259e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  else
3260a52e2986cd4a2147cfc8d41ae23d98907caaf3a0Matthias Clasen    return FALSE;
3261e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor}
3262e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
3263e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor/**
3264e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * g_timeout_source_new:
3265e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * @interval: the timeout interval in milliseconds.
3266a52e2986cd4a2147cfc8d41ae23d98907caaf3a0Matthias Clasen *
3267e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * Creates a new timeout source.
3268e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *
3269e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * The source will not initially be associated with any #GMainContext
3270e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * and must be added to one with g_source_attach() before it will be
3271b4c3107c7a1dc5dd9e8050ed06f24d6be408e840Owen Taylor * executed.
3272e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *
3273e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * Return value: the newly-created timeout source
3274e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor **/
3275e2fd4e2bd0589b159f87b491095565d16fac2789Owen TaylorGSource *
3276e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorg_timeout_source_new (guint interval)
3277e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor{
3278e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  GSource *source = g_source_new (&g_timeout_funcs, sizeof (GTimeoutSource));
3279e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  GTimeoutSource *timeout_source = (GTimeoutSource *)source;
3280e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  GTimeVal current_time;
3281e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
3282e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  timeout_source->interval = interval;
3283e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
3284f8c1c1f9e019d8fd2d5e56e3aa44183d0e752130Matthias Clasen  g_get_current_time (&current_time);
3285f8c1c1f9e019d8fd2d5e56e3aa44183d0e752130Matthias Clasen  g_timeout_set_expiration (timeout_source, &current_time);
3286f8c1c1f9e019d8fd2d5e56e3aa44183d0e752130Matthias Clasen
3287f8c1c1f9e019d8fd2d5e56e3aa44183d0e752130Matthias Clasen  return source;
3288f8c1c1f9e019d8fd2d5e56e3aa44183d0e752130Matthias Clasen}
3289f8c1c1f9e019d8fd2d5e56e3aa44183d0e752130Matthias Clasen
3290f8c1c1f9e019d8fd2d5e56e3aa44183d0e752130Matthias Clasen/**
3291f8c1c1f9e019d8fd2d5e56e3aa44183d0e752130Matthias Clasen * g_timeout_source_new_seconds:
329223cb7803c2d7bfc9045acfa571bd0a50506a115aMatthias Clasen * @interval: the timeout interval in seconds
3293f8c1c1f9e019d8fd2d5e56e3aa44183d0e752130Matthias Clasen *
3294f8c1c1f9e019d8fd2d5e56e3aa44183d0e752130Matthias Clasen * Creates a new timeout source.
3295f8c1c1f9e019d8fd2d5e56e3aa44183d0e752130Matthias Clasen *
3296f8c1c1f9e019d8fd2d5e56e3aa44183d0e752130Matthias Clasen * The source will not initially be associated with any #GMainContext
3297f8c1c1f9e019d8fd2d5e56e3aa44183d0e752130Matthias Clasen * and must be added to one with g_source_attach() before it will be
3298f8c1c1f9e019d8fd2d5e56e3aa44183d0e752130Matthias Clasen * executed.
3299f8c1c1f9e019d8fd2d5e56e3aa44183d0e752130Matthias Clasen *
3300f8c1c1f9e019d8fd2d5e56e3aa44183d0e752130Matthias Clasen * The scheduling granularity/accuracy of this timeout source will be
3301f8c1c1f9e019d8fd2d5e56e3aa44183d0e752130Matthias Clasen * in seconds.
3302f8c1c1f9e019d8fd2d5e56e3aa44183d0e752130Matthias Clasen *
3303f8c1c1f9e019d8fd2d5e56e3aa44183d0e752130Matthias Clasen * Return value: the newly-created timeout source
3304f8c1c1f9e019d8fd2d5e56e3aa44183d0e752130Matthias Clasen *
3305f8c1c1f9e019d8fd2d5e56e3aa44183d0e752130Matthias Clasen * Since: 2.14
3306f8c1c1f9e019d8fd2d5e56e3aa44183d0e752130Matthias Clasen **/
3307f8c1c1f9e019d8fd2d5e56e3aa44183d0e752130Matthias ClasenGSource *
3308f8c1c1f9e019d8fd2d5e56e3aa44183d0e752130Matthias Claseng_timeout_source_new_seconds (guint interval)
3309f8c1c1f9e019d8fd2d5e56e3aa44183d0e752130Matthias Clasen{
3310f8c1c1f9e019d8fd2d5e56e3aa44183d0e752130Matthias Clasen  GSource *source = g_source_new (&g_timeout_funcs, sizeof (GTimeoutSource));
3311f8c1c1f9e019d8fd2d5e56e3aa44183d0e752130Matthias Clasen  GTimeoutSource *timeout_source = (GTimeoutSource *)source;
3312f8c1c1f9e019d8fd2d5e56e3aa44183d0e752130Matthias Clasen  GTimeVal current_time;
3313f8c1c1f9e019d8fd2d5e56e3aa44183d0e752130Matthias Clasen
3314f8c1c1f9e019d8fd2d5e56e3aa44183d0e752130Matthias Clasen  timeout_source->interval = 1000*interval;
3315f8c1c1f9e019d8fd2d5e56e3aa44183d0e752130Matthias Clasen  timeout_source->granularity = 1000;
3316f8c1c1f9e019d8fd2d5e56e3aa44183d0e752130Matthias Clasen
3317f8c1c1f9e019d8fd2d5e56e3aa44183d0e752130Matthias Clasen  g_get_current_time (&current_time);
3318e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  g_timeout_set_expiration (timeout_source, &current_time);
331900ab83b8e8909cdaad4af57e33db4ed2b4fc6d93Emmanuele Bassi
332000ab83b8e8909cdaad4af57e33db4ed2b4fc6d93Emmanuele Bassi  return source;
3321e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor}
3322a52e2986cd4a2147cfc8d41ae23d98907caaf3a0Matthias Clasen
3323e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
3324e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor/**
332500ab83b8e8909cdaad4af57e33db4ed2b4fc6d93Emmanuele Bassi * g_timeout_add_full:
3326e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * @priority: the priority of the timeout source. Typically this will be in
3327e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *            the range between #G_PRIORITY_DEFAULT and #G_PRIORITY_HIGH.
3328e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * @interval: the time between calls to the function, in milliseconds
3329a52e2986cd4a2147cfc8d41ae23d98907caaf3a0Matthias Clasen *             (1/1000ths of a second)
3330e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * @function: function to call
3331e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * @data:     data to pass to @function
3332e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * @notify:   function to call when the timeout is removed, or %NULL
3333e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *
3334e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * Sets a function to be called at regular intervals, with the given
3335e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * priority.  The function is called repeatedly until it returns
3336e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * %FALSE, at which point the timeout is automatically destroyed and
3337e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * the function will not be called again.  The @notify function is
3338e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * called when the timeout is destroyed.  The first call to the
333940e192abf281989a109b70427b86eb4855a39c49Matthias Clasen * function will be at the end of the first @interval.
334040e192abf281989a109b70427b86eb4855a39c49Matthias Clasen *
334140e192abf281989a109b70427b86eb4855a39c49Matthias Clasen * Note that timeout functions may be delayed, due to the processing of other
334240e192abf281989a109b70427b86eb4855a39c49Matthias Clasen * event sources. Thus they should not be relied on for precise timing.
3343e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * After each call to the timeout function, the time of the next
334490bd00b055d71ad0b158b8125003b7a62ada657fMatthias Clasen * timeout is recalculated based on the current time and the given interval
3345e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * (it does not try to 'catch up' time lost in delays).
3346db8baf697889c80c0632d7cc91343c18a2647429Tim Janik *
3347beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor * This internally creates a main loop source using g_timeout_source_new()
3348db8baf697889c80c0632d7cc91343c18a2647429Tim Janik * and attaches it to the main loop context using g_source_attach(). You can
3349beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor * do these steps manually if you need greater control.
3350beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor *
3351beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor * Return value: the ID (greater than 0) of the event source.
3352beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor **/
3353e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorguint
33541084477e032113aefa2aad6d8c0a7360fafaae91Owen Taylorg_timeout_add_full (gint           priority,
3355e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor		    guint          interval,
3356e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor		    GSourceFunc    function,
3357beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor		    gpointer       data,
3358e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor		    GDestroyNotify notify)
33592623d2831ab006459da71d8a869a7a9a55869df2Owen Taylor{
3360e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  GSource *source;
3361e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  guint id;
3362beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
3363e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  g_return_val_if_fail (function != NULL, 0);
33641084477e032113aefa2aad6d8c0a7360fafaae91Owen Taylor
33651084477e032113aefa2aad6d8c0a7360fafaae91Owen Taylor  source = g_timeout_source_new (interval);
33661084477e032113aefa2aad6d8c0a7360fafaae91Owen Taylor
33671084477e032113aefa2aad6d8c0a7360fafaae91Owen Taylor  if (priority != G_PRIORITY_DEFAULT)
3368beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor    g_source_set_priority (source, priority);
3369beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
3370e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  g_source_set_callback (source, function, data, notify);
3371e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  id = g_source_attach (source, NULL);
3372e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  g_source_unref (source);
3373a52e2986cd4a2147cfc8d41ae23d98907caaf3a0Matthias Clasen
3374e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  return id;
3375e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor}
3376e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
3377e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor/**
3378e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * g_timeout_add:
3379a52e2986cd4a2147cfc8d41ae23d98907caaf3a0Matthias Clasen * @interval: the time between calls to the function, in milliseconds
33801d3b965d0792818bea32260f957cfab49791f833Owen Taylor *             (1/1000ths of a second)
3381e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * @function: function to call
3382e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * @data:     data to pass to @function
3383e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *
3384e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * Sets a function to be called at regular intervals, with the default
3385e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * priority, #G_PRIORITY_DEFAULT.  The function is called repeatedly
3386e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * until it returns %FALSE, at which point the timeout is automatically
3387e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * destroyed and the function will not be called again.  The first call
3388f8c1c1f9e019d8fd2d5e56e3aa44183d0e752130Matthias Clasen * to the function will be at the end of the first @interval.
3389f8c1c1f9e019d8fd2d5e56e3aa44183d0e752130Matthias Clasen *
3390f8c1c1f9e019d8fd2d5e56e3aa44183d0e752130Matthias Clasen * Note that timeout functions may be delayed, due to the processing of other
3391f8c1c1f9e019d8fd2d5e56e3aa44183d0e752130Matthias Clasen * event sources. Thus they should not be relied on for precise timing.
3392f8c1c1f9e019d8fd2d5e56e3aa44183d0e752130Matthias Clasen * After each call to the timeout function, the time of the next
3393f8c1c1f9e019d8fd2d5e56e3aa44183d0e752130Matthias Clasen * timeout is recalculated based on the current time and the given interval
339440e192abf281989a109b70427b86eb4855a39c49Matthias Clasen * (it does not try to 'catch up' time lost in delays).
339540e192abf281989a109b70427b86eb4855a39c49Matthias Clasen *
339640e192abf281989a109b70427b86eb4855a39c49Matthias Clasen * If you want to have a timer in the "seconds" range and do not care
339740e192abf281989a109b70427b86eb4855a39c49Matthias Clasen * about the exact time of the first call of the timer, use the
339890bd00b055d71ad0b158b8125003b7a62ada657fMatthias Clasen * g_timeout_add_seconds() function; this function allows for more
3399e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * optimizations and more efficient system power usage.
3400f8c1c1f9e019d8fd2d5e56e3aa44183d0e752130Matthias Clasen *
3401beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor * This internally creates a main loop source using g_timeout_source_new()
3402beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor * and attaches it to the main loop context using g_source_attach(). You can
3403beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor * do these steps manually if you need greater control.
3404beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor *
34057f237f6fcd00ad9888ef459ccdc8d02e12c311fdOwen Taylor * Return value: the ID (greater than 0) of the event source.
34067f237f6fcd00ad9888ef459ccdc8d02e12c311fdOwen Taylor **/
3407beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylorguint
3408beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylorg_timeout_add (guint32        interval,
3409f8c1c1f9e019d8fd2d5e56e3aa44183d0e752130Matthias Clasen	       GSourceFunc    function,
341000ab83b8e8909cdaad4af57e33db4ed2b4fc6d93Emmanuele Bassi	       gpointer       data)
341100ab83b8e8909cdaad4af57e33db4ed2b4fc6d93Emmanuele Bassi{
341200ab83b8e8909cdaad4af57e33db4ed2b4fc6d93Emmanuele Bassi  return g_timeout_add_full (G_PRIORITY_DEFAULT,
3413f8c1c1f9e019d8fd2d5e56e3aa44183d0e752130Matthias Clasen			     interval, function, data, NULL);
3414f8c1c1f9e019d8fd2d5e56e3aa44183d0e752130Matthias Clasen}
3415f8c1c1f9e019d8fd2d5e56e3aa44183d0e752130Matthias Clasen
341600ab83b8e8909cdaad4af57e33db4ed2b4fc6d93Emmanuele Bassi/**
3417f8c1c1f9e019d8fd2d5e56e3aa44183d0e752130Matthias Clasen * g_timeout_add_seconds_full:
341800ab83b8e8909cdaad4af57e33db4ed2b4fc6d93Emmanuele Bassi * @priority: the priority of the timeout source. Typically this will be in
341900ab83b8e8909cdaad4af57e33db4ed2b4fc6d93Emmanuele Bassi *            the range between #G_PRIORITY_DEFAULT and #G_PRIORITY_HIGH.
342000ab83b8e8909cdaad4af57e33db4ed2b4fc6d93Emmanuele Bassi * @interval: the time between calls to the function, in seconds
342100ab83b8e8909cdaad4af57e33db4ed2b4fc6d93Emmanuele Bassi * @function: function to call
3422f8c1c1f9e019d8fd2d5e56e3aa44183d0e752130Matthias Clasen * @data:     data to pass to @function
3423f8c1c1f9e019d8fd2d5e56e3aa44183d0e752130Matthias Clasen * @notify:   function to call when the timeout is removed, or %NULL
3424f8c1c1f9e019d8fd2d5e56e3aa44183d0e752130Matthias Clasen *
3425f8c1c1f9e019d8fd2d5e56e3aa44183d0e752130Matthias Clasen * Sets a function to be called at regular intervals, with @priority.
3426f8c1c1f9e019d8fd2d5e56e3aa44183d0e752130Matthias Clasen * The function is called repeatedly until it returns %FALSE, at which
3427f8c1c1f9e019d8fd2d5e56e3aa44183d0e752130Matthias Clasen * point the timeout is automatically destroyed and the function will
3428f8c1c1f9e019d8fd2d5e56e3aa44183d0e752130Matthias Clasen * not be called again.
3429f8c1c1f9e019d8fd2d5e56e3aa44183d0e752130Matthias Clasen *
3430f8c1c1f9e019d8fd2d5e56e3aa44183d0e752130Matthias Clasen * Unlike g_timeout_add(), this function operates at whole second granularity.
3431f8c1c1f9e019d8fd2d5e56e3aa44183d0e752130Matthias Clasen * The initial starting point of the timer is determined by the implementation
3432f8c1c1f9e019d8fd2d5e56e3aa44183d0e752130Matthias Clasen * and the implementation is expected to group multiple timers together so that
3433f8c1c1f9e019d8fd2d5e56e3aa44183d0e752130Matthias Clasen * they fire all at the same time.
3434f8c1c1f9e019d8fd2d5e56e3aa44183d0e752130Matthias Clasen * To allow this grouping, the @interval to the first timer is rounded
3435f8c1c1f9e019d8fd2d5e56e3aa44183d0e752130Matthias Clasen * and can deviate up to one second from the specified interval.
3436f8c1c1f9e019d8fd2d5e56e3aa44183d0e752130Matthias Clasen * Subsequent timer iterations will generally run at the specified interval.
3437f8c1c1f9e019d8fd2d5e56e3aa44183d0e752130Matthias Clasen *
3438f8c1c1f9e019d8fd2d5e56e3aa44183d0e752130Matthias Clasen * Note that timeout functions may be delayed, due to the processing of other
3439f8c1c1f9e019d8fd2d5e56e3aa44183d0e752130Matthias Clasen * event sources. Thus they should not be relied on for precise timing.
3440f8c1c1f9e019d8fd2d5e56e3aa44183d0e752130Matthias Clasen * After each call to the timeout function, the time of the next
3441b2d6494a5ed92dd69cf1d78ec91dad43dfe3b1a0Matthias Clasen * timeout is recalculated based on the current time and the given @interval
3442b2d6494a5ed92dd69cf1d78ec91dad43dfe3b1a0Matthias Clasen *
3443f8c1c1f9e019d8fd2d5e56e3aa44183d0e752130Matthias Clasen * If you want timing more precise than whole seconds, use g_timeout_add()
344440e192abf281989a109b70427b86eb4855a39c49Matthias Clasen * instead.
344540e192abf281989a109b70427b86eb4855a39c49Matthias Clasen *
344640e192abf281989a109b70427b86eb4855a39c49Matthias Clasen * The grouping of timers to fire at the same time results in a more power
344740e192abf281989a109b70427b86eb4855a39c49Matthias Clasen * and CPU efficient behavior so if your timer is in multiples of seconds
344840e192abf281989a109b70427b86eb4855a39c49Matthias Clasen * and you don't require the first timer exactly one second from now, the
3449f8c1c1f9e019d8fd2d5e56e3aa44183d0e752130Matthias Clasen * use of g_timeout_add_seconds() is preferred over g_timeout_add().
3450f8c1c1f9e019d8fd2d5e56e3aa44183d0e752130Matthias Clasen *
3451f8c1c1f9e019d8fd2d5e56e3aa44183d0e752130Matthias Clasen * This internally creates a main loop source using
3452f8c1c1f9e019d8fd2d5e56e3aa44183d0e752130Matthias Clasen * g_timeout_source_new_seconds() and attaches it to the main loop context
3453f8c1c1f9e019d8fd2d5e56e3aa44183d0e752130Matthias Clasen * using g_source_attach(). You can do these steps manually if you need
345400ab83b8e8909cdaad4af57e33db4ed2b4fc6d93Emmanuele Bassi * greater control.
345500ab83b8e8909cdaad4af57e33db4ed2b4fc6d93Emmanuele Bassi *
345600ab83b8e8909cdaad4af57e33db4ed2b4fc6d93Emmanuele Bassi * Return value: the ID (greater than 0) of the event source.
345700ab83b8e8909cdaad4af57e33db4ed2b4fc6d93Emmanuele Bassi *
345800ab83b8e8909cdaad4af57e33db4ed2b4fc6d93Emmanuele Bassi * Since: 2.14
3459f8c1c1f9e019d8fd2d5e56e3aa44183d0e752130Matthias Clasen **/
3460f8c1c1f9e019d8fd2d5e56e3aa44183d0e752130Matthias Clasenguint
3461f8c1c1f9e019d8fd2d5e56e3aa44183d0e752130Matthias Claseng_timeout_add_seconds_full (gint           priority,
3462f8c1c1f9e019d8fd2d5e56e3aa44183d0e752130Matthias Clasen                            guint32        interval,
3463f8c1c1f9e019d8fd2d5e56e3aa44183d0e752130Matthias Clasen                            GSourceFunc    function,
3464f8c1c1f9e019d8fd2d5e56e3aa44183d0e752130Matthias Clasen                            gpointer       data,
3465f8c1c1f9e019d8fd2d5e56e3aa44183d0e752130Matthias Clasen                            GDestroyNotify notify)
3466f8c1c1f9e019d8fd2d5e56e3aa44183d0e752130Matthias Clasen{
346700ab83b8e8909cdaad4af57e33db4ed2b4fc6d93Emmanuele Bassi  GSource *source;
346800ab83b8e8909cdaad4af57e33db4ed2b4fc6d93Emmanuele Bassi  guint id;
346900ab83b8e8909cdaad4af57e33db4ed2b4fc6d93Emmanuele Bassi
347000ab83b8e8909cdaad4af57e33db4ed2b4fc6d93Emmanuele Bassi  g_return_val_if_fail (function != NULL, 0);
3471f8c1c1f9e019d8fd2d5e56e3aa44183d0e752130Matthias Clasen
3472f8c1c1f9e019d8fd2d5e56e3aa44183d0e752130Matthias Clasen  source = g_timeout_source_new_seconds (interval);
3473f8c1c1f9e019d8fd2d5e56e3aa44183d0e752130Matthias Clasen
3474f8c1c1f9e019d8fd2d5e56e3aa44183d0e752130Matthias Clasen  if (priority != G_PRIORITY_DEFAULT)
3475f8c1c1f9e019d8fd2d5e56e3aa44183d0e752130Matthias Clasen    g_source_set_priority (source, priority);
3476f8c1c1f9e019d8fd2d5e56e3aa44183d0e752130Matthias Clasen
347700ab83b8e8909cdaad4af57e33db4ed2b4fc6d93Emmanuele Bassi  g_source_set_callback (source, function, data, notify);
347800ab83b8e8909cdaad4af57e33db4ed2b4fc6d93Emmanuele Bassi  id = g_source_attach (source, NULL);
347900ab83b8e8909cdaad4af57e33db4ed2b4fc6d93Emmanuele Bassi  g_source_unref (source);
348000ab83b8e8909cdaad4af57e33db4ed2b4fc6d93Emmanuele Bassi
348100ab83b8e8909cdaad4af57e33db4ed2b4fc6d93Emmanuele Bassi  return id;
348200ab83b8e8909cdaad4af57e33db4ed2b4fc6d93Emmanuele Bassi}
348300ab83b8e8909cdaad4af57e33db4ed2b4fc6d93Emmanuele Bassi
348400ab83b8e8909cdaad4af57e33db4ed2b4fc6d93Emmanuele Bassi/**
348500ab83b8e8909cdaad4af57e33db4ed2b4fc6d93Emmanuele Bassi * g_timeout_add_seconds:
348600ab83b8e8909cdaad4af57e33db4ed2b4fc6d93Emmanuele Bassi * @interval: the time between calls to the function, in seconds
348700ab83b8e8909cdaad4af57e33db4ed2b4fc6d93Emmanuele Bassi * @function: function to call
348840e192abf281989a109b70427b86eb4855a39c49Matthias Clasen * @data: data to pass to @function
348940e192abf281989a109b70427b86eb4855a39c49Matthias Clasen *
349040e192abf281989a109b70427b86eb4855a39c49Matthias Clasen * Sets a function to be called at regular intervals with the default
349140e192abf281989a109b70427b86eb4855a39c49Matthias Clasen * priority, #G_PRIORITY_DEFAULT. The function is called repeatedly until
349240e192abf281989a109b70427b86eb4855a39c49Matthias Clasen * it returns %FALSE, at which point the timeout is automatically destroyed
349300ab83b8e8909cdaad4af57e33db4ed2b4fc6d93Emmanuele Bassi * and the function will not be called again.
349400ab83b8e8909cdaad4af57e33db4ed2b4fc6d93Emmanuele Bassi *
349500ab83b8e8909cdaad4af57e33db4ed2b4fc6d93Emmanuele Bassi * This internally creates a main loop source using
349600ab83b8e8909cdaad4af57e33db4ed2b4fc6d93Emmanuele Bassi * g_timeout_source_new_seconds() and attaches it to the main loop context
349700ab83b8e8909cdaad4af57e33db4ed2b4fc6d93Emmanuele Bassi * using g_source_attach(). You can do these steps manually if you need
349800ab83b8e8909cdaad4af57e33db4ed2b4fc6d93Emmanuele Bassi * greater control. Also see g_timout_add_seconds_full().
349900ab83b8e8909cdaad4af57e33db4ed2b4fc6d93Emmanuele Bassi *
350000ab83b8e8909cdaad4af57e33db4ed2b4fc6d93Emmanuele Bassi * Return value: the ID (greater than 0) of the event source.
350100ab83b8e8909cdaad4af57e33db4ed2b4fc6d93Emmanuele Bassi *
350200ab83b8e8909cdaad4af57e33db4ed2b4fc6d93Emmanuele Bassi * Since: 2.14
350300ab83b8e8909cdaad4af57e33db4ed2b4fc6d93Emmanuele Bassi **/
350400ab83b8e8909cdaad4af57e33db4ed2b4fc6d93Emmanuele Bassiguint
350500ab83b8e8909cdaad4af57e33db4ed2b4fc6d93Emmanuele Bassig_timeout_add_seconds (guint       interval,
3506f8c1c1f9e019d8fd2d5e56e3aa44183d0e752130Matthias Clasen                       GSourceFunc function,
3507540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen                       gpointer    data)
3508540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen{
35094d470362b20627044ed9e56fa47ba012cb9b4c54Hans Breuer  g_return_val_if_fail (function != NULL, 0);
35104d470362b20627044ed9e56fa47ba012cb9b4c54Hans Breuer
35114d470362b20627044ed9e56fa47ba012cb9b4c54Hans Breuer  return g_timeout_add_seconds_full (G_PRIORITY_DEFAULT, interval, function, data, NULL);
35124d470362b20627044ed9e56fa47ba012cb9b4c54Hans Breuer}
35134d470362b20627044ed9e56fa47ba012cb9b4c54Hans Breuer
35144d470362b20627044ed9e56fa47ba012cb9b4c54Hans Breuer/* Child watch functions */
35154d470362b20627044ed9e56fa47ba012cb9b4c54Hans Breuer
35164d470362b20627044ed9e56fa47ba012cb9b4c54Hans Breuer#ifdef G_OS_WIN32
35174d470362b20627044ed9e56fa47ba012cb9b4c54Hans Breuer
35184d470362b20627044ed9e56fa47ba012cb9b4c54Hans Breuerstatic gboolean
35194d470362b20627044ed9e56fa47ba012cb9b4c54Hans Breuerg_child_watch_prepare (GSource *source,
35204d470362b20627044ed9e56fa47ba012cb9b4c54Hans Breuer		       gint    *timeout)
35214d470362b20627044ed9e56fa47ba012cb9b4c54Hans Breuer{
35224d470362b20627044ed9e56fa47ba012cb9b4c54Hans Breuer  *timeout = -1;
35234d470362b20627044ed9e56fa47ba012cb9b4c54Hans Breuer  return FALSE;
35244d470362b20627044ed9e56fa47ba012cb9b4c54Hans Breuer}
35254d470362b20627044ed9e56fa47ba012cb9b4c54Hans Breuer
35264d470362b20627044ed9e56fa47ba012cb9b4c54Hans Breuer
35274d470362b20627044ed9e56fa47ba012cb9b4c54Hans Breuerstatic gboolean
35284d470362b20627044ed9e56fa47ba012cb9b4c54Hans Breuerg_child_watch_check (GSource  *source)
35294d470362b20627044ed9e56fa47ba012cb9b4c54Hans Breuer{
35304d470362b20627044ed9e56fa47ba012cb9b4c54Hans Breuer  GChildWatchSource *child_watch_source;
35314d470362b20627044ed9e56fa47ba012cb9b4c54Hans Breuer  gboolean child_exited;
35324d470362b20627044ed9e56fa47ba012cb9b4c54Hans Breuer
35334d470362b20627044ed9e56fa47ba012cb9b4c54Hans Breuer  child_watch_source = (GChildWatchSource *) source;
35344d470362b20627044ed9e56fa47ba012cb9b4c54Hans Breuer
35354d470362b20627044ed9e56fa47ba012cb9b4c54Hans Breuer  child_exited = child_watch_source->poll.revents & G_IO_IN;
35364d470362b20627044ed9e56fa47ba012cb9b4c54Hans Breuer
35374d470362b20627044ed9e56fa47ba012cb9b4c54Hans Breuer  if (child_exited)
35384d470362b20627044ed9e56fa47ba012cb9b4c54Hans Breuer    {
35394d470362b20627044ed9e56fa47ba012cb9b4c54Hans Breuer      DWORD child_status;
35404d470362b20627044ed9e56fa47ba012cb9b4c54Hans Breuer
35414d470362b20627044ed9e56fa47ba012cb9b4c54Hans Breuer      /*
35424d470362b20627044ed9e56fa47ba012cb9b4c54Hans Breuer       * Note: We do _not_ check for the special value of STILL_ACTIVE
35434d470362b20627044ed9e56fa47ba012cb9b4c54Hans Breuer       * since we know that the process has exited and doing so runs into
35444d470362b20627044ed9e56fa47ba012cb9b4c54Hans Breuer       * problems if the child process "happens to return STILL_ACTIVE(259)"
35454d470362b20627044ed9e56fa47ba012cb9b4c54Hans Breuer       * as Microsoft's Platform SDK puts it.
35464d470362b20627044ed9e56fa47ba012cb9b4c54Hans Breuer       */
35474d470362b20627044ed9e56fa47ba012cb9b4c54Hans Breuer      if (!GetExitCodeProcess (child_watch_source->pid, &child_status))
35484d470362b20627044ed9e56fa47ba012cb9b4c54Hans Breuer        {
35494d470362b20627044ed9e56fa47ba012cb9b4c54Hans Breuer	  gchar *emsg = g_win32_error_message (GetLastError ());
35504d470362b20627044ed9e56fa47ba012cb9b4c54Hans Breuer	  g_warning (G_STRLOC ": GetExitCodeProcess() failed: %s", emsg);
35514d470362b20627044ed9e56fa47ba012cb9b4c54Hans Breuer	  g_free (emsg);
35524d470362b20627044ed9e56fa47ba012cb9b4c54Hans Breuer
35534d470362b20627044ed9e56fa47ba012cb9b4c54Hans Breuer	  child_watch_source->child_status = -1;
35544d470362b20627044ed9e56fa47ba012cb9b4c54Hans Breuer	}
35554d470362b20627044ed9e56fa47ba012cb9b4c54Hans Breuer      else
35564d470362b20627044ed9e56fa47ba012cb9b4c54Hans Breuer	child_watch_source->child_status = child_status;
355744ef9006758b4bfd899b4ba9b46b69528ed070f5Owen Taylor    }
3558540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen
3559540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  return child_exited;
3560540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen}
3561540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen
3562540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen#else /* G_OS_WIN32 */
3563540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen
3564540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasenstatic gboolean
3565540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasencheck_for_child_exited (GSource *source)
3566540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen{
3567540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  GChildWatchSource *child_watch_source;
356844ef9006758b4bfd899b4ba9b46b69528ed070f5Owen Taylor  gint count;
356944ef9006758b4bfd899b4ba9b46b69528ed070f5Owen Taylor
357044ef9006758b4bfd899b4ba9b46b69528ed070f5Owen Taylor  /* protect against another SIGCHLD in the middle of this call */
3571540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  count = child_watch_count;
3572540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen
3573540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  child_watch_source = (GChildWatchSource *) source;
3574540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen
3575540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  if (child_watch_source->child_exited)
3576540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen    return TRUE;
3577540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen
3578540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  if (child_watch_source->count < count)
3579540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen    {
3580540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen      gint child_status;
3581540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen
358244ef9006758b4bfd899b4ba9b46b69528ed070f5Owen Taylor      if (waitpid (child_watch_source->pid, &child_status, WNOHANG) > 0)
358344ef9006758b4bfd899b4ba9b46b69528ed070f5Owen Taylor	{
3584540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen	  child_watch_source->child_status = child_status;
3585540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen	  child_watch_source->child_exited = TRUE;
3586540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen	}
3587540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen      child_watch_source->count = count;
3588540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen    }
3589540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen
3590540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  return child_watch_source->child_exited;
3591540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen}
359244ef9006758b4bfd899b4ba9b46b69528ed070f5Owen Taylor
3593540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasenstatic gboolean
3594540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Claseng_child_watch_prepare (GSource *source,
3595540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen		       gint    *timeout)
3596540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen{
3597540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  *timeout = -1;
3598540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen
359944ef9006758b4bfd899b4ba9b46b69528ed070f5Owen Taylor  return check_for_child_exited (source);
3600540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen}
3601540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen
36024d470362b20627044ed9e56fa47ba012cb9b4c54Hans Breuer
36034d470362b20627044ed9e56fa47ba012cb9b4c54Hans Breuerstatic gboolean
3604540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Claseng_child_watch_check (GSource  *source)
3605540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen{
3606540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  return check_for_child_exited (source);
3607540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen}
3608540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen
3609540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen#endif /* G_OS_WIN32 */
3610540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen
3611540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasenstatic gboolean
3612540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Claseng_child_watch_dispatch (GSource    *source,
3613540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen			GSourceFunc callback,
3614540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen			gpointer    user_data)
3615540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen{
3616540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  GChildWatchSource *child_watch_source;
3617540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  GChildWatchFunc child_watch_callback = (GChildWatchFunc) callback;
3618540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen
3619540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  child_watch_source = (GChildWatchSource *) source;
3620540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen
3621540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  if (!callback)
3622540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen    {
3623540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen      g_warning ("Child watch source dispatched without callback\n"
3624540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen		 "You must call g_source_set_callback().");
3625540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen      return FALSE;
3626540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen    }
36274d470362b20627044ed9e56fa47ba012cb9b4c54Hans Breuer
36284d470362b20627044ed9e56fa47ba012cb9b4c54Hans Breuer  (child_watch_callback) (child_watch_source->pid, child_watch_source->child_status, user_data);
3629540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen
3630540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  /* We never keep a child watch source around as the child is gone */
3631540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  return FALSE;
3632540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen}
3633540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen
3634540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen#ifndef G_OS_WIN32
3635540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen
3636540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasenstatic void
3637540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Claseng_child_watch_signal_handler (int signum)
3638540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen{
3639540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  child_watch_count ++;
3640540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen
3641540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  if (child_watch_init_state == CHILD_WATCH_INITIALIZED_THREADED)
3642540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen    {
3643540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen      write (child_watch_wake_up_pipe[1], "B", 1);
3644540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen    }
3645540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  else
3646540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen    {
3647540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen      /* We count on the signal interrupting the poll in the same thread.
36480631238743d968a39798ebc2f32eb1418ff697c6Matthias Clasen       */
36490631238743d968a39798ebc2f32eb1418ff697c6Matthias Clasen    }
3650540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen}
3651540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen
3652540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasenstatic void
3653540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Claseng_child_watch_source_init_single (void)
3654540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen{
36550631238743d968a39798ebc2f32eb1418ff697c6Matthias Clasen  struct sigaction action;
36560631238743d968a39798ebc2f32eb1418ff697c6Matthias Clasen
36570914ea84e3c7a48fa59f686c4182787df3fe5320Matthias Clasen  g_assert (! g_thread_supported());
36580631238743d968a39798ebc2f32eb1418ff697c6Matthias Clasen  g_assert (child_watch_init_state == CHILD_WATCH_UNINITIALIZED);
3659540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen
3660540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  child_watch_init_state = CHILD_WATCH_INITIALIZED_SINGLE;
3661938ebb1b1ab5c724b5b679324aa94836d23aadefJaikumar Ganesh
36620f6b25ca96e70cd3b2c105dce7ef166ee2e0c220Matthias Clasen  action.sa_handler = g_child_watch_signal_handler;
3663bb28d819383d1cbebb355153d2f53c858288835fJaikumar Ganesh  sigemptyset (&action.sa_mask);
3664bb28d819383d1cbebb355153d2f53c858288835fJaikumar Ganesh  action.sa_flags = SA_NOCLDSTOP;
3665bb28d819383d1cbebb355153d2f53c858288835fJaikumar Ganesh  sigaction (SIGCHLD, &action, NULL);
36660f6b25ca96e70cd3b2c105dce7ef166ee2e0c220Matthias Clasen}
3667540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen
3668540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen#ifndef ANDROID_STUB
3669540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias ClasenG_GNUC_NORETURN static gpointer
3670540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen#else
3671540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasenvoid
3672540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen#endif
3673540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasenchild_watch_helper_thread (gpointer data)
3674540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen{
3675540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  while (1)
3676c40b15fc6b37d152d67c2d2ec18d0e635ea70f90Sebastian Wilhelmi    {
3677540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen      gchar b[20];
3678540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen      GSList *list;
3679540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen
3680540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen      read (child_watch_wake_up_pipe[0], b, 20);
3681540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen
3682c40b15fc6b37d152d67c2d2ec18d0e635ea70f90Sebastian Wilhelmi      /* We were woken up.  Wake up all other contexts in all other threads */
3683c40b15fc6b37d152d67c2d2ec18d0e635ea70f90Sebastian Wilhelmi      G_LOCK (main_context_list);
3684c40b15fc6b37d152d67c2d2ec18d0e635ea70f90Sebastian Wilhelmi      for (list = main_context_list; list; list = list->next)
3685c40b15fc6b37d152d67c2d2ec18d0e635ea70f90Sebastian Wilhelmi	{
3686c40b15fc6b37d152d67c2d2ec18d0e635ea70f90Sebastian Wilhelmi	  GMainContext *context;
3687c40b15fc6b37d152d67c2d2ec18d0e635ea70f90Sebastian Wilhelmi
3688540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen	  context = list->data;
3689c40b15fc6b37d152d67c2d2ec18d0e635ea70f90Sebastian Wilhelmi	  if (g_atomic_int_get (&context->ref_count) > 0)
3690540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen	    /* Due to racing conditions we can find ref_count == 0, in
3691540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen	     * that case, however, the context is still not destroyed
3692540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen	     * and no poll can be active, otherwise the ref_count
3693540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen	     * wouldn't be 0 */
3694540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen	    g_main_context_wakeup (context);
3695540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen	}
3696540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen      G_UNLOCK (main_context_list);
36970631238743d968a39798ebc2f32eb1418ff697c6Matthias Clasen    }
3698540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen}
3699540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen
3700540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasenstatic void
3701540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Claseng_child_watch_source_init_multi_threaded (void)
3702540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen{
3703540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  GError *error = NULL;
3704540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  struct sigaction action;
3705540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen
3706540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  g_assert (g_thread_supported());
3707540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen
3708540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  if (pipe (child_watch_wake_up_pipe) < 0)
3709540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen    g_error ("Cannot create wake up pipe: %s\n", g_strerror (errno));
37100631238743d968a39798ebc2f32eb1418ff697c6Matthias Clasen  fcntl (child_watch_wake_up_pipe[1], F_SETFL, O_NONBLOCK | fcntl (child_watch_wake_up_pipe[1], F_GETFL));
37110631238743d968a39798ebc2f32eb1418ff697c6Matthias Clasen
37120631238743d968a39798ebc2f32eb1418ff697c6Matthias Clasen  /* We create a helper thread that polls on the wakeup pipe indefinitely */
37130631238743d968a39798ebc2f32eb1418ff697c6Matthias Clasen  /* FIXME: Think this through for races */
37140631238743d968a39798ebc2f32eb1418ff697c6Matthias Clasen  if (g_thread_create (child_watch_helper_thread, NULL, FALSE, &error) == NULL)
3715540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen    g_error ("Cannot create a thread to monitor child exit status: %s\n", error->message);
3716540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  child_watch_init_state = CHILD_WATCH_INITIALIZED_THREADED;
3717540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen
3718540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  action.sa_handler = g_child_watch_signal_handler;
3719540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  sigemptyset (&action.sa_mask);
3720540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  action.sa_flags = SA_RESTART | SA_NOCLDSTOP;
3721540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  sigaction (SIGCHLD, &action, NULL);
3722540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen}
3723540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen
3724540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasenstatic void
3725540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Claseng_child_watch_source_init_promote_single_to_threaded (void)
3726540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen{
3727540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  g_child_watch_source_init_multi_threaded ();
3728540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen}
3729540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen
3730540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasenstatic void
3731540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Claseng_child_watch_source_init (void)
3732540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen{
3733540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  if (g_thread_supported())
3734540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen    {
3735540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen      if (child_watch_init_state == CHILD_WATCH_UNINITIALIZED)
3736540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen	g_child_watch_source_init_multi_threaded ();
3737540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen      else if (child_watch_init_state == CHILD_WATCH_INITIALIZED_SINGLE)
3738540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen	g_child_watch_source_init_promote_single_to_threaded ();
3739540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen    }
37404d470362b20627044ed9e56fa47ba012cb9b4c54Hans Breuer  else
37414d470362b20627044ed9e56fa47ba012cb9b4c54Hans Breuer    {
3742540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen      if (child_watch_init_state == CHILD_WATCH_UNINITIALIZED)
3743540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen	g_child_watch_source_init_single ();
3744a689811a410623c69a257a857129f0d9e9d5d61fTor Lillqvist    }
3745a689811a410623c69a257a857129f0d9e9d5d61fTor Lillqvist}
3746540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen
3747540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen#endif /* !G_OS_WIN32 */
3748540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen
3749540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen/**
3750540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen * g_child_watch_source_new:
3751540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen * @pid: process to watch. On POSIX the pid of a child process. On
3752540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen * Windows a handle for a process (which doesn't have to be a child).
3753229206165e23fb572e5b527a8be434c777ebf53aMatthias Clasen *
3754229206165e23fb572e5b527a8be434c777ebf53aMatthias Clasen * Creates a new child_watch source.
3755229206165e23fb572e5b527a8be434c777ebf53aMatthias Clasen *
3756229206165e23fb572e5b527a8be434c777ebf53aMatthias Clasen * The source will not initially be associated with any #GMainContext
37573080ebdaa87ba1e034e17625f46d9c15efd26660Matthias Clasen * and must be added to one with g_source_attach() before it will be
375838cbfaeb7a2ca063ec600de2220ba1c6796647a4Owen Taylor * executed.
375938cbfaeb7a2ca063ec600de2220ba1c6796647a4Owen Taylor *
376038cbfaeb7a2ca063ec600de2220ba1c6796647a4Owen Taylor * Note that child watch sources can only be used in conjunction with
37610914ea84e3c7a48fa59f686c4182787df3fe5320Matthias Clasen * <literal>g_spawn...</literal> when the %G_SPAWN_DO_NOT_REAP_CHILD
37620914ea84e3c7a48fa59f686c4182787df3fe5320Matthias Clasen * flag is used.
37630914ea84e3c7a48fa59f686c4182787df3fe5320Matthias Clasen *
37640914ea84e3c7a48fa59f686c4182787df3fe5320Matthias Clasen * Note that on platforms where #GPid must be explicitly closed
37650914ea84e3c7a48fa59f686c4182787df3fe5320Matthias Clasen * (see g_spawn_close_pid()) @pid must not be closed while the
376638cbfaeb7a2ca063ec600de2220ba1c6796647a4Owen Taylor * source is still active. Typically, you will want to call
3767540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen * g_spawn_close_pid() in the callback function for the source.
3768540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen *
3769540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen * Note further that using g_child_watch_source_new() is not
3770540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen * compatible with calling <literal>waitpid(-1)</literal> in
3771540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen * the application. Calling waitpid() for individual pids will
3772540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen * still work fine.
3773540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen *
3774540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen * Return value: the newly-created child watch source
3775540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen *
3776540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen * Since: 2.4
37774d470362b20627044ed9e56fa47ba012cb9b4c54Hans Breuer **/
37780e2384faa8778b91d502c228b4c5b7988d872959Tor LillqvistGSource *
37794d470362b20627044ed9e56fa47ba012cb9b4c54Hans Breuerg_child_watch_source_new (GPid pid)
37804d470362b20627044ed9e56fa47ba012cb9b4c54Hans Breuer{
37814d470362b20627044ed9e56fa47ba012cb9b4c54Hans Breuer  GSource *source = g_source_new (&g_child_watch_funcs, sizeof (GChildWatchSource));
37824d470362b20627044ed9e56fa47ba012cb9b4c54Hans Breuer  GChildWatchSource *child_watch_source = (GChildWatchSource *)source;
3783540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen
37844d470362b20627044ed9e56fa47ba012cb9b4c54Hans Breuer#ifdef G_OS_WIN32
3785540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  child_watch_source->poll.fd = (gintptr) pid;
3786540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  child_watch_source->poll.events = G_IO_IN;
3787540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen
3788540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  g_source_add_poll (source, &child_watch_source->poll);
3789540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen#else /* G_OS_WIN32 */
3790540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  g_child_watch_source_init ();
3791540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen#endif /* G_OS_WIN32 */
3792540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen
3793540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  child_watch_source->pid = pid;
3794540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen
3795a689811a410623c69a257a857129f0d9e9d5d61fTor Lillqvist  return source;
3796a689811a410623c69a257a857129f0d9e9d5d61fTor Lillqvist}
3797540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen
3798540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen/**
3799540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen * g_child_watch_add_full:
3800540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen * @priority: the priority of the idle source. Typically this will be in the
3801dc78f9b202ab926e1c77a16fde0f869aba1dfc06Matthias Clasen *            range between #G_PRIORITY_DEFAULT_IDLE and #G_PRIORITY_HIGH_IDLE.
3802dc78f9b202ab926e1c77a16fde0f869aba1dfc06Matthias Clasen * @pid:      process to watch. On POSIX the pid of a child process. On
3803dc78f9b202ab926e1c77a16fde0f869aba1dfc06Matthias Clasen * Windows a handle for a process (which doesn't have to be a child).
3804dc78f9b202ab926e1c77a16fde0f869aba1dfc06Matthias Clasen * @function: function to call
3805dc78f9b202ab926e1c77a16fde0f869aba1dfc06Matthias Clasen * @data:     data to pass to @function
3806dc78f9b202ab926e1c77a16fde0f869aba1dfc06Matthias Clasen * @notify:   function to call when the idle is removed, or %NULL
3807540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen *
38083080ebdaa87ba1e034e17625f46d9c15efd26660Matthias Clasen * Sets a function to be called when the child indicated by @pid
380938cbfaeb7a2ca063ec600de2220ba1c6796647a4Owen Taylor * exits, at the priority @priority.
381038cbfaeb7a2ca063ec600de2220ba1c6796647a4Owen Taylor *
381138cbfaeb7a2ca063ec600de2220ba1c6796647a4Owen Taylor * If you obtain @pid from g_spawn_async() or g_spawn_async_with_pipes()
381238cbfaeb7a2ca063ec600de2220ba1c6796647a4Owen Taylor * you will need to pass #G_SPAWN_DO_NOT_REAP_CHILD as flag to
38134bc720a4a4971035d97f0ab191e21952dceb9c69Matthias Clasen * the spawn function for the child watching to work.
38144bc720a4a4971035d97f0ab191e21952dceb9c69Matthias Clasen *
381540e192abf281989a109b70427b86eb4855a39c49Matthias Clasen * Note that on platforms where #GPid must be explicitly closed
381640e192abf281989a109b70427b86eb4855a39c49Matthias Clasen * (see g_spawn_close_pid()) @pid must not be closed while the
381740e192abf281989a109b70427b86eb4855a39c49Matthias Clasen * source is still active. Typically, you will want to call
381840e192abf281989a109b70427b86eb4855a39c49Matthias Clasen * g_spawn_close_pid() in the callback function for the source.
381940e192abf281989a109b70427b86eb4855a39c49Matthias Clasen *
382090bd00b055d71ad0b158b8125003b7a62ada657fMatthias Clasen * GLib supports only a single callback per process id.
3821540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen *
3822540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen * This internally creates a main loop source using
3823540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen * g_child_watch_source_new() and attaches it to the main loop context
3824540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen * using g_source_attach(). You can do these steps manually if you
3825540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen * need greater control.
3826540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen *
3827540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen * Return value: the ID (greater than 0) of the event source.
3828540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen *
3829540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen * Since: 2.4
3830540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen **/
3831540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasenguint
3832540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Claseng_child_watch_add_full (gint            priority,
3833540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen			GPid            pid,
3834540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen			GChildWatchFunc function,
3835540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen			gpointer        data,
3836540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen			GDestroyNotify  notify)
3837540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen{
3838540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  GSource *source;
3839540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  guint id;
3840540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen
3841540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  g_return_val_if_fail (function != NULL, 0);
3842540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen
3843540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  source = g_child_watch_source_new (pid);
3844540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen
3845540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  if (priority != G_PRIORITY_DEFAULT)
3846540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen    g_source_set_priority (source, priority);
3847540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen
3848540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  g_source_set_callback (source, (GSourceFunc) function, data, notify);
3849540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  id = g_source_attach (source, NULL);
3850a689811a410623c69a257a857129f0d9e9d5d61fTor Lillqvist  g_source_unref (source);
3851a689811a410623c69a257a857129f0d9e9d5d61fTor Lillqvist
3852540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  return id;
3853540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen}
3854540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen
3855dc78f9b202ab926e1c77a16fde0f869aba1dfc06Matthias Clasen/**
3856dc78f9b202ab926e1c77a16fde0f869aba1dfc06Matthias Clasen * g_child_watch_add:
3857dc78f9b202ab926e1c77a16fde0f869aba1dfc06Matthias Clasen * @pid:      process id to watch. On POSIX the pid of a child process. On
3858dc78f9b202ab926e1c77a16fde0f869aba1dfc06Matthias Clasen * Windows a handle for a process (which doesn't have to be a child).
3859dc78f9b202ab926e1c77a16fde0f869aba1dfc06Matthias Clasen * @function: function to call
3860dc78f9b202ab926e1c77a16fde0f869aba1dfc06Matthias Clasen * @data:     data to pass to @function
3861540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen *
38623080ebdaa87ba1e034e17625f46d9c15efd26660Matthias Clasen * Sets a function to be called when the child indicated by @pid
386338cbfaeb7a2ca063ec600de2220ba1c6796647a4Owen Taylor * exits, at a default priority, #G_PRIORITY_DEFAULT.
386438cbfaeb7a2ca063ec600de2220ba1c6796647a4Owen Taylor *
386538cbfaeb7a2ca063ec600de2220ba1c6796647a4Owen Taylor * If you obtain @pid from g_spawn_async() or g_spawn_async_with_pipes()
386638cbfaeb7a2ca063ec600de2220ba1c6796647a4Owen Taylor * you will need to pass #G_SPAWN_DO_NOT_REAP_CHILD as flag to
38674bc720a4a4971035d97f0ab191e21952dceb9c69Matthias Clasen * the spawn function for the child watching to work.
38684bc720a4a4971035d97f0ab191e21952dceb9c69Matthias Clasen *
386940e192abf281989a109b70427b86eb4855a39c49Matthias Clasen * Note that on platforms where #GPid must be explicitly closed
387040e192abf281989a109b70427b86eb4855a39c49Matthias Clasen * (see g_spawn_close_pid()) @pid must not be closed while the
387140e192abf281989a109b70427b86eb4855a39c49Matthias Clasen * source is still active. Typically, you will want to call
387240e192abf281989a109b70427b86eb4855a39c49Matthias Clasen * g_spawn_close_pid() in the callback function for the source.
387340e192abf281989a109b70427b86eb4855a39c49Matthias Clasen *
387490bd00b055d71ad0b158b8125003b7a62ada657fMatthias Clasen * GLib supports only a single callback per process id.
3875540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen *
3876540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen * This internally creates a main loop source using
3877540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen * g_child_watch_source_new() and attaches it to the main loop context
3878540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen * using g_source_attach(). You can do these steps manually if you
3879540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen * need greater control.
3880540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen *
3881540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen * Return value: the ID (greater than 0) of the event source.
3882540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen *
3883540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen * Since: 2.4
3884540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen **/
3885540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasenguint
3886540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Claseng_child_watch_add (GPid            pid,
3887beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor		   GChildWatchFunc function,
3888beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor		   gpointer        data)
3889beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor{
3890e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  return g_child_watch_add_full (G_PRIORITY_DEFAULT, pid, function, data, NULL);
3891e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor}
3892beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
38931e5d06d4ceb07ae8ddbd596cb69936fb3807a116Tim Janik
38941e5d06d4ceb07ae8ddbd596cb69936fb3807a116Tim Janik/* Idle functions */
3895beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
3896beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylorstatic gboolean
3897beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylorg_idle_prepare  (GSource  *source,
3898beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor		 gint     *timeout)
3899e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor{
3900beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  *timeout = 0;
3901beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
3902beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  return TRUE;
3903beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor}
3904beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
3905e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorstatic gboolean
3906e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorg_idle_check    (GSource  *source)
3907e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor{
3908beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  return TRUE;
3909e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor}
3910e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
3911e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorstatic gboolean
3912e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorg_idle_dispatch (GSource    *source,
3913e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor		 GSourceFunc callback,
3914e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor		 gpointer    user_data)
3915e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor{
3916e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  if (!callback)
3917e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    {
3918beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor      g_warning ("Idle source dispatched without callback\n"
3919e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor		 "You must call g_source_set_callback().");
3920e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      return FALSE;
3921e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    }
3922a52e2986cd4a2147cfc8d41ae23d98907caaf3a0Matthias Clasen
3923e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  return callback (user_data);
3924e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor}
3925e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
3926b51c0d2f7057d64b59a5eef209d5d7b693349cdeOwen Taylor/**
3927b51c0d2f7057d64b59a5eef209d5d7b693349cdeOwen Taylor * g_idle_source_new:
3928b51c0d2f7057d64b59a5eef209d5d7b693349cdeOwen Taylor *
3929e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * Creates a new idle source.
3930a52e2986cd4a2147cfc8d41ae23d98907caaf3a0Matthias Clasen *
3931e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * The source will not initially be associated with any #GMainContext
3932e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * and must be added to one with g_source_attach() before it will be
3933e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * executed. Note that the default priority for idle sources is
3934e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * %G_PRIORITY_DEFAULT_IDLE, as compared to other sources which
3935b51c0d2f7057d64b59a5eef209d5d7b693349cdeOwen Taylor * have a default priority of %G_PRIORITY_DEFAULT.
3936b51c0d2f7057d64b59a5eef209d5d7b693349cdeOwen Taylor *
3937b51c0d2f7057d64b59a5eef209d5d7b693349cdeOwen Taylor * Return value: the newly-created idle source
3938b51c0d2f7057d64b59a5eef209d5d7b693349cdeOwen Taylor **/
3939b51c0d2f7057d64b59a5eef209d5d7b693349cdeOwen TaylorGSource *
3940b51c0d2f7057d64b59a5eef209d5d7b693349cdeOwen Taylorg_idle_source_new (void)
3941beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor{
3942beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  GSource *source;
3943e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
3944e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  source = g_source_new (&g_idle_funcs, sizeof (GSource));
3945e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  g_source_set_priority (source, G_PRIORITY_DEFAULT_IDLE);
39468df23d2283b56b181c4ebac9a74d9ea980efb1baRyan Lortie
3947e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  return source;
3948e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor}
3949e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
3950e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor/**
3951e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * g_idle_add_full:
3952a52e2986cd4a2147cfc8d41ae23d98907caaf3a0Matthias Clasen * @priority: the priority of the idle source. Typically this will be in the
3953e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *            range between #G_PRIORITY_DEFAULT_IDLE and #G_PRIORITY_HIGH_IDLE.
3954e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * @function: function to call
395540e192abf281989a109b70427b86eb4855a39c49Matthias Clasen * @data:     data to pass to @function
395640e192abf281989a109b70427b86eb4855a39c49Matthias Clasen * @notify:   function to call when the idle is removed, or %NULL
395740e192abf281989a109b70427b86eb4855a39c49Matthias Clasen *
395840e192abf281989a109b70427b86eb4855a39c49Matthias Clasen * Adds a function to be called whenever there are no higher priority
395990bd00b055d71ad0b158b8125003b7a62ada657fMatthias Clasen * events pending.  If the function returns %FALSE it is automatically
3960e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * removed from the list of event sources and will not be called again.
3961beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor *
396208425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik * This internally creates a main loop source using g_idle_source_new()
3963beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor * and attaches it to the main loop context using g_source_attach().
3964beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor * You can do these steps manually if you need greater control.
3965beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor *
3966beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor * Return value: the ID (greater than 0) of the event source.
3967e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor **/
39681084477e032113aefa2aad6d8c0a7360fafaae91Owen Taylorguint
3969e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorg_idle_add_full (gint           priority,
397008425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik		 GSourceFunc    function,
3971beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor		 gpointer       data,
3972e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor		 GDestroyNotify notify)
3973e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor{
3974b51c0d2f7057d64b59a5eef209d5d7b693349cdeOwen Taylor  GSource *source;
3975e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  guint id;
3976e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
3977e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  g_return_val_if_fail (function != NULL, 0);
39781084477e032113aefa2aad6d8c0a7360fafaae91Owen Taylor
39791084477e032113aefa2aad6d8c0a7360fafaae91Owen Taylor  source = g_idle_source_new ();
39801084477e032113aefa2aad6d8c0a7360fafaae91Owen Taylor
39811084477e032113aefa2aad6d8c0a7360fafaae91Owen Taylor  if (priority != G_PRIORITY_DEFAULT_IDLE)
3982beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor    g_source_set_priority (source, priority);
3983beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
3984e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  g_source_set_callback (source, function, data, notify);
3985e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  id = g_source_attach (source, NULL);
3986e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  g_source_unref (source);
3987e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
3988e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  return id;
3989e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor}
3990e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
3991e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor/**
3992a52e2986cd4a2147cfc8d41ae23d98907caaf3a0Matthias Clasen * g_idle_add:
3993e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * @function: function to call
3994e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * @data: data to pass to @function.
399540e192abf281989a109b70427b86eb4855a39c49Matthias Clasen *
399640e192abf281989a109b70427b86eb4855a39c49Matthias Clasen * Adds a function to be called whenever there are no higher priority
399740e192abf281989a109b70427b86eb4855a39c49Matthias Clasen * events pending to the default main loop. The function is given the
399840e192abf281989a109b70427b86eb4855a39c49Matthias Clasen * default idle priority, #G_PRIORITY_DEFAULT_IDLE.  If the function
399990bd00b055d71ad0b158b8125003b7a62ada657fMatthias Clasen * returns %FALSE it is automatically removed from the list of event
4000e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * sources and will not be called again.
4001beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor *
4002beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor * This internally creates a main loop source using g_idle_source_new()
4003beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor * and attaches it to the main loop context using g_source_attach().
4004beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor * You can do these steps manually if you need greater control.
40057f237f6fcd00ad9888ef459ccdc8d02e12c311fdOwen Taylor *
4006beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor * Return value: the ID (greater than 0) of the event source.
400708425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik **/
4008e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorguint
4009e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorg_idle_add (GSourceFunc    function,
4010e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	    gpointer       data)
4011e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor{
4012e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  return g_idle_add_full (G_PRIORITY_DEFAULT_IDLE, function, data, NULL);
4013e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor}
4014e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
4015e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor/**
401608425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik * g_idle_remove_by_data:
401708425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik * @data: the data for the idle source's callback.
401808425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik *
4019b4c3107c7a1dc5dd9e8050ed06f24d6be408e840Owen Taylor * Removes the idle function with the given data.
402008425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik *
4021e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * Return value: %TRUE if an idle source was found and removed.
4022608a31b98e1420f487190871ee7312db2643d93dMatthias Clasen **/
4023608a31b98e1420f487190871ee7312db2643d93dMatthias Clasengboolean
4024g_idle_remove_by_data (gpointer data)
4025{
4026  return g_source_remove_by_funcs_user_data (&g_idle_funcs, data);
4027}
4028
4029#define __G_MAIN_C__
4030#include "galiasdef.c"
4031