gmain.c revision 4bc720a4a4971035d97f0ab191e21952dceb9c69
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
3687c7aeb93bd654776f59805a342ad913031034f3Tim Janik/* uncomment the next line to get poll() debugging info */
3787c7aeb93bd654776f59805a342ad913031034f3Tim Janik/* #define G_MAIN_POLL_DEBUG */
3887c7aeb93bd654776f59805a342ad913031034f3Tim Janik
39dafdffd7516324a67db519372e9dcfddfd4fdeb0Matthias Clasen#include "galias.h"
40beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor#include "glib.h"
418e91cf9eb98da826abc1384418b5e9a4401048b8Sebastian Wilhelmi#include "gthreadinit.h"
42e906108048c4fbe7b1525a1ded119376447068cfMatthias Clasen#include <signal.h>
43e0153773a69fe64b2643c0d74c40af2dee7eb38fTim Janik#include <sys/types.h>
44f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist#include <time.h>
45f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist#ifdef HAVE_SYS_TIME_H
46beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor#include <sys/time.h>
4708425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik#endif /* HAVE_SYS_TIME_H */
4808425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik#ifdef GLIB_HAVE_SYS_POLL_H
49250d1a07bb4687135793fa61bafe79f100b50e66Tim Janik#  include <sys/poll.h>
50250d1a07bb4687135793fa61bafe79f100b50e66Tim Janik#  undef events	 /* AIX 4.1.5 & 4.3.2 define this for SVR3,4 compatibility */
51250d1a07bb4687135793fa61bafe79f100b50e66Tim Janik#  undef revents /* AIX 4.1.5 & 4.3.2 define this for SVR3,4 compatibility */
52d261f3fbfc37faef46c97cc1d41236a0e92ed9fbOwen Taylor
53d261f3fbfc37faef46c97cc1d41236a0e92ed9fbOwen Taylor/* The poll() emulation on OS/X doesn't handle fds=NULL, nfds=0,
54d261f3fbfc37faef46c97cc1d41236a0e92ed9fbOwen Taylor * so we prefer our own poll emulation.
55d261f3fbfc37faef46c97cc1d41236a0e92ed9fbOwen Taylor */
56d261f3fbfc37faef46c97cc1d41236a0e92ed9fbOwen Taylor#ifdef _POLL_EMUL_H_
57d261f3fbfc37faef46c97cc1d41236a0e92ed9fbOwen Taylor#undef HAVE_POLL
58d261f3fbfc37faef46c97cc1d41236a0e92ed9fbOwen Taylor#endif
59d261f3fbfc37faef46c97cc1d41236a0e92ed9fbOwen Taylor
6008425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik#endif /* GLIB_HAVE_SYS_POLL_H */
61f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist#ifdef HAVE_UNISTD_H
62beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor#include <unistd.h>
6308425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik#endif /* HAVE_UNISTD_H */
64931ea952650b013b834041b91b0c37a748ffd449Owen Taylor#include <errno.h>
65f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist
667ea73a019935e1118935433c86480acc5eee2e05Manish Singh#ifdef G_OS_WIN32
67f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist#define STRICT
68f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist#include <windows.h>
697ea73a019935e1118935433c86480acc5eee2e05Manish Singh#endif /* G_OS_WIN32 */
70f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist
717ea73a019935e1118935433c86480acc5eee2e05Manish Singh#ifdef G_OS_BEOS
72499c9786d1316bc72c539d55786bb3a65d95a83aCDT#include <net/socket.h>
737ea73a019935e1118935433c86480acc5eee2e05Manish Singh#endif /* G_OS_BEOS */
74499c9786d1316bc72c539d55786bb3a65d95a83aCDT
75540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen#ifdef G_OS_UNIX
76540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen#include <fcntl.h>
77540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen#include <sys/wait.h>
78540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen#endif
79beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor/* Types */
80beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
81e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylortypedef struct _GTimeoutSource GTimeoutSource;
82540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasentypedef struct _GChildWatchSource GChildWatchSource;
83beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylortypedef struct _GPollRec GPollRec;
84e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylortypedef struct _GSourceCallback GSourceCallback;
85beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
86a62ebb0e757c972ef4bc5892d7e3e673c6426015Tim Janiktypedef enum
87a62ebb0e757c972ef4bc5892d7e3e673c6426015Tim Janik{
88beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  G_SOURCE_READY = 1 << G_HOOK_FLAG_USER_SHIFT,
89beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  G_SOURCE_CAN_RECURSE = 1 << (G_HOOK_FLAG_USER_SHIFT + 1)
90beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor} GSourceFlags;
91beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
928951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor#ifdef G_THREADS_ENABLED
938951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylortypedef struct _GMainWaiter GMainWaiter;
948951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor
958951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylorstruct _GMainWaiter
968951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor{
978951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  GCond *cond;
988951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  GMutex *mutex;
998951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor};
1008951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor#endif
1018951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor
102e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorstruct _GMainContext
103a62ebb0e757c972ef4bc5892d7e3e673c6426015Tim Janik{
104e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor#ifdef G_THREADS_ENABLED
105e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  /* The following lock is used for both the list of sources
106e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor   * and the list of poll records
107e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor   */
1088951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  GStaticMutex mutex;
1098951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  GCond *cond;
1108951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  GThread *owner;
1118951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  guint owner_count;
1128951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  GSList *waiters;
113e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor#endif
114e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
115c40b15fc6b37d152d67c2d2ec18d0e635ea70f90Sebastian Wilhelmi  gint ref_count;
1168951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor
117e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  GPtrArray *pending_dispatches;
118e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  gint timeout;			/* Timeout for current iteration */
119e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
120e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  guint next_id;
121e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  GSource *source_list;
122e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  gint in_check_or_prepare;
123e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
124e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  GPollRec *poll_records;
125e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  GPollRec *poll_free_list;
126e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  GMemChunk *poll_chunk;
127e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  guint n_poll_records;
128e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  GPollFD *cached_poll_array;
129f5c28ce4ab8e8015a1432060b6cfe547183b2f9eOwen Taylor  guint cached_poll_array_size;
130e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
131e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor#ifdef G_THREADS_ENABLED
132e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor#ifndef G_OS_WIN32
133e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor/* this pipe is used to wake up the main loop when a source is added.
134e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor */
135e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  gint wake_up_pipe[2];
136e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor#else /* G_OS_WIN32 */
137e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  HANDLE wake_up_semaphore;
138e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor#endif /* G_OS_WIN32 */
139e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
140e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  GPollFD wake_up_rec;
141e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  gboolean poll_waiting;
142e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
143e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor/* Flag indicating whether the set of fd's changed during a poll */
144e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  gboolean poll_changed;
145e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor#endif /* G_THREADS_ENABLED */
146e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
147e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  GPollFunc poll_func;
148e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
149e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  GTimeVal current_time;
150e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  gboolean time_is_current;
151e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor};
152e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
153e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorstruct _GSourceCallback
154e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor{
155e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  guint ref_count;
156e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  GSourceFunc func;
157e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  gpointer    data;
158e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  GDestroyNotify notify;
159beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor};
160beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
161a62ebb0e757c972ef4bc5892d7e3e673c6426015Tim Janikstruct _GMainLoop
162a62ebb0e757c972ef4bc5892d7e3e673c6426015Tim Janik{
163e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  GMainContext *context;
1648be41eae4d0077069ecf77a8904b5f624d5ea5ffTim Janik  gboolean is_running;
165c40b15fc6b37d152d67c2d2ec18d0e635ea70f90Sebastian Wilhelmi  gint ref_count;
166beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor};
167beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
168e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorstruct _GTimeoutSource
169a62ebb0e757c972ef4bc5892d7e3e673c6426015Tim Janik{
170e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  GSource     source;
171beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  GTimeVal    expiration;
17252644b08e77ddb3c146556451982dd3ff53bc1efOwen Taylor  guint       interval;
173beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor};
174beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
175540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasenstruct _GChildWatchSource
176540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen{
177540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  GSource     source;
178540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  GPid        pid;
179540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  gint        child_status;
1804d470362b20627044ed9e56fa47ba012cb9b4c54Hans Breuer#ifdef G_OS_WIN32
1814d470362b20627044ed9e56fa47ba012cb9b4c54Hans Breuer  GPollFD     poll;
1824d470362b20627044ed9e56fa47ba012cb9b4c54Hans Breuer#else /* G_OS_WIN32 */
183c40b15fc6b37d152d67c2d2ec18d0e635ea70f90Sebastian Wilhelmi  gint        count;
184c40b15fc6b37d152d67c2d2ec18d0e635ea70f90Sebastian Wilhelmi  gboolean    child_exited;
1854d470362b20627044ed9e56fa47ba012cb9b4c54Hans Breuer#endif /* G_OS_WIN32 */
186540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen};
187540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen
188a62ebb0e757c972ef4bc5892d7e3e673c6426015Tim Janikstruct _GPollRec
189a62ebb0e757c972ef4bc5892d7e3e673c6426015Tim Janik{
190beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  gint priority;
191beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  GPollFD *fd;
192beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  GPollRec *next;
193beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor};
194beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
195e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor#ifdef G_THREADS_ENABLED
1968951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor#define LOCK_CONTEXT(context) g_static_mutex_lock (&context->mutex)
1978951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor#define UNLOCK_CONTEXT(context) g_static_mutex_unlock (&context->mutex)
1988951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor#define G_THREAD_SELF g_thread_self ()
199e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor#else
200e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor#define LOCK_CONTEXT(context) (void)0
201e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor#define UNLOCK_CONTEXT(context) (void)0
2028951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor#define G_THREAD_SELF NULL
203e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor#endif
204e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
205e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor#define SOURCE_DESTROYED(source) (((source)->flags & G_HOOK_FLAG_ACTIVE) == 0)
2069753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor#define SOURCE_BLOCKED(source) (((source)->flags & G_HOOK_FLAG_IN_CALL) != 0 && \
2079753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor		                ((source)->flags & G_SOURCE_CAN_RECURSE) == 0)
208e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
209e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor#define SOURCE_UNREF(source, context)                       \
210e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor   G_STMT_START {                                           \
211e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    if ((source)->ref_count > 1)                            \
212e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      (source)->ref_count--;                                \
213e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    else                                                    \
214e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      g_source_unref_internal ((source), (context), TRUE);  \
215e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor   } G_STMT_END
216e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
217e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
218beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor/* Forward declarations */
219beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
220e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorstatic void g_source_unref_internal             (GSource      *source,
221e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor						 GMainContext *context,
222e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor						 gboolean      have_lock);
223e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorstatic void g_source_destroy_internal           (GSource      *source,
224e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor						 GMainContext *context,
225e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor						 gboolean      have_lock);
226e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorstatic void g_main_context_poll                 (GMainContext *context,
227e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor						 gint          timeout,
228e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor						 gint          priority,
229e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor						 GPollFD      *fds,
230e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor						 gint          n_fds);
231e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorstatic void g_main_context_add_poll_unlocked    (GMainContext *context,
232e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor						 gint          priority,
233e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor						 GPollFD      *fd);
234e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorstatic void g_main_context_remove_poll_unlocked (GMainContext *context,
235e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor						 GPollFD      *fd);
2368951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylorstatic void g_main_context_wakeup_unlocked      (GMainContext *context);
237e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
238e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorstatic gboolean g_timeout_prepare  (GSource     *source,
239e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor				    gint        *timeout);
240e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorstatic gboolean g_timeout_check    (GSource     *source);
241e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorstatic gboolean g_timeout_dispatch (GSource     *source,
242e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor				    GSourceFunc  callback,
243e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor				    gpointer     user_data);
244540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasenstatic gboolean g_child_watch_prepare  (GSource     *source,
245540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen				        gint        *timeout);
246540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasenstatic gboolean g_child_watch_check    (GSource     *source);
247540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasenstatic gboolean g_child_watch_dispatch (GSource     *source,
248540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen					GSourceFunc  callback,
249540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen					gpointer     user_data);
250e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorstatic gboolean g_idle_prepare     (GSource     *source,
251e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor				    gint        *timeout);
252e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorstatic gboolean g_idle_check       (GSource     *source);
253e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorstatic gboolean g_idle_dispatch    (GSource     *source,
254e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor				    GSourceFunc  callback,
255e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor				    gpointer     user_data);
256e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
257b37e032581c44135b480dc74ae0355e72eef1372Sebastian WilhelmiG_LOCK_DEFINE_STATIC (main_loop);
258e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorstatic GMainContext *default_main_context;
259659fd4113b919a9491c5f872d11a445b6ea48765Sebastian Wilhelmistatic GSList *main_contexts_without_pipe = NULL;
260931ea952650b013b834041b91b0c37a748ffd449Owen Taylor
2614d470362b20627044ed9e56fa47ba012cb9b4c54Hans Breuer#ifndef G_OS_WIN32
262540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen/* Child status monitoring code */
263540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasenenum {
264540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  CHILD_WATCH_UNINITIALIZED,
265540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  CHILD_WATCH_INITIALIZED_SINGLE,
266540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  CHILD_WATCH_INITIALIZED_THREADED
267540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen};
268540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasenstatic gint child_watch_init_state = CHILD_WATCH_UNINITIALIZED;
269540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasenstatic gint child_watch_count = 0;
270540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasenstatic gint child_watch_wake_up_pipe[2] = {0, 0};
2714d470362b20627044ed9e56fa47ba012cb9b4c54Hans Breuer#endif /* !G_OS_WIN32 */
272540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias ClasenG_LOCK_DEFINE_STATIC (main_context_list);
273540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasenstatic GSList *main_context_list = NULL;
274540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen
275b4c3107c7a1dc5dd9e8050ed06f24d6be408e840Owen TaylorGSourceFuncs g_timeout_funcs =
27608425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik{
277beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  g_timeout_prepare,
278beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  g_timeout_check,
279beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  g_timeout_dispatch,
280e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  NULL
281beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor};
282beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
283540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias ClasenGSourceFuncs g_child_watch_funcs =
284540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen{
285540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  g_child_watch_prepare,
286540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  g_child_watch_check,
287540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  g_child_watch_dispatch,
288540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  NULL
289540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen};
290540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen
291b4c3107c7a1dc5dd9e8050ed06f24d6be408e840Owen TaylorGSourceFuncs g_idle_funcs =
29208425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik{
293beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  g_idle_prepare,
294beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  g_idle_check,
295beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  g_idle_dispatch,
296e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  NULL
297beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor};
298beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
299beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor#ifdef HAVE_POLL
30087c7aeb93bd654776f59805a342ad913031034f3Tim Janik/* SunOS has poll, but doesn't provide a prototype. */
30187c7aeb93bd654776f59805a342ad913031034f3Tim Janik#  if defined (sun) && !defined (__SVR4)
30287c7aeb93bd654776f59805a342ad913031034f3Tim Janikextern gint poll (GPollFD *ufds, guint nfsd, gint timeout);
30387c7aeb93bd654776f59805a342ad913031034f3Tim Janik#  endif  /* !sun */
304a62ebb0e757c972ef4bc5892d7e3e673c6426015Tim Janik#else	/* !HAVE_POLL */
305e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
3067ea73a019935e1118935433c86480acc5eee2e05Manish Singh#ifdef G_OS_WIN32
307f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist
308f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqviststatic gint
309b965bb5db1732cee8e0ed92d6484921a1431d6a9Tor Lillqvistg_poll (GPollFD *fds,
310b965bb5db1732cee8e0ed92d6484921a1431d6a9Tor Lillqvist	guint    nfds,
311b965bb5db1732cee8e0ed92d6484921a1431d6a9Tor Lillqvist	gint     timeout)
312f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist{
313f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist  HANDLE handles[MAXIMUM_WAIT_OBJECTS];
314b965bb5db1732cee8e0ed92d6484921a1431d6a9Tor Lillqvist  gboolean poll_msgs = FALSE;
315f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist  GPollFD *f;
316f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist  DWORD ready;
317f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist  MSG msg;
318f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist  UINT timer;
319f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist  gint nhandles = 0;
320f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist
321f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist  for (f = fds; f < &fds[nfds]; ++f)
322f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist    if (f->fd >= 0)
323f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist      {
324a488638747f175320004b424821424488c82c4acTor Lillqvist	if (f->fd == G_WIN32_MSG_HANDLE)
325a488638747f175320004b424821424488c82c4acTor Lillqvist	  poll_msgs = TRUE;
3263f3bb7fef336bbe8da051644c7333bc8f4e03f11Tor Lillqvist	else if (nhandles == MAXIMUM_WAIT_OBJECTS)
3273f3bb7fef336bbe8da051644c7333bc8f4e03f11Tor Lillqvist	  {
3283f3bb7fef336bbe8da051644c7333bc8f4e03f11Tor Lillqvist	    g_warning (G_STRLOC ": Too many handles to wait for!\n");
3293f3bb7fef336bbe8da051644c7333bc8f4e03f11Tor Lillqvist	    break;
3303f3bb7fef336bbe8da051644c7333bc8f4e03f11Tor Lillqvist	  }
331a488638747f175320004b424821424488c82c4acTor Lillqvist	else
332b965bb5db1732cee8e0ed92d6484921a1431d6a9Tor Lillqvist	  {
333b965bb5db1732cee8e0ed92d6484921a1431d6a9Tor Lillqvist#ifdef G_MAIN_POLL_DEBUG
334a488638747f175320004b424821424488c82c4acTor Lillqvist	    g_print ("g_poll: waiting for %#x\n", f->fd);
335b965bb5db1732cee8e0ed92d6484921a1431d6a9Tor Lillqvist#endif
336a488638747f175320004b424821424488c82c4acTor Lillqvist	    handles[nhandles++] = (HANDLE) f->fd;
337b965bb5db1732cee8e0ed92d6484921a1431d6a9Tor Lillqvist	  }
338f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist      }
339f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist
340f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist  if (timeout == -1)
341f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist    timeout = INFINITE;
342f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist
343b965bb5db1732cee8e0ed92d6484921a1431d6a9Tor Lillqvist  if (poll_msgs)
344f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist    {
3458a0df0a71c88c04d4fccbc6780b7105bc527261bTor Lillqvist      /* Waiting for messages, and maybe events
3468a0df0a71c88c04d4fccbc6780b7105bc527261bTor Lillqvist       * -> First PeekMessage
3478a0df0a71c88c04d4fccbc6780b7105bc527261bTor Lillqvist       */
348b965bb5db1732cee8e0ed92d6484921a1431d6a9Tor Lillqvist#ifdef G_MAIN_POLL_DEBUG
3498a0df0a71c88c04d4fccbc6780b7105bc527261bTor Lillqvist      g_print ("PeekMessage\n");
350b965bb5db1732cee8e0ed92d6484921a1431d6a9Tor Lillqvist#endif
3518a0df0a71c88c04d4fccbc6780b7105bc527261bTor Lillqvist      if (PeekMessage (&msg, NULL, 0, 0, PM_NOREMOVE))
3528a0df0a71c88c04d4fccbc6780b7105bc527261bTor Lillqvist	ready = WAIT_OBJECT_0 + nhandles;
3538a0df0a71c88c04d4fccbc6780b7105bc527261bTor Lillqvist      else
3548a0df0a71c88c04d4fccbc6780b7105bc527261bTor Lillqvist	{
3558a0df0a71c88c04d4fccbc6780b7105bc527261bTor Lillqvist	  if (nhandles == 0)
356f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist	    {
3578a0df0a71c88c04d4fccbc6780b7105bc527261bTor Lillqvist	      /* Waiting just for messages */
3588a0df0a71c88c04d4fccbc6780b7105bc527261bTor Lillqvist	      if (timeout == INFINITE)
3598a0df0a71c88c04d4fccbc6780b7105bc527261bTor Lillqvist		{
3608a0df0a71c88c04d4fccbc6780b7105bc527261bTor Lillqvist		  /* Infinite timeout
3618a0df0a71c88c04d4fccbc6780b7105bc527261bTor Lillqvist		   * -> WaitMessage
3628a0df0a71c88c04d4fccbc6780b7105bc527261bTor Lillqvist		   */
363b965bb5db1732cee8e0ed92d6484921a1431d6a9Tor Lillqvist#ifdef G_MAIN_POLL_DEBUG
3648a0df0a71c88c04d4fccbc6780b7105bc527261bTor Lillqvist		  g_print ("WaitMessage\n");
365b965bb5db1732cee8e0ed92d6484921a1431d6a9Tor Lillqvist#endif
3668a0df0a71c88c04d4fccbc6780b7105bc527261bTor Lillqvist		  if (!WaitMessage ())
3671cf610e216072fdb49d170d898bd4b7178ea3d2bTor Lillqvist		    {
3681cf610e216072fdb49d170d898bd4b7178ea3d2bTor Lillqvist		      gchar *emsg = g_win32_error_message (GetLastError ());
3691cf610e216072fdb49d170d898bd4b7178ea3d2bTor Lillqvist		      g_warning (G_STRLOC ": WaitMessage() failed: %s", emsg);
3701cf610e216072fdb49d170d898bd4b7178ea3d2bTor Lillqvist		      g_free (emsg);
3711cf610e216072fdb49d170d898bd4b7178ea3d2bTor Lillqvist		    }
3728a0df0a71c88c04d4fccbc6780b7105bc527261bTor Lillqvist		  ready = WAIT_OBJECT_0 + nhandles;
3738a0df0a71c88c04d4fccbc6780b7105bc527261bTor Lillqvist		}
3748a0df0a71c88c04d4fccbc6780b7105bc527261bTor Lillqvist	      else if (timeout == 0)
3758a0df0a71c88c04d4fccbc6780b7105bc527261bTor Lillqvist		{
3768a0df0a71c88c04d4fccbc6780b7105bc527261bTor Lillqvist		  /* Waiting just for messages, zero timeout.
3778a0df0a71c88c04d4fccbc6780b7105bc527261bTor Lillqvist		   * If we got here, there was no message
3788a0df0a71c88c04d4fccbc6780b7105bc527261bTor Lillqvist		   */
3798a0df0a71c88c04d4fccbc6780b7105bc527261bTor Lillqvist		  ready = WAIT_TIMEOUT;
3808a0df0a71c88c04d4fccbc6780b7105bc527261bTor Lillqvist		}
381f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist	      else
3828a0df0a71c88c04d4fccbc6780b7105bc527261bTor Lillqvist		{
3838a0df0a71c88c04d4fccbc6780b7105bc527261bTor Lillqvist		  /* Waiting just for messages, some timeout
3848a0df0a71c88c04d4fccbc6780b7105bc527261bTor Lillqvist		   * -> Set a timer, wait for message,
3858a0df0a71c88c04d4fccbc6780b7105bc527261bTor Lillqvist		   * kill timer, use PeekMessage
3868a0df0a71c88c04d4fccbc6780b7105bc527261bTor Lillqvist		   */
387c2bd295c57059ac0c14d6fbb3741b1f69dbc4ff3Tor Lillqvist		  timer = SetTimer (NULL, 0, timeout, NULL);
388c2bd295c57059ac0c14d6fbb3741b1f69dbc4ff3Tor Lillqvist		  if (timer == 0)
389a488638747f175320004b424821424488c82c4acTor Lillqvist		    {
3901cf610e216072fdb49d170d898bd4b7178ea3d2bTor Lillqvist		      gchar *emsg = g_win32_error_message (GetLastError ());
3911cf610e216072fdb49d170d898bd4b7178ea3d2bTor Lillqvist		      g_warning (G_STRLOC ": SetTimer() failed: %s", emsg);
3921cf610e216072fdb49d170d898bd4b7178ea3d2bTor Lillqvist		      g_free (emsg);
393a488638747f175320004b424821424488c82c4acTor Lillqvist		      ready = WAIT_TIMEOUT;
394a488638747f175320004b424821424488c82c4acTor Lillqvist		    }
3958a0df0a71c88c04d4fccbc6780b7105bc527261bTor Lillqvist		  else
3968a0df0a71c88c04d4fccbc6780b7105bc527261bTor Lillqvist		    {
397b965bb5db1732cee8e0ed92d6484921a1431d6a9Tor Lillqvist#ifdef G_MAIN_POLL_DEBUG
3988a0df0a71c88c04d4fccbc6780b7105bc527261bTor Lillqvist		      g_print ("WaitMessage\n");
399b965bb5db1732cee8e0ed92d6484921a1431d6a9Tor Lillqvist#endif
4008a0df0a71c88c04d4fccbc6780b7105bc527261bTor Lillqvist		      WaitMessage ();
4018a0df0a71c88c04d4fccbc6780b7105bc527261bTor Lillqvist		      KillTimer (NULL, timer);
402b965bb5db1732cee8e0ed92d6484921a1431d6a9Tor Lillqvist#ifdef G_MAIN_POLL_DEBUG
4038a0df0a71c88c04d4fccbc6780b7105bc527261bTor Lillqvist		      g_print ("PeekMessage\n");
404b965bb5db1732cee8e0ed92d6484921a1431d6a9Tor Lillqvist#endif
4058a0df0a71c88c04d4fccbc6780b7105bc527261bTor Lillqvist		      if (PeekMessage (&msg, NULL, 0, 0, PM_NOREMOVE)
4068a0df0a71c88c04d4fccbc6780b7105bc527261bTor Lillqvist			  && msg.message != WM_TIMER)
4078a0df0a71c88c04d4fccbc6780b7105bc527261bTor Lillqvist			ready = WAIT_OBJECT_0;
4088a0df0a71c88c04d4fccbc6780b7105bc527261bTor Lillqvist		      else
4098a0df0a71c88c04d4fccbc6780b7105bc527261bTor Lillqvist			ready = WAIT_TIMEOUT;
4108a0df0a71c88c04d4fccbc6780b7105bc527261bTor Lillqvist		    }
411f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist		}
412f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist	    }
4138a0df0a71c88c04d4fccbc6780b7105bc527261bTor Lillqvist	  else
4148a0df0a71c88c04d4fccbc6780b7105bc527261bTor Lillqvist	    {
4158a0df0a71c88c04d4fccbc6780b7105bc527261bTor Lillqvist	      /* Wait for either message or event
4168a0df0a71c88c04d4fccbc6780b7105bc527261bTor Lillqvist	       * -> Use MsgWaitForMultipleObjects
4178a0df0a71c88c04d4fccbc6780b7105bc527261bTor Lillqvist	       */
418b965bb5db1732cee8e0ed92d6484921a1431d6a9Tor Lillqvist#ifdef G_MAIN_POLL_DEBUG
4198a0df0a71c88c04d4fccbc6780b7105bc527261bTor Lillqvist	      g_print ("MsgWaitForMultipleObjects(%d, %d)\n", nhandles, timeout);
420b965bb5db1732cee8e0ed92d6484921a1431d6a9Tor Lillqvist#endif
4218a0df0a71c88c04d4fccbc6780b7105bc527261bTor Lillqvist	      ready = MsgWaitForMultipleObjects (nhandles, handles, FALSE,
4228a0df0a71c88c04d4fccbc6780b7105bc527261bTor Lillqvist						 timeout, QS_ALLINPUT);
423b965bb5db1732cee8e0ed92d6484921a1431d6a9Tor Lillqvist
4248a0df0a71c88c04d4fccbc6780b7105bc527261bTor Lillqvist	      if (ready == WAIT_FAILED)
4251cf610e216072fdb49d170d898bd4b7178ea3d2bTor Lillqvist		{
4261cf610e216072fdb49d170d898bd4b7178ea3d2bTor Lillqvist		  gchar *emsg = g_win32_error_message (GetLastError ());
4271cf610e216072fdb49d170d898bd4b7178ea3d2bTor Lillqvist		  g_warning (G_STRLOC ": MsgWaitForMultipleObjects() failed: %s", emsg);
4281cf610e216072fdb49d170d898bd4b7178ea3d2bTor Lillqvist		  g_free (emsg);
4291cf610e216072fdb49d170d898bd4b7178ea3d2bTor Lillqvist		}
4308a0df0a71c88c04d4fccbc6780b7105bc527261bTor Lillqvist	    }
431f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist	}
432f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist    }
433f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist  else if (nhandles == 0)
434f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist    {
435f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist      /* Wait for nothing (huh?) */
436f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist      return 0;
437f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist    }
438f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist  else
439f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist    {
440f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist      /* Wait for just events
441f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist       * -> Use WaitForMultipleObjects
442f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist       */
443b965bb5db1732cee8e0ed92d6484921a1431d6a9Tor Lillqvist#ifdef G_MAIN_POLL_DEBUG
444b965bb5db1732cee8e0ed92d6484921a1431d6a9Tor Lillqvist      g_print ("WaitForMultipleObjects(%d, %d)\n", nhandles, timeout);
445b965bb5db1732cee8e0ed92d6484921a1431d6a9Tor Lillqvist#endif
446f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist      ready = WaitForMultipleObjects (nhandles, handles, FALSE, timeout);
447f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist      if (ready == WAIT_FAILED)
4481cf610e216072fdb49d170d898bd4b7178ea3d2bTor Lillqvist	{
4491cf610e216072fdb49d170d898bd4b7178ea3d2bTor Lillqvist	  gchar *emsg = g_win32_error_message (GetLastError ());
4501cf610e216072fdb49d170d898bd4b7178ea3d2bTor Lillqvist	  g_warning (G_STRLOC ": WaitForMultipleObjects() failed: %s", emsg);
4511cf610e216072fdb49d170d898bd4b7178ea3d2bTor Lillqvist	  g_free (emsg);
4521cf610e216072fdb49d170d898bd4b7178ea3d2bTor Lillqvist	}
453f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist    }
454f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist
4558a0df0a71c88c04d4fccbc6780b7105bc527261bTor Lillqvist#ifdef G_MAIN_POLL_DEBUG
456a488638747f175320004b424821424488c82c4acTor Lillqvist  g_print ("wait returns %ld%s\n",
4578a0df0a71c88c04d4fccbc6780b7105bc527261bTor Lillqvist	   ready,
4588a0df0a71c88c04d4fccbc6780b7105bc527261bTor Lillqvist	   (ready == WAIT_FAILED ? " (WAIT_FAILED)" :
4598a0df0a71c88c04d4fccbc6780b7105bc527261bTor Lillqvist	    (ready == WAIT_TIMEOUT ? " (WAIT_TIMEOUT)" :
4608a0df0a71c88c04d4fccbc6780b7105bc527261bTor Lillqvist	     (poll_msgs && ready == WAIT_OBJECT_0 + nhandles ? " (msg)" : ""))));
4618a0df0a71c88c04d4fccbc6780b7105bc527261bTor Lillqvist#endif
462f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist  for (f = fds; f < &fds[nfds]; ++f)
463f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist    f->revents = 0;
464f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist
465f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist  if (ready == WAIT_FAILED)
466f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist    return -1;
467b965bb5db1732cee8e0ed92d6484921a1431d6a9Tor Lillqvist  else if (ready == WAIT_TIMEOUT)
468b965bb5db1732cee8e0ed92d6484921a1431d6a9Tor Lillqvist    return 0;
469b965bb5db1732cee8e0ed92d6484921a1431d6a9Tor Lillqvist  else if (poll_msgs && ready == WAIT_OBJECT_0 + nhandles)
470f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist    {
471b965bb5db1732cee8e0ed92d6484921a1431d6a9Tor Lillqvist      for (f = fds; f < &fds[nfds]; ++f)
472b965bb5db1732cee8e0ed92d6484921a1431d6a9Tor Lillqvist	if (f->fd >= 0)
473b965bb5db1732cee8e0ed92d6484921a1431d6a9Tor Lillqvist	  {
474b965bb5db1732cee8e0ed92d6484921a1431d6a9Tor Lillqvist	    if (f->events & G_IO_IN)
475b965bb5db1732cee8e0ed92d6484921a1431d6a9Tor Lillqvist	      if (f->fd == G_WIN32_MSG_HANDLE)
476b965bb5db1732cee8e0ed92d6484921a1431d6a9Tor Lillqvist		f->revents |= G_IO_IN;
477b965bb5db1732cee8e0ed92d6484921a1431d6a9Tor Lillqvist	  }
478f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist    }
47934462896a035f9cd89668ca9441720e8fc625ee7Bruno Haible#if 1 /* TEST_WITHOUT_THIS */
480f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist  else if (ready >= WAIT_OBJECT_0 && ready < WAIT_OBJECT_0 + nhandles)
481f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist    for (f = fds; f < &fds[nfds]; ++f)
482f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist      {
483a488638747f175320004b424821424488c82c4acTor Lillqvist	if ((f->events & (G_IO_IN | G_IO_OUT))
484f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist	    && f->fd == (gint) handles[ready - WAIT_OBJECT_0])
485f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist	  {
486a488638747f175320004b424821424488c82c4acTor Lillqvist	    if (f->events & G_IO_IN)
487a488638747f175320004b424821424488c82c4acTor Lillqvist	      f->revents |= G_IO_IN;
488a488638747f175320004b424821424488c82c4acTor Lillqvist	    else
489a488638747f175320004b424821424488c82c4acTor Lillqvist	      f->revents |= G_IO_OUT;
490b965bb5db1732cee8e0ed92d6484921a1431d6a9Tor Lillqvist#ifdef G_MAIN_POLL_DEBUG
491b965bb5db1732cee8e0ed92d6484921a1431d6a9Tor Lillqvist	    g_print ("g_poll: got event %#x\n", f->fd);
492b965bb5db1732cee8e0ed92d6484921a1431d6a9Tor Lillqvist#endif
493b965bb5db1732cee8e0ed92d6484921a1431d6a9Tor Lillqvist#if 0
494f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist	    ResetEvent ((HANDLE) f->fd);
495b965bb5db1732cee8e0ed92d6484921a1431d6a9Tor Lillqvist#endif
496f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist	  }
497f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist      }
4988a0df0a71c88c04d4fccbc6780b7105bc527261bTor Lillqvist#endif
499f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist
5008a0df0a71c88c04d4fccbc6780b7105bc527261bTor Lillqvist  return 1;
501f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist}
502f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist
5037ea73a019935e1118935433c86480acc5eee2e05Manish Singh#else  /* !G_OS_WIN32 */
504beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
505beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor/* The following implementation of poll() comes from the GNU C Library.
506beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor * Copyright (C) 1994, 1996, 1997 Free Software Foundation, Inc.
507beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor */
508beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
509738864a1a758b2421211e4ecf1ce6102842428eaManish Singh#include <string.h> /* for bzero on BSD systems */
510738864a1a758b2421211e4ecf1ce6102842428eaManish Singh
511beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor#ifdef HAVE_SYS_SELECT_H
512beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor#include <sys/select.h>
513bfc21756e14e4600c916c00e6ee03e1c10e0cc01Raja R Harinath#endif /* HAVE_SYS_SELECT_H */
514beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
5157ea73a019935e1118935433c86480acc5eee2e05Manish Singh#ifdef G_OS_BEOS
516499c9786d1316bc72c539d55786bb3a65d95a83aCDT#undef NO_FD_SET
5177ea73a019935e1118935433c86480acc5eee2e05Manish Singh#endif /* G_OS_BEOS */
518499c9786d1316bc72c539d55786bb3a65d95a83aCDT
519beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor#ifndef NO_FD_SET
520beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor#  define SELECT_MASK fd_set
52108425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik#else /* !NO_FD_SET */
52287c7aeb93bd654776f59805a342ad913031034f3Tim Janik#  ifndef _AIX
52387c7aeb93bd654776f59805a342ad913031034f3Tim Janiktypedef long fd_mask;
52487c7aeb93bd654776f59805a342ad913031034f3Tim Janik#  endif /* _AIX */
52508425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik#  ifdef _IBMR2
526beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor#    define SELECT_MASK void
52708425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik#  else /* !_IBMR2 */
528beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor#    define SELECT_MASK int
52908425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik#  endif /* !_IBMR2 */
53008425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik#endif /* !NO_FD_SET */
531beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
532beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylorstatic gint
53308425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janikg_poll (GPollFD *fds,
53408425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik	guint    nfds,
53508425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik	gint     timeout)
536beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor{
537beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  struct timeval tv;
538beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  SELECT_MASK rset, wset, xset;
539beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  GPollFD *f;
540beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  int ready;
541beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  int maxfd = 0;
542beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
543beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  FD_ZERO (&rset);
544beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  FD_ZERO (&wset);
545beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  FD_ZERO (&xset);
546beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
547beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  for (f = fds; f < &fds[nfds]; ++f)
548beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor    if (f->fd >= 0)
549beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor      {
550beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor	if (f->events & G_IO_IN)
551beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor	  FD_SET (f->fd, &rset);
552beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor	if (f->events & G_IO_OUT)
553beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor	  FD_SET (f->fd, &wset);
554beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor	if (f->events & G_IO_PRI)
555beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor	  FD_SET (f->fd, &xset);
556738864a1a758b2421211e4ecf1ce6102842428eaManish Singh	if (f->fd > maxfd && (f->events & (G_IO_IN|G_IO_OUT|G_IO_PRI)))
557beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor	  maxfd = f->fd;
558beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor      }
559beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
560beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  tv.tv_sec = timeout / 1000;
561beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  tv.tv_usec = (timeout % 1000) * 1000;
562beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
563beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  ready = select (maxfd + 1, &rset, &wset, &xset,
564beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor		  timeout == -1 ? NULL : &tv);
565beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  if (ready > 0)
566beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor    for (f = fds; f < &fds[nfds]; ++f)
567beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor      {
568beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor	f->revents = 0;
569beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor	if (f->fd >= 0)
570beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor	  {
571beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor	    if (FD_ISSET (f->fd, &rset))
572beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor	      f->revents |= G_IO_IN;
573beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor	    if (FD_ISSET (f->fd, &wset))
574beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor	      f->revents |= G_IO_OUT;
575beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor	    if (FD_ISSET (f->fd, &xset))
576beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor	      f->revents |= G_IO_PRI;
577beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor	  }
578beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor      }
579beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
580beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  return ready;
581beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor}
58208425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik
5837ea73a019935e1118935433c86480acc5eee2e05Manish Singh#endif /* !G_OS_WIN32 */
584f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist
585a62ebb0e757c972ef4bc5892d7e3e673c6426015Tim Janik#endif	/* !HAVE_POLL */
586beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
5878951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor/**
5888951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor * g_main_context_ref:
58916fc3b22c0ae7ca268f34d554da4f4850748d335Owen Taylor * @context: a #GMainContext
5908951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor *
5918951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor * Increases the reference count on a #GMainContext object by one.
5928951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor **/
5937b06f826c942bf691b1fe6e52546ebcee3eecb5aSebastian Wilhelmivoid
5948951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylorg_main_context_ref (GMainContext *context)
595dc602866312bff134f4d827190f5c24934970e19Owen Taylor{
5968951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  g_return_if_fail (context != NULL);
597c40b15fc6b37d152d67c2d2ec18d0e635ea70f90Sebastian Wilhelmi  g_return_if_fail (g_atomic_int_get (&context->ref_count) > 0);
5988951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor
599c40b15fc6b37d152d67c2d2ec18d0e635ea70f90Sebastian Wilhelmi  g_atomic_int_inc (&context->ref_count);
6008951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor}
6018951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor
6022afc40f3a62146ac0518cf6fa6d936c708f66d42Owen Taylor/* If DISABLE_MEM_POOLS is defined, then freeing the
6032afc40f3a62146ac0518cf6fa6d936c708f66d42Owen Taylor * mem chunk won't free the records, so we have to
6042afc40f3a62146ac0518cf6fa6d936c708f66d42Owen Taylor * do it manually. The conditionalization here is
6052afc40f3a62146ac0518cf6fa6d936c708f66d42Owen Taylor * an optimization; g_mem_chunk_free() is a no-op
6062afc40f3a62146ac0518cf6fa6d936c708f66d42Owen Taylor * when DISABLE_MEM_POOLS is set.
6072afc40f3a62146ac0518cf6fa6d936c708f66d42Owen Taylor */
6082afc40f3a62146ac0518cf6fa6d936c708f66d42Owen Taylor#ifdef DISABLE_MEM_POOLS
6092afc40f3a62146ac0518cf6fa6d936c708f66d42Owen Taylorstatic void
6102afc40f3a62146ac0518cf6fa6d936c708f66d42Owen Taylorpoll_rec_list_free (GMainContext *context,
6112afc40f3a62146ac0518cf6fa6d936c708f66d42Owen Taylor		    GPollRec     *list)
6122afc40f3a62146ac0518cf6fa6d936c708f66d42Owen Taylor{
6132afc40f3a62146ac0518cf6fa6d936c708f66d42Owen Taylor  while (list)
6142afc40f3a62146ac0518cf6fa6d936c708f66d42Owen Taylor    {
6152afc40f3a62146ac0518cf6fa6d936c708f66d42Owen Taylor      GPollRec *tmp_rec = list;
6162afc40f3a62146ac0518cf6fa6d936c708f66d42Owen Taylor      list = list->next;
6172afc40f3a62146ac0518cf6fa6d936c708f66d42Owen Taylor      g_chunk_free (tmp_rec, context->poll_chunk);
6182afc40f3a62146ac0518cf6fa6d936c708f66d42Owen Taylor    }
6192afc40f3a62146ac0518cf6fa6d936c708f66d42Owen Taylor}
6202afc40f3a62146ac0518cf6fa6d936c708f66d42Owen Taylor#endif /* DISABLE_MEM_POOLS */
6212afc40f3a62146ac0518cf6fa6d936c708f66d42Owen Taylor
622c40b15fc6b37d152d67c2d2ec18d0e635ea70f90Sebastian Wilhelmi/**
623c40b15fc6b37d152d67c2d2ec18d0e635ea70f90Sebastian Wilhelmi * g_main_context_unref:
624c40b15fc6b37d152d67c2d2ec18d0e635ea70f90Sebastian Wilhelmi * @context: a #GMainContext
625c40b15fc6b37d152d67c2d2ec18d0e635ea70f90Sebastian Wilhelmi *
626c40b15fc6b37d152d67c2d2ec18d0e635ea70f90Sebastian Wilhelmi * Decreases the reference count on a #GMainContext object by one. If
627c40b15fc6b37d152d67c2d2ec18d0e635ea70f90Sebastian Wilhelmi * the result is zero, free the context and free all associated memory.
628c40b15fc6b37d152d67c2d2ec18d0e635ea70f90Sebastian Wilhelmi **/
629c40b15fc6b37d152d67c2d2ec18d0e635ea70f90Sebastian Wilhelmivoid
630c40b15fc6b37d152d67c2d2ec18d0e635ea70f90Sebastian Wilhelmig_main_context_unref (GMainContext *context)
6318951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor{
6328951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  GSource *source;
633c40b15fc6b37d152d67c2d2ec18d0e635ea70f90Sebastian Wilhelmi  g_return_if_fail (context != NULL);
634c40b15fc6b37d152d67c2d2ec18d0e635ea70f90Sebastian Wilhelmi  g_return_if_fail (g_atomic_int_get (&context->ref_count) > 0);
6358951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor
636c40b15fc6b37d152d67c2d2ec18d0e635ea70f90Sebastian Wilhelmi  if (!g_atomic_int_dec_and_test (&context->ref_count))
637c40b15fc6b37d152d67c2d2ec18d0e635ea70f90Sebastian Wilhelmi    return;
6388951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor
639540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  G_LOCK (main_context_list);
640540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  main_context_list = g_slist_remove (main_context_list, context);
641540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  G_UNLOCK (main_context_list);
642540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen
643e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  source = context->source_list;
644e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  while (source)
645e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    {
646e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      GSource *next = source->next;
647e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      g_source_destroy_internal (source, context, TRUE);
648e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      source = next;
649e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    }
65008425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik
651e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor#ifdef G_THREADS_ENABLED
6528951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  g_static_mutex_free (&context->mutex);
653e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor#endif
65408425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik
655e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  g_ptr_array_free (context->pending_dispatches, TRUE);
656e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  g_free (context->cached_poll_array);
6572afc40f3a62146ac0518cf6fa6d936c708f66d42Owen Taylor
6582afc40f3a62146ac0518cf6fa6d936c708f66d42Owen Taylor#ifdef DISABLE_MEM_POLLS
6592afc40f3a62146ac0518cf6fa6d936c708f66d42Owen Taylor  poll_rec_list_free (context, context->poll_records);
6602afc40f3a62146ac0518cf6fa6d936c708f66d42Owen Taylor  poll_rec_list_free (context, context->poll_free_list);
6612afc40f3a62146ac0518cf6fa6d936c708f66d42Owen Taylor#endif /* DISABLE_MEM_POOLS */
6622afc40f3a62146ac0518cf6fa6d936c708f66d42Owen Taylor
663ca1ff92c511cd264886fc2384a4275d8566e1d0bManish Singh  if (context->poll_chunk)
664ca1ff92c511cd264886fc2384a4275d8566e1d0bManish Singh    g_mem_chunk_destroy (context->poll_chunk);
66508425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik
6669edb08492d09a36caf389f639f45c8c1c8315f10Havoc Pennington#ifdef G_THREADS_ENABLED
667e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  if (g_thread_supported())
668e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    {
669e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor#ifndef G_OS_WIN32
670e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      close (context->wake_up_pipe[0]);
671e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      close (context->wake_up_pipe[1]);
672e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor#else
673e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      CloseHandle (context->wake_up_semaphore);
674e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor#endif
675659fd4113b919a9491c5f872d11a445b6ea48765Sebastian Wilhelmi    }
676659fd4113b919a9491c5f872d11a445b6ea48765Sebastian Wilhelmi  else
677659fd4113b919a9491c5f872d11a445b6ea48765Sebastian Wilhelmi    main_contexts_without_pipe = g_slist_remove (main_contexts_without_pipe,
678659fd4113b919a9491c5f872d11a445b6ea48765Sebastian Wilhelmi						 context);
6799edb08492d09a36caf389f639f45c8c1c8315f10Havoc Pennington#endif
680e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
681e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  g_free (context);
682dc602866312bff134f4d827190f5c24934970e19Owen Taylor}
683dc602866312bff134f4d827190f5c24934970e19Owen Taylor
684659fd4113b919a9491c5f872d11a445b6ea48765Sebastian Wilhelmi#ifdef G_THREADS_ENABLED
685659fd4113b919a9491c5f872d11a445b6ea48765Sebastian Wilhelmistatic void
686659fd4113b919a9491c5f872d11a445b6ea48765Sebastian Wilhelmig_main_context_init_pipe (GMainContext *context)
687659fd4113b919a9491c5f872d11a445b6ea48765Sebastian Wilhelmi{
688fc9afe0d219ad7bb16c2ba8ce2a1e268bdd25479Hans Breuer# ifndef G_OS_WIN32
689540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  if (context->wake_up_pipe[0] != -1)
690540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen    return;
691659fd4113b919a9491c5f872d11a445b6ea48765Sebastian Wilhelmi  if (pipe (context->wake_up_pipe) < 0)
692659fd4113b919a9491c5f872d11a445b6ea48765Sebastian Wilhelmi    g_error ("Cannot create pipe main loop wake-up: %s\n",
693659fd4113b919a9491c5f872d11a445b6ea48765Sebastian Wilhelmi	     g_strerror (errno));
694659fd4113b919a9491c5f872d11a445b6ea48765Sebastian Wilhelmi
695659fd4113b919a9491c5f872d11a445b6ea48765Sebastian Wilhelmi  context->wake_up_rec.fd = context->wake_up_pipe[0];
696659fd4113b919a9491c5f872d11a445b6ea48765Sebastian Wilhelmi  context->wake_up_rec.events = G_IO_IN;
697659fd4113b919a9491c5f872d11a445b6ea48765Sebastian Wilhelmi# else
698fc9afe0d219ad7bb16c2ba8ce2a1e268bdd25479Hans Breuer  if (context->wake_up_semaphore != NULL)
699fc9afe0d219ad7bb16c2ba8ce2a1e268bdd25479Hans Breuer    return;
700659fd4113b919a9491c5f872d11a445b6ea48765Sebastian Wilhelmi  context->wake_up_semaphore = CreateSemaphore (NULL, 0, 100, NULL);
701659fd4113b919a9491c5f872d11a445b6ea48765Sebastian Wilhelmi  if (context->wake_up_semaphore == NULL)
702659fd4113b919a9491c5f872d11a445b6ea48765Sebastian Wilhelmi    g_error ("Cannot create wake-up semaphore: %s",
703659fd4113b919a9491c5f872d11a445b6ea48765Sebastian Wilhelmi	     g_win32_error_message (GetLastError ()));
704659fd4113b919a9491c5f872d11a445b6ea48765Sebastian Wilhelmi  context->wake_up_rec.fd = (gint) context->wake_up_semaphore;
705659fd4113b919a9491c5f872d11a445b6ea48765Sebastian Wilhelmi  context->wake_up_rec.events = G_IO_IN;
706659fd4113b919a9491c5f872d11a445b6ea48765Sebastian Wilhelmi#  ifdef G_MAIN_POLL_DEBUG
707659fd4113b919a9491c5f872d11a445b6ea48765Sebastian Wilhelmi  g_print ("wake-up semaphore: %#x\n", (guint) context->wake_up_semaphore);
708659fd4113b919a9491c5f872d11a445b6ea48765Sebastian Wilhelmi#  endif
709659fd4113b919a9491c5f872d11a445b6ea48765Sebastian Wilhelmi# endif
710659fd4113b919a9491c5f872d11a445b6ea48765Sebastian Wilhelmi  g_main_context_add_poll_unlocked (context, 0, &context->wake_up_rec);
711659fd4113b919a9491c5f872d11a445b6ea48765Sebastian Wilhelmi}
712659fd4113b919a9491c5f872d11a445b6ea48765Sebastian Wilhelmi
713659fd4113b919a9491c5f872d11a445b6ea48765Sebastian Wilhelmivoid
7148e91cf9eb98da826abc1384418b5e9a4401048b8Sebastian Wilhelmi_g_main_thread_init ()
715659fd4113b919a9491c5f872d11a445b6ea48765Sebastian Wilhelmi{
716659fd4113b919a9491c5f872d11a445b6ea48765Sebastian Wilhelmi  GSList *curr = main_contexts_without_pipe;
717659fd4113b919a9491c5f872d11a445b6ea48765Sebastian Wilhelmi  while (curr)
718659fd4113b919a9491c5f872d11a445b6ea48765Sebastian Wilhelmi    {
719659fd4113b919a9491c5f872d11a445b6ea48765Sebastian Wilhelmi      g_main_context_init_pipe ((GMainContext *)curr->data);
720659fd4113b919a9491c5f872d11a445b6ea48765Sebastian Wilhelmi      curr = curr->next;
721659fd4113b919a9491c5f872d11a445b6ea48765Sebastian Wilhelmi    }
722659fd4113b919a9491c5f872d11a445b6ea48765Sebastian Wilhelmi  g_slist_free (main_contexts_without_pipe);
723659fd4113b919a9491c5f872d11a445b6ea48765Sebastian Wilhelmi  main_contexts_without_pipe = NULL;
724659fd4113b919a9491c5f872d11a445b6ea48765Sebastian Wilhelmi}
725659fd4113b919a9491c5f872d11a445b6ea48765Sebastian Wilhelmi#endif /* G_THREADS_ENABLED */
726659fd4113b919a9491c5f872d11a445b6ea48765Sebastian Wilhelmi
727e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor/**
7288951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor * g_main_context_new:
729e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *
7308951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor * Creates a new #GMainContext strcuture
731e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *
7328951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor * Return value: the new #GMainContext
733e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor **/
734e2fd4e2bd0589b159f87b491095565d16fac2789Owen TaylorGMainContext *
7358951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylorg_main_context_new ()
736e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor{
7378951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  GMainContext *context = g_new0 (GMainContext, 1);
73870a7a7654ef87c05a281318262ed635b90ffeebeOwen Taylor
73970a7a7654ef87c05a281318262ed635b90ffeebeOwen Taylor#ifdef G_THREADS_ENABLED
7408951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  g_static_mutex_init (&context->mutex);
74170a7a7654ef87c05a281318262ed635b90ffeebeOwen Taylor
7428951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  context->owner = NULL;
7438951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  context->waiters = NULL;
744540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen
745fc9afe0d219ad7bb16c2ba8ce2a1e268bdd25479Hans Breuer# ifndef G_OS_WIN32
746540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  context->wake_up_pipe[0] = -1;
747540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  context->wake_up_pipe[1] = -1;
748fc9afe0d219ad7bb16c2ba8ce2a1e268bdd25479Hans Breuer# else
749fc9afe0d219ad7bb16c2ba8ce2a1e268bdd25479Hans Breuer  context->wake_up_semaphore = NULL;
750fc9afe0d219ad7bb16c2ba8ce2a1e268bdd25479Hans Breuer# endif
751f18db7d2d498c80d58d2ac7abb082529d3b06a12Sebastian Wilhelmi#endif
752540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen
7538951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  context->ref_count = 1;
7548951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor
755659fd4113b919a9491c5f872d11a445b6ea48765Sebastian Wilhelmi  context->next_id = 1;
756659fd4113b919a9491c5f872d11a445b6ea48765Sebastian Wilhelmi
757659fd4113b919a9491c5f872d11a445b6ea48765Sebastian Wilhelmi  context->source_list = NULL;
758659fd4113b919a9491c5f872d11a445b6ea48765Sebastian Wilhelmi
759e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor#if HAVE_POLL
760659fd4113b919a9491c5f872d11a445b6ea48765Sebastian Wilhelmi  context->poll_func = (GPollFunc)poll;
761e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor#else
762659fd4113b919a9491c5f872d11a445b6ea48765Sebastian Wilhelmi  context->poll_func = g_poll;
763e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor#endif
764659fd4113b919a9491c5f872d11a445b6ea48765Sebastian Wilhelmi
765659fd4113b919a9491c5f872d11a445b6ea48765Sebastian Wilhelmi  context->cached_poll_array = NULL;
766659fd4113b919a9491c5f872d11a445b6ea48765Sebastian Wilhelmi  context->cached_poll_array_size = 0;
767659fd4113b919a9491c5f872d11a445b6ea48765Sebastian Wilhelmi
768659fd4113b919a9491c5f872d11a445b6ea48765Sebastian Wilhelmi  context->pending_dispatches = g_ptr_array_new ();
769659fd4113b919a9491c5f872d11a445b6ea48765Sebastian Wilhelmi
770659fd4113b919a9491c5f872d11a445b6ea48765Sebastian Wilhelmi  context->time_is_current = FALSE;
771659fd4113b919a9491c5f872d11a445b6ea48765Sebastian Wilhelmi
772f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist#ifdef G_THREADS_ENABLED
773659fd4113b919a9491c5f872d11a445b6ea48765Sebastian Wilhelmi  if (g_thread_supported ())
774659fd4113b919a9491c5f872d11a445b6ea48765Sebastian Wilhelmi    g_main_context_init_pipe (context);
775659fd4113b919a9491c5f872d11a445b6ea48765Sebastian Wilhelmi  else
776659fd4113b919a9491c5f872d11a445b6ea48765Sebastian Wilhelmi    main_contexts_without_pipe = g_slist_prepend (main_contexts_without_pipe,
777659fd4113b919a9491c5f872d11a445b6ea48765Sebastian Wilhelmi						  context);
778e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor#endif
779e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
780540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  G_LOCK (main_context_list);
781540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  main_context_list = g_slist_append (main_context_list, context);
782540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  G_UNLOCK (main_context_list);
783540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen
784e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  return context;
785beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor}
786beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
787e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor/**
788e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * g_main_context_default:
789e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *
790a52e2986cd4a2147cfc8d41ae23d98907caaf3a0Matthias Clasen * Returns the default main context. This is the main context used
791e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * for main loop functions when a main loop is not explicitly
792e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * specified.
793e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *
794e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * Return value: the default main context.
795e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor **/
796e2fd4e2bd0589b159f87b491095565d16fac2789Owen TaylorGMainContext *
797e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorg_main_context_default (void)
798beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor{
799e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  /* Slow, but safe */
800e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
801b2e318ff3ecc50d72121a4e8561442a6d79a7a84Tim Janik  G_LOCK (main_loop);
802931ea952650b013b834041b91b0c37a748ffd449Owen Taylor
803e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  if (!default_main_context)
8048951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor    default_main_context = g_main_context_new ();
805931ea952650b013b834041b91b0c37a748ffd449Owen Taylor
806b2e318ff3ecc50d72121a4e8561442a6d79a7a84Tim Janik  G_UNLOCK (main_loop);
80708425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik
808e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  return default_main_context;
809beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor}
810beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
811e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor/* Hooks for adding to the main loop */
812e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
813e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor/**
814e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * g_source_new:
815e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * @source_funcs: structure containing functions that implement
816e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *                the sources behavior.
817a52e2986cd4a2147cfc8d41ae23d98907caaf3a0Matthias Clasen * @struct_size: size of the #GSource structure to create.
818e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *
819a52e2986cd4a2147cfc8d41ae23d98907caaf3a0Matthias Clasen * Creates a new #GSource structure. The size is specified to
820a52e2986cd4a2147cfc8d41ae23d98907caaf3a0Matthias Clasen * allow creating structures derived from #GSource that contain
821e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * additional data. The size passed in must be at least
822a52e2986cd4a2147cfc8d41ae23d98907caaf3a0Matthias Clasen * <literal>sizeof (GSource)</literal>.
823e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *
824e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * The source will not initially be associated with any #GMainContext
8255e45a337b8c9e0d77375711d643ecd22c95d194bMatthias Clasen * and must be added to one with g_source_attach() before it will be
826e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * executed.
827e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *
828a52e2986cd4a2147cfc8d41ae23d98907caaf3a0Matthias Clasen * Return value: the newly-created #GSource.
829e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor **/
830e2fd4e2bd0589b159f87b491095565d16fac2789Owen TaylorGSource *
831e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorg_source_new (GSourceFuncs *source_funcs,
832e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	      guint         struct_size)
833beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor{
834e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  GSource *source;
835e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
836e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  g_return_val_if_fail (source_funcs != NULL, NULL);
837e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  g_return_val_if_fail (struct_size >= sizeof (GSource), NULL);
838931ea952650b013b834041b91b0c37a748ffd449Owen Taylor
839e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  source = (GSource*) g_malloc0 (struct_size);
840e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
841e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  source->source_funcs = source_funcs;
842e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  source->ref_count = 1;
843931ea952650b013b834041b91b0c37a748ffd449Owen Taylor
844e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  source->priority = G_PRIORITY_DEFAULT;
845931ea952650b013b834041b91b0c37a748ffd449Owen Taylor
846e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  source->flags = G_HOOK_FLAG_ACTIVE;
84708425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik
848e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  /* NULL/0 initialization for all other fields */
849e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
850e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  return source;
851beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor}
852beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
853e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor/* Holds context's lock
854e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor */
855e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorstatic void
856e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorg_source_list_add (GSource      *source,
857e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor		   GMainContext *context)
858beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor{
859e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  GSource *tmp_source, *last_source;
860e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
861e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  last_source = NULL;
862e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  tmp_source = context->source_list;
863e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  while (tmp_source && tmp_source->priority <= source->priority)
864e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    {
865e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      last_source = tmp_source;
866e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      tmp_source = tmp_source->next;
867e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    }
868a62ebb0e757c972ef4bc5892d7e3e673c6426015Tim Janik
869e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  source->next = tmp_source;
870e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  if (tmp_source)
871e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    tmp_source->prev = source;
872e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
873e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  source->prev = last_source;
874e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  if (last_source)
875e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    last_source->next = source;
876e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  else
877e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    context->source_list = source;
878beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor}
879beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
880e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor/* Holds context's lock
881e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor */
882e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorstatic void
883e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorg_source_list_remove (GSource      *source,
884e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor		      GMainContext *context)
885beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor{
886e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  if (source->prev)
887e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    source->prev->next = source->next;
888e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  else
889e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    context->source_list = source->next;
890931ea952650b013b834041b91b0c37a748ffd449Owen Taylor
891e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  if (source->next)
892e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    source->next->prev = source->prev;
89308425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik
894e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  source->prev = NULL;
895e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  source->next = NULL;
89608425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik}
89708425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik
898e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor/**
899e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * g_source_attach:
900e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * @source: a #GSource
901e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * @context: a #GMainContext (if %NULL, the default context will be used)
902e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *
903e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * Adds a #GSource to a @context so that it will be executed within
904e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * that context.
905e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *
906e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * Return value: the ID for the source within the #GMainContext
907e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor **/
908e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorguint
909e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorg_source_attach (GSource      *source,
910e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor		 GMainContext *context)
91108425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik{
912e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  guint result = 0;
913e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  GSList *tmp_list;
91408425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik
915e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  g_return_val_if_fail (source->context == NULL, 0);
916e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  g_return_val_if_fail (!SOURCE_DESTROYED (source), 0);
917e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
918e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  if (!context)
919e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    context = g_main_context_default ();
92008425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik
921e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  LOCK_CONTEXT (context);
92208425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik
923e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  source->context = context;
92413852a10d4e2a94320f4c6db09a274de0aba63d7Owen Taylor  result = source->source_id = context->next_id++;
92508425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik
9261084477e032113aefa2aad6d8c0a7360fafaae91Owen Taylor  source->ref_count++;
927e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  g_source_list_add (source, context);
92808425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik
929e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  tmp_list = source->poll_fds;
930e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  while (tmp_list)
931e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    {
932e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      g_main_context_add_poll_unlocked (context, source->priority, tmp_list->data);
933e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      tmp_list = tmp_list->next;
934e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    }
93508425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik
936e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor#ifdef G_THREADS_ENABLED
937e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  /* Now wake up the main loop if it is waiting in the poll() */
9388951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  g_main_context_wakeup_unlocked (context);
939e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor#endif
94008425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik
941e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  UNLOCK_CONTEXT (context);
94208425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik
943e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  return result;
944beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor}
945beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
946e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorstatic void
947e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorg_source_destroy_internal (GSource      *source,
948e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor			   GMainContext *context,
949e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor			   gboolean      have_lock)
950beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor{
951e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  if (!have_lock)
952e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    LOCK_CONTEXT (context);
953e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
954e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  if (!SOURCE_DESTROYED (source))
955e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    {
956cbd74878d1ff8d218e9854fe5b42bfdad3397acaOwen Taylor      GSList *tmp_list;
957e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      gpointer old_cb_data;
958e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      GSourceCallbackFuncs *old_cb_funcs;
959e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
960e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      source->flags &= ~G_HOOK_FLAG_ACTIVE;
961a62ebb0e757c972ef4bc5892d7e3e673c6426015Tim Janik
962e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      old_cb_data = source->callback_data;
963e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      old_cb_funcs = source->callback_funcs;
964f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist
965e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      source->callback_data = NULL;
966e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      source->callback_funcs = NULL;
96748b41a2f5f36507a78ff7f8f1b4d57393ee4ec7eTor Lillqvist
968e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      if (old_cb_funcs)
969e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	{
970e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	  UNLOCK_CONTEXT (context);
971e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	  old_cb_funcs->unref (old_cb_data);
972e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	  LOCK_CONTEXT (context);
973e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	}
9749753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor
9759753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor      if (!SOURCE_BLOCKED (source))
976cbd74878d1ff8d218e9854fe5b42bfdad3397acaOwen Taylor	{
9779753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor	  tmp_list = source->poll_fds;
9789753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor	  while (tmp_list)
9799753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor	    {
9809753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor	      g_main_context_remove_poll_unlocked (context, tmp_list->data);
9819753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor	      tmp_list = tmp_list->next;
9829753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor	    }
983cbd74878d1ff8d218e9854fe5b42bfdad3397acaOwen Taylor	}
9849753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor
985e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      g_source_unref_internal (source, context, TRUE);
986e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    }
987f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist
988e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  if (!have_lock)
989e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    UNLOCK_CONTEXT (context);
990beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor}
991beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
992e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor/**
993e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * g_source_destroy:
994e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * @source: a #GSource
995e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *
996a52e2986cd4a2147cfc8d41ae23d98907caaf3a0Matthias Clasen * Removes a source from its #GMainContext, if any, and mark it as
997e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * destroyed.  The source cannot be subsequently added to another
998e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * context.
999e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor **/
1000e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorvoid
1001e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorg_source_destroy (GSource *source)
1002e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor{
1003e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  GMainContext *context;
1004e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1005e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  g_return_if_fail (source != NULL);
1006e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1007e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  context = source->context;
1008e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1009e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  if (context)
1010e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    g_source_destroy_internal (source, context, FALSE);
1011e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  else
1012e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    source->flags &= ~G_HOOK_FLAG_ACTIVE;
1013e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor}
1014beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
1015e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor/**
1016e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * g_source_get_id:
1017e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * @source: a #GSource
1018e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *
1019a52e2986cd4a2147cfc8d41ae23d98907caaf3a0Matthias Clasen * Returns the numeric ID for a particular source. The ID of a source
1020e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * is unique within a particular main loop context. The reverse
1021e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * mapping from ID to source is done by g_main_context_find_source_by_id().
1022e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *
1023e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * Return value: the ID for the source
1024e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor **/
1025e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorguint
1026e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorg_source_get_id (GSource *source)
1027beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor{
1028e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  guint result;
1029e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1030e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  g_return_val_if_fail (source != NULL, 0);
1031e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  g_return_val_if_fail (source->context != NULL, 0);
1032e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1033e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  LOCK_CONTEXT (source->context);
103413852a10d4e2a94320f4c6db09a274de0aba63d7Owen Taylor  result = source->source_id;
1035e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  UNLOCK_CONTEXT (source->context);
1036e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1037e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  return result;
1038e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor}
1039beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
1040e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor/**
1041e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * g_source_get_context:
1042e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * @source: a #GSource
1043e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *
1044a52e2986cd4a2147cfc8d41ae23d98907caaf3a0Matthias Clasen * Gets the #GMainContext with which the source is associated.
1045e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * Calling this function on a destroyed source is an error.
1046e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *
1047e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * Return value: the #GMainContext with which the source is associated,
1048e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *               or %NULL if the context has not yet been added
1049e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *               to a source.
1050e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor **/
1051e2fd4e2bd0589b159f87b491095565d16fac2789Owen TaylorGMainContext *
1052e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorg_source_get_context (GSource *source)
1053e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor{
1054e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  g_return_val_if_fail (!SOURCE_DESTROYED (source), NULL);
1055beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
1056e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  return source->context;
1057e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor}
1058931ea952650b013b834041b91b0c37a748ffd449Owen Taylor
1059e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor/**
106053be713583cf00b61da8d67348a664e2ec970ddcOwen Taylor * g_source_add_poll:
1061e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * @source:a #GSource
1062e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * @fd: a #GPollFD structure holding information about a file
1063e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *      descriptor to watch.
1064e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *
1065a52e2986cd4a2147cfc8d41ae23d98907caaf3a0Matthias Clasen * Adds a file descriptor to the set of file descriptors polled for
1066e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * this source. This is usually combined with g_source_new() to add an
1067e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * event source. The event source's check function will typically test
1068a52e2986cd4a2147cfc8d41ae23d98907caaf3a0Matthias Clasen * the @revents field in the #GPollFD struct and return %TRUE if events need
1069e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * to be processed.
1070e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor **/
1071e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorvoid
1072e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorg_source_add_poll (GSource *source,
1073e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor		   GPollFD *fd)
1074e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor{
1075e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  GMainContext *context;
1076e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1077e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  g_return_if_fail (source != NULL);
1078e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  g_return_if_fail (fd != NULL);
1079b74e7d2f4780c159f7583bd4eecd07ee222d1d9cTor Lillqvist  g_return_if_fail (!SOURCE_DESTROYED (source));
1080cbd74878d1ff8d218e9854fe5b42bfdad3397acaOwen Taylor
1081e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  context = source->context;
1082931ea952650b013b834041b91b0c37a748ffd449Owen Taylor
1083e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  if (context)
1084e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    LOCK_CONTEXT (context);
1085e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1086e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  source->poll_fds = g_slist_prepend (source->poll_fds, fd);
1087beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
1088e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  if (context)
1089e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    {
10909753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor      if (!SOURCE_BLOCKED (source))
10919753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor	g_main_context_add_poll_unlocked (context, source->priority, fd);
1092e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      UNLOCK_CONTEXT (context);
1093beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor    }
1094beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor}
1095beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
1096e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor/**
109753be713583cf00b61da8d67348a664e2ec970ddcOwen Taylor * g_source_remove_poll:
109853be713583cf00b61da8d67348a664e2ec970ddcOwen Taylor * @source:a #GSource
10995e45a337b8c9e0d77375711d643ecd22c95d194bMatthias Clasen * @fd: a #GPollFD structure previously passed to g_source_add_poll().
110053be713583cf00b61da8d67348a664e2ec970ddcOwen Taylor *
1101a52e2986cd4a2147cfc8d41ae23d98907caaf3a0Matthias Clasen * Removes a file descriptor from the set of file descriptors polled for
110253be713583cf00b61da8d67348a664e2ec970ddcOwen Taylor * this source.
110353be713583cf00b61da8d67348a664e2ec970ddcOwen Taylor **/
110453be713583cf00b61da8d67348a664e2ec970ddcOwen Taylorvoid
110553be713583cf00b61da8d67348a664e2ec970ddcOwen Taylorg_source_remove_poll (GSource *source,
110653be713583cf00b61da8d67348a664e2ec970ddcOwen Taylor		      GPollFD *fd)
110753be713583cf00b61da8d67348a664e2ec970ddcOwen Taylor{
110853be713583cf00b61da8d67348a664e2ec970ddcOwen Taylor  GMainContext *context;
110953be713583cf00b61da8d67348a664e2ec970ddcOwen Taylor
111053be713583cf00b61da8d67348a664e2ec970ddcOwen Taylor  g_return_if_fail (source != NULL);
111153be713583cf00b61da8d67348a664e2ec970ddcOwen Taylor  g_return_if_fail (fd != NULL);
111253be713583cf00b61da8d67348a664e2ec970ddcOwen Taylor  g_return_if_fail (!SOURCE_DESTROYED (source));
111353be713583cf00b61da8d67348a664e2ec970ddcOwen Taylor
111453be713583cf00b61da8d67348a664e2ec970ddcOwen Taylor  context = source->context;
111553be713583cf00b61da8d67348a664e2ec970ddcOwen Taylor
111653be713583cf00b61da8d67348a664e2ec970ddcOwen Taylor  if (context)
111753be713583cf00b61da8d67348a664e2ec970ddcOwen Taylor    LOCK_CONTEXT (context);
111853be713583cf00b61da8d67348a664e2ec970ddcOwen Taylor
111953be713583cf00b61da8d67348a664e2ec970ddcOwen Taylor  source->poll_fds = g_slist_remove (source->poll_fds, fd);
112053be713583cf00b61da8d67348a664e2ec970ddcOwen Taylor
112153be713583cf00b61da8d67348a664e2ec970ddcOwen Taylor  if (context)
112253be713583cf00b61da8d67348a664e2ec970ddcOwen Taylor    {
11239753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor      if (!SOURCE_BLOCKED (source))
11249753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor	g_main_context_remove_poll_unlocked (context, fd);
112553be713583cf00b61da8d67348a664e2ec970ddcOwen Taylor      UNLOCK_CONTEXT (context);
112653be713583cf00b61da8d67348a664e2ec970ddcOwen Taylor    }
112753be713583cf00b61da8d67348a664e2ec970ddcOwen Taylor}
112853be713583cf00b61da8d67348a664e2ec970ddcOwen Taylor
112953be713583cf00b61da8d67348a664e2ec970ddcOwen Taylor/**
1130e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * g_source_set_callback_indirect:
1131e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * @source: the source
1132e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * @callback_data: pointer to callback data "object"
1133a52e2986cd4a2147cfc8d41ae23d98907caaf3a0Matthias Clasen * @callback_funcs: functions for reference counting @callback_data
1134e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *                  and getting the callback and data
1135e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *
1136a52e2986cd4a2147cfc8d41ae23d98907caaf3a0Matthias Clasen * Sets the callback function storing the data as a refcounted callback
11375e45a337b8c9e0d77375711d643ecd22c95d194bMatthias Clasen * "object". This is used internally. Note that calling
11385e45a337b8c9e0d77375711d643ecd22c95d194bMatthias Clasen * g_source_set_callback_indirect() assumes
1139e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * an initial reference count on @callback_data, and thus
1140e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * @callback_funcs->unref will eventually be called once more
1141e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * than @callback_funcs->ref.
1142e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor **/
1143e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorvoid
1144e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorg_source_set_callback_indirect (GSource              *source,
1145e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor				gpointer              callback_data,
1146e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor				GSourceCallbackFuncs *callback_funcs)
1147beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor{
1148e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  GMainContext *context;
1149e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  gpointer old_cb_data;
1150e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  GSourceCallbackFuncs *old_cb_funcs;
1151e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1152e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  g_return_if_fail (source != NULL);
1153e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  g_return_if_fail (callback_funcs != NULL || callback_data == NULL);
1154beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
1155e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  context = source->context;
1156beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
1157e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  if (context)
1158e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    LOCK_CONTEXT (context);
1159931ea952650b013b834041b91b0c37a748ffd449Owen Taylor
1160e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  old_cb_data = source->callback_data;
1161e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  old_cb_funcs = source->callback_funcs;
116287c7aeb93bd654776f59805a342ad913031034f3Tim Janik
1163e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  source->callback_data = callback_data;
1164e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  source->callback_funcs = callback_funcs;
1165beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
1166e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  if (context)
1167e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    UNLOCK_CONTEXT (context);
1168e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1169e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  if (old_cb_funcs)
1170e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    old_cb_funcs->unref (old_cb_data);
1171e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor}
11728be41eae4d0077069ecf77a8904b5f624d5ea5ffTim Janik
1173e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorstatic void
1174e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorg_source_callback_ref (gpointer cb_data)
1175e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor{
1176e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  GSourceCallback *callback = cb_data;
1177beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
1178e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  callback->ref_count++;
1179e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor}
1180beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
1181e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1182e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorstatic void
1183e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorg_source_callback_unref (gpointer cb_data)
1184e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor{
1185e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  GSourceCallback *callback = cb_data;
1186e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1187e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  callback->ref_count--;
1188e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  if (callback->ref_count == 0)
1189beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor    {
1190e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      if (callback->notify)
1191e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	callback->notify (callback->data);
11926d145180181075ac9aae1b46af3cddc6e90d4ed2callback);      g_free (callback);
1193e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    }
1194e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor}
1195beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
1196e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorstatic void
1197e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorg_source_callback_get (gpointer     cb_data,
1198b4c3107c7a1dc5dd9e8050ed06f24d6be408e840Owen Taylor		       GSource     *source,
1199e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor		       GSourceFunc *func,
1200e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor		       gpointer    *data)
1201e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor{
1202e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  GSourceCallback *callback = cb_data;
1203beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
1204e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  *func = callback->func;
1205e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  *data = callback->data;
1206e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor}
1207f26256fe182bc1249d3058d9f18402d0ac26974cOwen Taylor
1208e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorstatic GSourceCallbackFuncs g_source_callback_funcs = {
1209e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  g_source_callback_ref,
1210e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  g_source_callback_unref,
1211e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  g_source_callback_get,
1212e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor};
1213f26256fe182bc1249d3058d9f18402d0ac26974cOwen Taylor
1214e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor/**
1215e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * g_source_set_callback:
1216e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * @source: the source
1217e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * @func: a callback function
1218e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * @data: the data to pass to callback function
1219e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * @notify: a function to call when @data is no longer in use, or %NULL.
1220e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *
12214acacec101e4fb1456bcdf7f0b503f8e5d809cd1Soeren Sandmann * Sets the callback function for a source. The callback for a source is
12224acacec101e4fb1456bcdf7f0b503f8e5d809cd1Soeren Sandmann * called from the source's dispatch function.
12234acacec101e4fb1456bcdf7f0b503f8e5d809cd1Soeren Sandmann *
12244acacec101e4fb1456bcdf7f0b503f8e5d809cd1Soeren Sandmann * The exact type of @func depends on the type of source; ie. you
12254acacec101e4fb1456bcdf7f0b503f8e5d809cd1Soeren Sandmann * should not count on @func being called with @data as its first
12264acacec101e4fb1456bcdf7f0b503f8e5d809cd1Soeren Sandmann * parameter.
12274acacec101e4fb1456bcdf7f0b503f8e5d809cd1Soeren Sandmann *
12284acacec101e4fb1456bcdf7f0b503f8e5d809cd1Soeren Sandmann * Typically, you won't use this function. Instead use functions specific
12294acacec101e4fb1456bcdf7f0b503f8e5d809cd1Soeren Sandmann * to the type of source you are using.
1230e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor **/
1231e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorvoid
1232e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorg_source_set_callback (GSource        *source,
1233e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor		       GSourceFunc     func,
1234e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor		       gpointer        data,
1235e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor		       GDestroyNotify  notify)
1236e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor{
1237e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  GSourceCallback *new_callback;
1238f26256fe182bc1249d3058d9f18402d0ac26974cOwen Taylor
1239e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  g_return_if_fail (source != NULL);
12408be41eae4d0077069ecf77a8904b5f624d5ea5ffTim Janik
1241e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  new_callback = g_new (GSourceCallback, 1);
1242e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1243e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  new_callback->ref_count = 1;
1244e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  new_callback->func = func;
1245e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  new_callback->data = data;
1246e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  new_callback->notify = notify;
1247e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1248e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  g_source_set_callback_indirect (source, new_callback, &g_source_callback_funcs);
1249e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor}
1250e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1251e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor/**
1252e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * g_source_set_priority:
1253e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * @source: a #GSource
1254a52e2986cd4a2147cfc8d41ae23d98907caaf3a0Matthias Clasen * @priority: the new priority.
1255720e9f5e66a15b7df89aeaa6a9850bfec68e112eMatthias Clasen *
1256720e9f5e66a15b7df89aeaa6a9850bfec68e112eMatthias Clasen * Sets the priority of a source. While the main loop is being
1257e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * run, a source will be dispatched if it is ready to be dispatched and no sources
1258e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * at a higher (numerically smaller) priority are ready to be dispatched.
1259e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor **/
1260e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorvoid
1261e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorg_source_set_priority (GSource  *source,
1262e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor		       gint      priority)
1263e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor{
1264e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  GSList *tmp_list;
1265e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  GMainContext *context;
1266e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1267e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  g_return_if_fail (source != NULL);
1268e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1269e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  context = source->context;
1270e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1271e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  if (context)
1272e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    LOCK_CONTEXT (context);
1273e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1274e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  source->priority = priority;
1275e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
12769753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor  if (context)
12779753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor    {
12789753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor      /* Remove the source from the context's source and then
12799753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor       * add it back so it is sorted in the correct plcae
12809753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor       */
12819753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor      g_source_list_remove (source, source->context);
12829753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor      g_source_list_add (source, source->context);
1283e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
12849753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor      if (!SOURCE_BLOCKED (source))
12859753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor	{
12869753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor	  tmp_list = source->poll_fds;
12879753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor	  while (tmp_list)
12889753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor	    {
12899753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor	      g_main_context_remove_poll_unlocked (context, tmp_list->data);
12909753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor	      g_main_context_add_poll_unlocked (context, priority, tmp_list->data);
12919753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor
1292e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	      tmp_list = tmp_list->next;
1293e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	    }
1294e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	}
1295e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1296e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      UNLOCK_CONTEXT (source->context);
1297e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    }
1298e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor}
1299e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1300e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor/**
1301e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * g_source_get_priority:
1302a52e2986cd4a2147cfc8d41ae23d98907caaf3a0Matthias Clasen * @source: a #GSource
1303e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *
1304e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * Gets the priority of a source.
1305e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *
1306e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * Return value: the priority of the source
1307e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor **/
1308e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorgint
1309e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorg_source_get_priority (GSource *source)
1310e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor{
1311e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  g_return_val_if_fail (source != NULL, 0);
1312e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1313e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  return source->priority;
1314e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor}
1315e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1316e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor/**
1317e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * g_source_set_can_recurse:
1318e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * @source: a #GSource
1319e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * @can_recurse: whether recursion is allowed for this source
1320e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *
1321e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * Sets whether a source can be called recursively. If @can_recurse is
1322e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * %TRUE, then while the source is being dispatched then this source
1323e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * will be processed normally. Otherwise, all processing of this
1324e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * source is blocked until the dispatch function returns.
1325e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor **/
1326e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorvoid
1327e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorg_source_set_can_recurse (GSource  *source,
1328e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor			  gboolean  can_recurse)
1329e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor{
1330e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  GMainContext *context;
1331e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1332e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  g_return_if_fail (source != NULL);
1333e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1334e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  context = source->context;
1335e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1336e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  if (context)
1337e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    LOCK_CONTEXT (context);
1338e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1339e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  if (can_recurse)
1340e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    source->flags |= G_SOURCE_CAN_RECURSE;
1341e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  else
1342e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    source->flags &= ~G_SOURCE_CAN_RECURSE;
1343e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1344e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  if (context)
1345e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    UNLOCK_CONTEXT (context);
1346e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor}
1347e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1348e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor/**
1349e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * g_source_get_can_recurse:
1350e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * @source: a #GSource
1351a52e2986cd4a2147cfc8d41ae23d98907caaf3a0Matthias Clasen *
1352e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * Checks whether a source is allowed to be called recursively.
1353e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * see g_source_set_can_recurse().
1354e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *
1355e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * Return value: whether recursion is allowed.
1356e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor **/
1357e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorgboolean
1358e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorg_source_get_can_recurse (GSource  *source)
1359e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor{
1360e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  g_return_val_if_fail (source != NULL, FALSE);
1361e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1362e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  return (source->flags & G_SOURCE_CAN_RECURSE) != 0;
1363e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor}
1364e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1365e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor/**
1366e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * g_source_ref:
1367e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * @source: a #GSource
1368e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *
1369e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * Increases the reference count on a source by one.
1370e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *
1371e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * Return value: @source
1372e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor **/
1373e2fd4e2bd0589b159f87b491095565d16fac2789Owen TaylorGSource *
1374e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorg_source_ref (GSource *source)
1375e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor{
1376e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  GMainContext *context;
1377e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1378e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  g_return_val_if_fail (source != NULL, NULL);
1379e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1380e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  context = source->context;
1381e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1382e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  if (context)
1383e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    LOCK_CONTEXT (context);
1384e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1385e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  source->ref_count++;
1386e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1387e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  if (context)
1388e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    UNLOCK_CONTEXT (context);
1389e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1390e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  return source;
1391e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor}
1392e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1393e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor/* g_source_unref() but possible to call within context lock
1394e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor */
1395e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorstatic void
1396e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorg_source_unref_internal (GSource      *source,
1397e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor			 GMainContext *context,
139807267bf096978a528a02bfa9d12aec2d6f5de541Owen Taylor			 gboolean      have_lock)
139907267bf096978a528a02bfa9d12aec2d6f5de541Owen Taylor{
1400e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  gpointer old_cb_data = NULL;
1401e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  GSourceCallbackFuncs *old_cb_funcs = NULL;
1402e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1403e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  g_return_if_fail (source != NULL);
1404e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1405e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  if (!have_lock && context)
1406e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    LOCK_CONTEXT (context);
1407e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1408e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  source->ref_count--;
140907267bf096978a528a02bfa9d12aec2d6f5de541Owen Taylor  if (source->ref_count == 0)
141007267bf096978a528a02bfa9d12aec2d6f5de541Owen Taylor    {
141107267bf096978a528a02bfa9d12aec2d6f5de541Owen Taylor      old_cb_data = source->callback_data;
141207267bf096978a528a02bfa9d12aec2d6f5de541Owen Taylor      old_cb_funcs = source->callback_funcs;
141307267bf096978a528a02bfa9d12aec2d6f5de541Owen Taylor
141407267bf096978a528a02bfa9d12aec2d6f5de541Owen Taylor      source->callback_data = NULL;
1415e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      source->callback_funcs = NULL;
1416e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1417e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      if (context && !SOURCE_DESTROYED (source))
1418e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	{
1419e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	  g_warning (G_STRLOC ": ref_count == 0, but source is still attached to a context!");
1420cbd74878d1ff8d218e9854fe5b42bfdad3397acaOwen Taylor	  source->ref_count++;
1421cbd74878d1ff8d218e9854fe5b42bfdad3397acaOwen Taylor	}
1422cbd74878d1ff8d218e9854fe5b42bfdad3397acaOwen Taylor      else if (context)
1423b37e7bbb53afd0f8d3386065aff0d74195737fd1Owen Taylor	g_source_list_remove (source, context);
1424b37e7bbb53afd0f8d3386065aff0d74195737fd1Owen Taylor
1425cbd74878d1ff8d218e9854fe5b42bfdad3397acaOwen Taylor      if (source->source_funcs->finalize)
1426cbd74878d1ff8d218e9854fe5b42bfdad3397acaOwen Taylor	source->source_funcs->finalize (source);
1427cbd74878d1ff8d218e9854fe5b42bfdad3397acaOwen Taylor
1428cbd74878d1ff8d218e9854fe5b42bfdad3397acaOwen Taylor      g_slist_free (source->poll_fds);
1429e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      source->poll_fds = NULL;
1430e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      g_free (source);
1431e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    }
1432e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1433e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  if (!have_lock && context)
143407267bf096978a528a02bfa9d12aec2d6f5de541Owen Taylor    UNLOCK_CONTEXT (context);
1435e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1436e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  if (old_cb_funcs)
1437e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    {
1438e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      if (have_lock)
143907267bf096978a528a02bfa9d12aec2d6f5de541Owen Taylor	UNLOCK_CONTEXT (context);
1440e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1441e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      old_cb_funcs->unref (old_cb_data);
1442e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1443e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      if (have_lock)
1444e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	LOCK_CONTEXT (context);
1445e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    }
1446e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor}
1447e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1448e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor/**
1449e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * g_source_unref:
1450e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * @source: a #GSource
1451e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *
1452e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * Decreases the reference count of a source by one. If the
1453e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * resulting reference count is zero the source and associated
1454e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * memory will be destroyed.
1455e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor **/
1456e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorvoid
1457e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorg_source_unref (GSource *source)
1458e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor{
1459e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  g_return_if_fail (source != NULL);
1460e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1461e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  g_source_unref_internal (source, source->context, FALSE);
1462e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor}
1463e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1464e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor/**
146513852a10d4e2a94320f4c6db09a274de0aba63d7Owen Taylor * g_main_context_find_source_by_id:
1466e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * @context: a #GMainContext (if %NULL, the default context will be used)
1467e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * @source_id: the source ID, as returned by g_source_get_id()
1468e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *
1469e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * Finds a #GSource given a pair of context and ID
1470e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *
1471e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * Return value: the #GSource if found, otherwise, %NULL
1472e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor **/
147313852a10d4e2a94320f4c6db09a274de0aba63d7Owen TaylorGSource *
1474e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorg_main_context_find_source_by_id (GMainContext *context,
1475e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor				  guint         source_id)
1476e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor{
1477ea9a7199a17a8f391cb3a4b0c40606c3d628e015Matthias Clasen  GSource *source;
1478e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1479e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  g_return_val_if_fail (source_id > 0, NULL);
1480e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1481e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  if (context == NULL)
1482e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    context = g_main_context_default ();
1483e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1484e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  LOCK_CONTEXT (context);
1485e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1486e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  source = context->source_list;
1487e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  while (source)
148813852a10d4e2a94320f4c6db09a274de0aba63d7Owen Taylor    {
1489e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      if (!SOURCE_DESTROYED (source) &&
1490e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	  source->source_id == source_id)
1491e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	break;
1492e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      source = source->next;
1493e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    }
1494e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1495e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  UNLOCK_CONTEXT (context);
1496e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1497e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  return source;
1498e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor}
1499e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1500e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor/**
1501e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * g_main_context_find_source_by_funcs_user_data:
1502e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * @context: a #GMainContext (if %NULL, the default context will be used).
1503e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * @funcs: the @source_funcs passed to g_source_new().
1504e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * @user_data: the user data from the callback.
1505e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *
1506e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * Finds a source with the given source functions and user data.  If
1507e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * multiple sources exist with the same source function and user data,
1508e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * the first one found will be returned.
1509e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *
1510e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * Return value: the source, if one was found, otherwise %NULL
1511e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor **/
1512e2fd4e2bd0589b159f87b491095565d16fac2789Owen TaylorGSource *
1513e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorg_main_context_find_source_by_funcs_user_data (GMainContext *context,
1514e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor					       GSourceFuncs *funcs,
1515e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor					       gpointer      user_data)
1516e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor{
1517ea9a7199a17a8f391cb3a4b0c40606c3d628e015Matthias Clasen  GSource *source;
1518e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1519e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  g_return_val_if_fail (funcs != NULL, NULL);
1520e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1521e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  if (context == NULL)
1522e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    context = g_main_context_default ();
1523e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1524e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  LOCK_CONTEXT (context);
1525e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1526e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  source = context->source_list;
1527e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  while (source)
1528e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    {
1529ffe592544fbc7527f489bc13e91bebccf6ceb4f7Owen Taylor      if (!SOURCE_DESTROYED (source) &&
1530ffe592544fbc7527f489bc13e91bebccf6ceb4f7Owen Taylor	  source->source_funcs == funcs &&
1531ffe592544fbc7527f489bc13e91bebccf6ceb4f7Owen Taylor	  source->callback_funcs)
1532ffe592544fbc7527f489bc13e91bebccf6ceb4f7Owen Taylor	{
1533ffe592544fbc7527f489bc13e91bebccf6ceb4f7Owen Taylor	  GSourceFunc callback;
1534ffe592544fbc7527f489bc13e91bebccf6ceb4f7Owen Taylor	  gpointer callback_data;
1535ffe592544fbc7527f489bc13e91bebccf6ceb4f7Owen Taylor
1536ffe592544fbc7527f489bc13e91bebccf6ceb4f7Owen Taylor	  source->callback_funcs->get (source->callback_data, source, &callback, &callback_data);
1537ffe592544fbc7527f489bc13e91bebccf6ceb4f7Owen Taylor
1538ffe592544fbc7527f489bc13e91bebccf6ceb4f7Owen Taylor	  if (callback_data == user_data)
1539e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	    break;
1540e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	}
1541e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      source = source->next;
1542e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    }
1543e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1544e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  UNLOCK_CONTEXT (context);
1545e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1546e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  return source;
1547e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor}
1548e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1549e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor/**
1550e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * g_main_context_find_source_by_user_data:
1551e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * @context: a #GMainContext
1552e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * @user_data: the user_data for the callback.
1553e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *
1554e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * Finds a source with the given user data for the callback.  If
1555e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * multiple sources exist with the same user data, the first
1556e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * one found will be returned.
1557e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *
1558e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * Return value: the source, if one was found, otherwise %NULL
1559e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor **/
1560e2fd4e2bd0589b159f87b491095565d16fac2789Owen TaylorGSource *
1561e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorg_main_context_find_source_by_user_data (GMainContext *context,
1562e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor					 gpointer      user_data)
1563e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor{
1564e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  GSource *source;
1565e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1566e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  if (context == NULL)
1567e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    context = g_main_context_default ();
1568e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1569e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  LOCK_CONTEXT (context);
1570e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1571e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  source = context->source_list;
1572e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  while (source)
1573ffe592544fbc7527f489bc13e91bebccf6ceb4f7Owen Taylor    {
1574ffe592544fbc7527f489bc13e91bebccf6ceb4f7Owen Taylor      if (!SOURCE_DESTROYED (source) &&
1575ffe592544fbc7527f489bc13e91bebccf6ceb4f7Owen Taylor	  source->callback_funcs)
1576ffe592544fbc7527f489bc13e91bebccf6ceb4f7Owen Taylor	{
1577ffe592544fbc7527f489bc13e91bebccf6ceb4f7Owen Taylor	  GSourceFunc callback;
1578ffe592544fbc7527f489bc13e91bebccf6ceb4f7Owen Taylor	  gpointer callback_data = NULL;
1579ffe592544fbc7527f489bc13e91bebccf6ceb4f7Owen Taylor
1580ffe592544fbc7527f489bc13e91bebccf6ceb4f7Owen Taylor	  source->callback_funcs->get (source->callback_data, source, &callback, &callback_data);
1581ffe592544fbc7527f489bc13e91bebccf6ceb4f7Owen Taylor
1582ffe592544fbc7527f489bc13e91bebccf6ceb4f7Owen Taylor	  if (callback_data == user_data)
1583e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	    break;
1584e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	}
1585e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      source = source->next;
1586e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    }
1587e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1588e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  UNLOCK_CONTEXT (context);
1589e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1590e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  return source;
1591e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor}
1592e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1593e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor/**
1594e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * g_source_remove:
1595540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen * @tag: the id of the source to remove.
1596540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen *
1597540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen * Removes the source with the given id from the default main context. The id of
1598540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen * a #GSource is given by g_source_get_id(), or will be returned by the
1599540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen * functions g_source_attach(), g_idle_add(), g_idle_add_full(),
1600e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * g_timeout_add(), g_timeout_add_full(), g_child_watch_add(),
1601e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * g_child_watch_add_full(), g_io_add_watch(), and g_io_add_watch_full().
1602e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *
1603e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * See also g_source_destroy().
1604e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *
1605e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * Return value: %TRUE if the source was found and removed.
1606e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor **/
1607e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorgboolean
1608e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorg_source_remove (guint tag)
1609e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor{
1610e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  GSource *source;
1611e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1612e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  g_return_val_if_fail (tag > 0, FALSE);
1613e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1614e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  source = g_main_context_find_source_by_id (NULL, tag);
1615e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  if (source)
1616e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    g_source_destroy (source);
1617e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1618e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  return source != NULL;
1619e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor}
1620e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1621e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor/**
1622e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * g_source_remove_by_user_data:
1623e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * @user_data: the user_data for the callback.
1624e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *
1625e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * Removes a source from the default main loop context given the user
1626e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * data for the callback. If multiple sources exist with the same user
1627e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * data, only one will be destroyed.
1628e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *
1629e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * Return value: %TRUE if a source was found and removed.
1630e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor **/
1631e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorgboolean
1632e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorg_source_remove_by_user_data (gpointer user_data)
1633e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor{
1634e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  GSource *source;
1635e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1636e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  source = g_main_context_find_source_by_user_data (NULL, user_data);
1637e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  if (source)
1638e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    {
1639e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      g_source_destroy (source);
1640e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      return TRUE;
1641e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    }
1642e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  else
1643e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    return FALSE;
1644e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor}
1645e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1646e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor/**
1647e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * g_source_remove_by_funcs_user_data:
1648e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * @funcs: The @source_funcs passed to g_source_new()
1649e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * @user_data: the user data for the callback
1650e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *
1651e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * Removes a source from the default main loop context given the
1652e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * source functions and user data. If multiple sources exist with the
1653e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * same source functions and user data, only one will be destroyed.
1654e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *
1655e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * Return value: %TRUE if a source was found and removed.
1656e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor **/
1657e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorgboolean
1658e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorg_source_remove_by_funcs_user_data (GSourceFuncs *funcs,
1659e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor				    gpointer      user_data)
1660e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor{
1661e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  GSource *source;
1662e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1663e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  g_return_val_if_fail (funcs != NULL, FALSE);
1664e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1665e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  source = g_main_context_find_source_by_funcs_user_data (NULL, funcs, user_data);
1666e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  if (source)
1667e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    {
1668e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      g_source_destroy (source);
1669e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      return TRUE;
1670e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    }
1671e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  else
1672e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    return FALSE;
1673e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor}
1674e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1675e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor/**
1676e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * g_get_current_time:
1677a412fb16541620ed72da86daac0774afe4703d9dMatthias Clasen * @result: #GTimeVal structure in which to store current time.
1678e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *
1679e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * Equivalent to the UNIX gettimeofday() function, but portable.
1680e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor **/
1681e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorvoid
1682e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorg_get_current_time (GTimeVal *result)
1683e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor{
1684e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor#ifndef G_OS_WIN32
1685e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  struct timeval r;
1686e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1687e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  g_return_if_fail (result != NULL);
1688e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1689e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  /*this is required on alpha, there the timeval structs are int's
1690e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    not longs and a cast only would fail horribly*/
1691e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  gettimeofday (&r, NULL);
1692e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  result->tv_sec = r.tv_sec;
1693e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  result->tv_usec = r.tv_usec;
1694e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor#else
1695e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  /* Avoid calling time() except for the first time.
1696e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor   * GetTickCount() should be pretty fast and low-level?
1697e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor   * I could also use ftime() but it seems unnecessarily overheady.
1698e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor   */
1699e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  static DWORD start_tick = 0;
1700e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  static time_t start_time;
1701e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  DWORD tick;
1702e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1703e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  g_return_if_fail (result != NULL);
1704e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1705e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  if (start_tick == 0)
1706e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    {
1707e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      start_tick = GetTickCount ();
1708e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      time (&start_time);
1709e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    }
1710e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1711e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  tick = GetTickCount ();
1712e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1713e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  result->tv_sec = (tick - start_tick) / 1000 + start_time;
1714e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  result->tv_usec = ((tick - start_tick) % 1000) * 1000;
1715e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor#endif
1716e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor}
1717e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
17180875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor/* Running the main loop */
17190875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor
17200875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylorstatic gint *
17210875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylorget_depth_pointer (void)
17220875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor{
17230875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor  static GStaticPrivate depth_private = G_STATIC_PRIVATE_INIT;
17240875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor  gint *depth_pointer = g_static_private_get (&depth_private);
17250875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor  if (!depth_pointer)
17260875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor    {
17270875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor      depth_pointer = g_new (gint, 1);
17280875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor      *depth_pointer = 0;
17290875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor      g_static_private_set (&depth_private, depth_pointer, g_free);
17300875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor    }
17310875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor
17320875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor  return depth_pointer;
17330875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor}
17340875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor
17350875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor/**
17360875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor * g_main_depth:
17370875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor *
17380875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor * Return value: The main loop recursion level in the current thread
17390875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor *
17400875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor * Returns the depth of the stack of calls to
17410875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor * g_main_context_dispatch() on any #GMainContext in the current thread.
17420875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor *  That is, when called from the toplevel, it gives 0. When
17430875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor * called from within a callback from g_main_context_iteration()
17440875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor * (or g_main_loop_run(), etc.) it returns 1. When called from within
17450875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor * a callback to a recursive call to g_main_context_iterate(),
17460875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor * it returns 2. And so forth.
17470875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor *
17480875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor * This function is useful in a situation like the following:
17490875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor * Imagine an extremely simple "garbage collected" system.
17500875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor *
17510875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor * <example>
17520875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor * static GList *free_list;
17530875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor *
17540875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor * gpointer
17550875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor * allocate_memory (gsize size)
17560875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor * {
17570875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor *   gpointer result = g_malloc (size);
17580875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor *   free_list = g_list_prepend (free_list, result);
17590875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor *   return result;
17600875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor * }
17610875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor *
17620875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor * void
17630875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor * free_allocated_memory (void)
17640875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor * {
17650875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor *   GList *l;
17660875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor *   for (l = free_list; l; l = l->next);
17670875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor *     g_free (l->data);
17680875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor *   g_list_free (free_list);
17690875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor *   free_list = NULL;
17700875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor *  }
17710875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor *
17720875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor * [...]
17730875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor *
17740875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor * while (TRUE);
17750875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor *  {
17760875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor *    g_main_context_iteration (NULL, TRUE);
17770875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor *    free_allocated_memory();
17780875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor *   }
17790875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor * </example>
17800875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor *
17810875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor * This works from an application, however, if you want to do the same
17820875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor * thing from a library, it gets more difficult, since you no longer
17830875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor * control the main loop. You might think you can simply use an idle
1784e1c15eb0d13eecfeea5059cf1f93e18040be4653Owen Taylor * function to make the call to free_allocated_memory(), but that
17850875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor * doesn't work, since the idle function could be called from a
17860875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor * recursive callback. This can be fixed by using g_main_depth()
17870875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor *
17880875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor * <example>
17890875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor * gpointer
17900875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor * allocate_memory (gsize size)
17910875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor * {
1792e1c15eb0d13eecfeea5059cf1f93e18040be4653Owen Taylor *   FreeListBlock *block = g_new (FreeListBlock, 1);\
17930875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor *   block->mem = g_malloc (size);
17940875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor *   block->depth = g_main_depth ();
17950875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor *   free_list = g_list_prepend (free_list, block);
17960875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor *   return block->mem;
17970875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor * }
17980875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor *
17990875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor * void
18000875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor * free_allocated_memory (void)
18010875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor * {
1802e1c15eb0d13eecfeea5059cf1f93e18040be4653Owen Taylor *   GList *l;
18030875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor *
18040875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor *   int depth = g_main_depth ();
18050875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor *   for (l = free_list; l; );
18060875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor *     {
18070f789811beaf59d197d385ea49b40182a330c6cbMatthias Clasen *       GList *next = l->next;
18080875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor *       FreeListBlock *block = l->data;
18090875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor *       if (block->depth > depth)
18100875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor *         {
18110875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor *           g_free (block->mem);
18120875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor *           g_free (block);
18130875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor *           free_list = g_list_delete_link (free_list, l);
18140875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor *         }
18150875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor *
18160875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor *       l = next;
18170875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor *     }
18180875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor *   }
1819e1c15eb0d13eecfeea5059cf1f93e18040be4653Owen Taylor * </example>
18200875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor *
18210875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor * There is a temptation to use g_main_depth() to solve
18220875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor * problems with reentrancy. For instance, while waiting for data
18233e8b3a13f5ff3eaff583d98ca641170ba1422fceOwen Taylor * to be received from the network in response to a menu item,
18243e8b3a13f5ff3eaff583d98ca641170ba1422fceOwen Taylor * the menu item might be selected again. It might seem that
18253e8b3a13f5ff3eaff583d98ca641170ba1422fceOwen Taylor * one could make the menu item's callback return immediately
18263e8b3a13f5ff3eaff583d98ca641170ba1422fceOwen Taylor * and do nothing if g_main_depth() returns a value greater than 1.
18270875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor * However, this should be avoided since the user then sees selecting
18280875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor * the menu item do nothing. Furthermore, you'll find yourself adding
18290875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor * these checks all over your code, since there are doubtless many,
18300875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor * many things that the user could do. Instead, you can use the
18310875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor * following techniques:
18320875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor *
18330875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor * <orderedlist>
18340875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor *  <listitem>
18350875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor *   <para>
18360875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor *     Use gtk_widget_set_sensitive() or modal dialogs to prevent
18370875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor *     the user from interacting with elements while the main
18380875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor *     loop is recursing.
18390875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor *   </para>
18400875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor *  </listitem>
18410875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor *  <listitem>
18420875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor *   <para>
18430875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor *     Avoid main loop recursion in situations where you can't handle
18440875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor *     arbitrary  callbacks. Instead, structure your code so that you
18450875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor *     simply return to the main loop and then get called again when
18460875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor *     there is more work to do.
1847109ebb109a49735cb42c84f6c9ba881c50797011Owen Taylor *   </para>
18480875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor *  </listitem>
18490875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor * </orderedlist>
18500875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor **/
18510875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylorint
18520875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylorg_main_depth (void)
18530875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor{
18540875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor  gint *depth = get_depth_pointer ();
18550875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor  return *depth;
18569753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor}
18579753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor
18589753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor/* Temporarily remove all this source's file descriptors from the
18599753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor * poll(), so that if data comes available for one of the file descriptors
18609753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor * we don't continually spin in the poll()
1861185c1de57776dc6cc2c5447692d68acd58d8a941Matthias Clasen */
18629753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor/* HOLDS: source->context's lock */
18639753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylorstatic void
18649753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylorblock_source (GSource *source)
18659753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor{
18669753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor  GSList *tmp_list;
18679753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor
18689753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor  g_return_if_fail (!SOURCE_BLOCKED (source));
18699753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor
18709753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor  tmp_list = source->poll_fds;
18719753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor  while (tmp_list)
18729753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor    {
18739753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor      g_main_context_remove_poll_unlocked (source->context, tmp_list->data);
18749753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor      tmp_list = tmp_list->next;
18759753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor    }
18769753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor}
1877185c1de57776dc6cc2c5447692d68acd58d8a941Matthias Clasen
18789753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor/* HOLDS: source->context's lock */
18799753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylorstatic void
18809753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylorunblock_source (GSource *source)
18819753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor{
18829753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor  GSList *tmp_list;
18839753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor
18849753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor  g_return_if_fail (!SOURCE_BLOCKED (source)); /* Source already unblocked */
18859753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor  g_return_if_fail (!SOURCE_DESTROYED (source));
18869753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor
18879753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor  tmp_list = source->poll_fds;
18889753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor  while (tmp_list)
18899753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor    {
18909753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor      g_main_context_add_poll_unlocked (source->context, source->priority, tmp_list->data);
18919753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor      tmp_list = tmp_list->next;
18929753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor    }
1893e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor}
1894e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1895e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor/* HOLDS: context's lock */
1896e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorstatic void
18970875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylorg_main_dispatch (GMainContext *context)
1898f5c28ce4ab8e8015a1432060b6cfe547183b2f9eOwen Taylor{
1899e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  gint *depth = get_depth_pointer ();
1900e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  guint i;
1901e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1902e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  for (i = 0; i < context->pending_dispatches->len; i++)
1903e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    {
1904e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      GSource *source = context->pending_dispatches->pdata[i];
1905e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1906e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      context->pending_dispatches->pdata[i] = NULL;
1907e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      g_assert (source);
1908e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1909e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      source->flags &= ~G_SOURCE_READY;
1910e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1911e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      if (!SOURCE_DESTROYED (source))
1912e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	{
1913e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	  gboolean was_in_call;
1914e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	  gpointer user_data = NULL;
1915e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	  GSourceFunc callback = NULL;
1916e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	  GSourceCallbackFuncs *cb_funcs;
1917e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	  gpointer cb_data;
1918e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	  gboolean need_destroy;
1919e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1920e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	  gboolean (*dispatch) (GSource *,
1921e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor				GSourceFunc,
1922e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor				gpointer);
1923e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1924e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	  dispatch = source->source_funcs->dispatch;
1925e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	  cb_funcs = source->callback_funcs;
1926e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	  cb_data = source->callback_data;
1927e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1928e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	  if (cb_funcs)
19299753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor	    cb_funcs->ref (cb_data);
19309753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor
19319753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor	  if ((source->flags & G_SOURCE_CAN_RECURSE) == 0)
1932e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	    block_source (source);
1933e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1934e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	  was_in_call = source->flags & G_HOOK_FLAG_IN_CALL;
1935e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	  source->flags |= G_HOOK_FLAG_IN_CALL;
1936b4c3107c7a1dc5dd9e8050ed06f24d6be408e840Owen Taylor
1937e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	  if (cb_funcs)
1938ffe592544fbc7527f489bc13e91bebccf6ceb4f7Owen Taylor	    cb_funcs->get (cb_data, source, &callback, &user_data);
1939ffe592544fbc7527f489bc13e91bebccf6ceb4f7Owen Taylor
19400875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor	  UNLOCK_CONTEXT (context);
1941e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1942e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	  (*depth)++;
1943e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	  need_destroy = ! dispatch (source,
19440875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor				     callback,
19450875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor				     user_data);
19460875017ad13ba352b488b0116eab1fa1a12d34e5Owen Taylor	  (*depth)--;
1947e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1948e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor 	  LOCK_CONTEXT (context);
1949e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1950e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	  if (cb_funcs)
1951e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	    cb_funcs->unref (cb_data);
1952e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1953e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	 if (!was_in_call)
19549753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor	    source->flags &= ~G_HOOK_FLAG_IN_CALL;
19559753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor
19569753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor	  if ((source->flags & G_SOURCE_CAN_RECURSE) == 0 &&
19579753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor	      !SOURCE_DESTROYED (source))
1958e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	    unblock_source (source);
1959e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1960e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	  /* Note: this depends on the fact that we can't switch
1961e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	   * sources from one main context to another
1962e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	   */
1963e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	  if (need_destroy && !SOURCE_DESTROYED (source))
1964e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	    {
1965e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	      g_assert (source->context == context);
1966e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	      g_source_destroy_internal (source, context, TRUE);
1967e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	    }
1968e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	}
1969e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1970e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      SOURCE_UNREF (source, context);
1971e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    }
1972e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1973e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  g_ptr_array_set_size (context->pending_dispatches, 0);
1974e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor}
1975e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1976e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor/* Holds context's lock */
1977e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorstatic inline GSource *
1978e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylornext_valid_source (GMainContext *context,
1979e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor		   GSource      *source)
1980e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor{
1981e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  GSource *new_source = source ? source->next : context->source_list;
1982e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1983e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  while (new_source)
1984e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    {
1985e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      if (!SOURCE_DESTROYED (new_source))
1986e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	{
1987e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	  new_source->ref_count++;
1988e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	  break;
1989e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	}
1990e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1991e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      new_source = new_source->next;
1992e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    }
1993e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1994e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  if (source)
1995e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    SOURCE_UNREF (source, context);
1996e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
1997e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  return new_source;
19988951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor}
19998951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor
20008951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor/**
20018951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor * g_main_context_acquire:
20028951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor * @context: a #GMainContext
20038951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor *
20048951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor * Tries to become the owner of the specified context.
20058951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor * If some other context is the owner of the context,
20068951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor * returns %FALSE immediately. Ownership is properly
20078951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor * recursive: the owner can require ownership again
20088951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor * and will release ownership when g_main_context_release()
20098951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor * is called as many times as g_main_context_acquire().
20108951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor *
20118951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor * You must be the owner of a context before you
20128951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor * can call g_main_context_prepare(), g_main_context_query(),
20138951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor * g_main_context_check(), g_main_context_dispatch().
20148951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor *
20158951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor * Return value: %TRUE if the operation succeeded, and
20168951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor *   this thread is now the owner of @context.
20178951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor **/
20188951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylorgboolean
20195cdbc63e478a0432f3c5359043b02542de87347fSebastian Wilhelmig_main_context_acquire (GMainContext *context)
20208951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor{
20218951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor#ifdef G_THREADS_ENABLED
20228951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  gboolean result = FALSE;
20238951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  GThread *self = G_THREAD_SELF;
20248951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor
20258951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  if (context == NULL)
20268951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor    context = g_main_context_default ();
20278951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor
20288951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  LOCK_CONTEXT (context);
20291107552617653b80ef9fff77437569e1ac8e2408Sebastian Wilhelmi
20301107552617653b80ef9fff77437569e1ac8e2408Sebastian Wilhelmi  if (!context->owner)
20311107552617653b80ef9fff77437569e1ac8e2408Sebastian Wilhelmi    {
20321107552617653b80ef9fff77437569e1ac8e2408Sebastian Wilhelmi      context->owner = self;
20338951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor      g_assert (context->owner_count == 0);
20348951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor    }
20358951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor
20368951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  if (context->owner == self)
20378951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor    {
20388951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor      context->owner_count++;
20398951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor      result = TRUE;
20408951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor    }
20418951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor
20428951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  UNLOCK_CONTEXT (context);
20435cdbc63e478a0432f3c5359043b02542de87347fSebastian Wilhelmi
20448951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  return result;
20455cdbc63e478a0432f3c5359043b02542de87347fSebastian Wilhelmi#else /* !G_THREADS_ENABLED */
20468951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  return TRUE;
20478951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor#endif /* G_THREADS_ENABLED */
20488951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor}
20498951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor
20508951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor/**
20518951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor * g_main_context_release:
2052a52e2986cd4a2147cfc8d41ae23d98907caaf3a0Matthias Clasen * @context: a #GMainContext
20538951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor *
20548951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor * Releases ownership of a context previously acquired by this thread
20558951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor * with g_main_context_acquire(). If the context was acquired multiple
20568951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor * times, the only release ownership when g_main_context_release()
20578951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor * is called as many times as it was acquired.
20588951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor **/
20598951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylorvoid
20605cdbc63e478a0432f3c5359043b02542de87347fSebastian Wilhelmig_main_context_release (GMainContext *context)
20618951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor{
20628951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor#ifdef G_THREADS_ENABLED
20638951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  if (context == NULL)
20648951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor    context = g_main_context_default ();
20658951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor
20668951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  LOCK_CONTEXT (context);
20678951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor
20688951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  context->owner_count--;
20698951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  if (context->owner_count == 0)
20708951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor    {
20718951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor      context->owner = NULL;
20728951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor
20731107552617653b80ef9fff77437569e1ac8e2408Sebastian Wilhelmi      if (context->waiters)
20741107552617653b80ef9fff77437569e1ac8e2408Sebastian Wilhelmi	{
20751107552617653b80ef9fff77437569e1ac8e2408Sebastian Wilhelmi	  GMainWaiter *waiter = context->waiters->data;
20768951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor	  gboolean loop_internal_waiter =
20778951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor	    (waiter->mutex == g_static_mutex_get_mutex (&context->mutex));
20781107552617653b80ef9fff77437569e1ac8e2408Sebastian Wilhelmi	  context->waiters = g_slist_delete_link (context->waiters,
20791107552617653b80ef9fff77437569e1ac8e2408Sebastian Wilhelmi						  context->waiters);
20801107552617653b80ef9fff77437569e1ac8e2408Sebastian Wilhelmi	  if (!loop_internal_waiter)
20811107552617653b80ef9fff77437569e1ac8e2408Sebastian Wilhelmi	    g_mutex_lock (waiter->mutex);
20821107552617653b80ef9fff77437569e1ac8e2408Sebastian Wilhelmi
20831107552617653b80ef9fff77437569e1ac8e2408Sebastian Wilhelmi	  g_cond_signal (waiter->cond);
20841107552617653b80ef9fff77437569e1ac8e2408Sebastian Wilhelmi
20858951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor	  if (!loop_internal_waiter)
20868951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor	    g_mutex_unlock (waiter->mutex);
20878951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor	}
20881107552617653b80ef9fff77437569e1ac8e2408Sebastian Wilhelmi    }
20895cdbc63e478a0432f3c5359043b02542de87347fSebastian Wilhelmi
20908951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  UNLOCK_CONTEXT (context);
20918951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor#endif /* G_THREADS_ENABLED */
20928951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor}
20938951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor
20948951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor/**
20958951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor * g_main_context_wait:
20968951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor * @context: a #GMainContext
20978951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor * @cond: a condition variable
20988951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor * @mutex: a mutex, currently held
2099a52e2986cd4a2147cfc8d41ae23d98907caaf3a0Matthias Clasen *
2100a52e2986cd4a2147cfc8d41ae23d98907caaf3a0Matthias Clasen * Tries to become the owner of the specified context,
2101a52e2986cd4a2147cfc8d41ae23d98907caaf3a0Matthias Clasen * as with g_main_context_acquire(). But if another thread
21028951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor * is the owner, atomically drop @mutex and wait on @cond until
21038951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor * that owner releases ownership or until @cond is signaled, then
21048951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor * try again (once) to become the owner.
21058951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor *
21068951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor * Return value: %TRUE if the operation succeeded, and
21078951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor *   this thread is now the owner of @context.
21088951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor **/
21098951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylorgboolean
21108951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylorg_main_context_wait (GMainContext *context,
21118951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor		     GCond        *cond,
21125cdbc63e478a0432f3c5359043b02542de87347fSebastian Wilhelmi		     GMutex       *mutex)
21138951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor{
21148951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor#ifdef G_THREADS_ENABLED
21158951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  gboolean result = FALSE;
21168951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  GThread *self = G_THREAD_SELF;
21178951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  gboolean loop_internal_waiter;
21188951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor
21198951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  if (context == NULL)
21208951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor    context = g_main_context_default ();
21218951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor
21228951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  loop_internal_waiter = (mutex == g_static_mutex_get_mutex (&context->mutex));
21238951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor
21248951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  if (!loop_internal_waiter)
21258951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor    LOCK_CONTEXT (context);
21268951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor
21278951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  if (context->owner && context->owner != self)
21288951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor    {
21298951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor      GMainWaiter waiter;
21308951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor
21318951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor      waiter.cond = cond;
21328951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor      waiter.mutex = mutex;
21338951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor
21348951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor      context->waiters = g_slist_append (context->waiters, &waiter);
21358951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor
21368951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor      if (!loop_internal_waiter)
21378951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor	UNLOCK_CONTEXT (context);
21388951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor      g_cond_wait (cond, mutex);
21398951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor      if (!loop_internal_waiter)
21408951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor	LOCK_CONTEXT (context);
21418951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor
21428951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor      context->waiters = g_slist_remove (context->waiters, &waiter);
21438951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor    }
21441107552617653b80ef9fff77437569e1ac8e2408Sebastian Wilhelmi
21451107552617653b80ef9fff77437569e1ac8e2408Sebastian Wilhelmi  if (!context->owner)
21461107552617653b80ef9fff77437569e1ac8e2408Sebastian Wilhelmi    {
21471107552617653b80ef9fff77437569e1ac8e2408Sebastian Wilhelmi      context->owner = self;
21488951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor      g_assert (context->owner_count == 0);
21498951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor    }
21508951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor
21518951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  if (context->owner == self)
21528951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor    {
21538951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor      context->owner_count++;
21548951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor      result = TRUE;
21558951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor    }
21568951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor
21578951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  if (!loop_internal_waiter)
21588951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor    UNLOCK_CONTEXT (context);
21595cdbc63e478a0432f3c5359043b02542de87347fSebastian Wilhelmi
21608951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  return result;
21615cdbc63e478a0432f3c5359043b02542de87347fSebastian Wilhelmi#else /* !G_THREADS_ENABLED */
21628951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  return TRUE;
2163e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor#endif /* G_THREADS_ENABLED */
2164e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor}
2165e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2166e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor/**
2167e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * g_main_context_prepare:
2168e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * @context: a #GMainContext
2169e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * @priority: location to store priority of highest priority
2170e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *            source already ready.
2171e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *
2172e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * Prepares to poll sources within a main loop. The resulting information
2173e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * for polling is determined by calling g_main_context_query ().
2174e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *
2175e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * Return value: %TRUE if some source is ready to be dispatched
2176e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *               prior to polling.
2177e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor **/
2178e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorgboolean
2179e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorg_main_context_prepare (GMainContext *context,
2180c55b9a4f44eb7e01ec5fa93fc63b0f34cceabc37Owen Taylor			gint         *priority)
2181e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor{
2182e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  gint i;
2183e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  gint n_ready = 0;
2184e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  gint current_priority = G_MAXINT;
2185e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  GSource *source;
2186e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2187e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  if (context == NULL)
2188e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    context = g_main_context_default ();
2189e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2190e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  LOCK_CONTEXT (context);
2191e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2192e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  context->time_is_current = FALSE;
2193e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2194e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  if (context->in_check_or_prepare)
2195e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    {
2196e28e398eb03fcfc467524d17fed666d1afc6dc82Tim Janik      g_warning ("g_main_context_prepare() called recursively from within a source's check() or "
2197e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor		 "prepare() member.");
2198e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      UNLOCK_CONTEXT (context);
2199e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      return FALSE;
2200e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    }
2201e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2202e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor#ifdef G_THREADS_ENABLED
2203e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  if (context->poll_waiting)
2204e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    {
2205e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      g_warning("g_main_context_prepare(): main loop already active in another thread");
2206e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      UNLOCK_CONTEXT (context);
2207e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      return FALSE;
2208e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    }
2209dc7d6c24645656ea1fb55d23a107e5e747b841beRaja R Harinath
2210e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  context->poll_waiting = TRUE;
2211e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor#endif /* G_THREADS_ENABLED */
2212e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2213e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor#if 0
2214e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  /* If recursing, finish up current dispatch, before starting over */
2215e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  if (context->pending_dispatches)
2216e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    {
2217e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      if (dispatch)
2218e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	g_main_dispatch (context, &current_time);
2219e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2220e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      UNLOCK_CONTEXT (context);
2221e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      return TRUE;
2222e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    }
2223e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor#endif
2224c55b9a4f44eb7e01ec5fa93fc63b0f34cceabc37Owen Taylor
2225c55b9a4f44eb7e01ec5fa93fc63b0f34cceabc37Owen Taylor  /* If recursing, clear list of pending dispatches */
2226a3d982007e38310b4e2b15147793ae767fcaba59Owen Taylor
2227a3d982007e38310b4e2b15147793ae767fcaba59Owen Taylor  for (i = 0; i < context->pending_dispatches->len; i++)
2228a3d982007e38310b4e2b15147793ae767fcaba59Owen Taylor    {
2229a3d982007e38310b4e2b15147793ae767fcaba59Owen Taylor      if (context->pending_dispatches->pdata[i])
2230e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	SOURCE_UNREF ((GSource *)context->pending_dispatches->pdata[i], context);
2231e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    }
2232e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  g_ptr_array_set_size (context->pending_dispatches, 0);
2233e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2234e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  /* Prepare all sources */
2235e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2236e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  context->timeout = -1;
2237e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2238e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  source = next_valid_source (context, NULL);
2239e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  while (source)
2240e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    {
2241e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      gint source_timeout = -1;
2242e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2243e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      if ((n_ready > 0) && (source->priority > current_priority))
2244e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	{
2245e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	  SOURCE_UNREF (source, context);
22469753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor	  break;
2247e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	}
2248e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      if (SOURCE_BLOCKED (source))
2249e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	goto next;
2250e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2251e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      if (!(source->flags & G_SOURCE_READY))
2252e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	{
2253e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	  gboolean result;
2254e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	  gboolean (*prepare)  (GSource  *source,
2255e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor				gint     *timeout);
2256e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2257e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	  prepare = source->source_funcs->prepare;
2258e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	  context->in_check_or_prepare++;
2259e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	  UNLOCK_CONTEXT (context);
2260e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2261e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	  result = (*prepare) (source, &source_timeout);
2262e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2263e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	  LOCK_CONTEXT (context);
2264e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	  context->in_check_or_prepare--;
2265e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2266e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	  if (result)
2267e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	    source->flags |= G_SOURCE_READY;
2268e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	}
2269e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2270e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      if (source->flags & G_SOURCE_READY)
2271e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	{
2272e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	  n_ready++;
2273e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	  current_priority = source->priority;
2274beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor	  context->timeout = 0;
2275beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor	}
2276beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
2277e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      if (source_timeout >= 0)
2278e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	{
2279beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor	  if (context->timeout < 0)
2280e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	    context->timeout = source_timeout;
2281beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor	  else
2282beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor	    context->timeout = MIN (context->timeout, source_timeout);
2283e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	}
2284e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2285e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    next:
2286e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      source = next_valid_source (context, source);
2287e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    }
2288e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2289e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  UNLOCK_CONTEXT (context);
2290e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2291e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  if (priority)
2292e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    *priority = current_priority;
2293e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2294e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  return (n_ready > 0);
2295e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor}
2296e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2297e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor/**
2298e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * g_main_context_query:
2299d201974f56d7b805f70b5c5703be79e8db73526eSoeren Sandmann * @context: a #GMainContext
2300e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * @max_priority: maximum priority source to check
2301e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * @timeout_: location to store timeout to be used in polling
2302e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * @fds: location to store #GPollFD records that need to be polled.
2303e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * @n_fds: length of @fds.
2304e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *
23058079eb3456914a03618b92b48f75a71b25331acbOwen Taylor * Determines information necessary to poll this main loop.
23068079eb3456914a03618b92b48f75a71b25331acbOwen Taylor *
23078079eb3456914a03618b92b48f75a71b25331acbOwen Taylor * Return value: the number of records actually stored in @fds,
2308e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *   or, if more than @n_fds records need to be stored, the number
2309e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *   of records that need to be stored.
2310e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor **/
2311e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorgint
2312e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorg_main_context_query (GMainContext *context,
2313e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor		      gint          max_priority,
2314e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor		      gint         *timeout,
2315e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor		      GPollFD      *fds,
2316e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor		      gint          n_fds)
2317e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor{
2318e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  gint n_poll;
2319e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  GPollRec *pollrec;
2320e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2321e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  LOCK_CONTEXT (context);
2322e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2323e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  pollrec = context->poll_records;
2324e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  n_poll = 0;
2325e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  while (pollrec && max_priority >= pollrec->priority)
2326e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    {
2327e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      if (pollrec->fd->events)
2328e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	{
2329e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	  if (n_poll < n_fds)
2330e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	    {
2331e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	      fds[n_poll].fd = pollrec->fd->fd;
2332e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	      /* In direct contradiction to the Unix98 spec, IRIX runs into
2333e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	       * difficulty if you pass in POLLERR, POLLHUP or POLLNVAL
2334e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	       * flags in the events field of the pollfd while it should
2335e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	       * just ignoring them. So we mask them out here.
2336e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	       */
2337e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	      fds[n_poll].events = pollrec->fd->events & ~(G_IO_ERR|G_IO_HUP|G_IO_NVAL);
2338e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	      fds[n_poll].revents = 0;
2339e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	    }
2340e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	  n_poll++;
2341e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	}
2342beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
2343beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor      pollrec = pollrec->next;
23449edb08492d09a36caf389f639f45c8c1c8315f10Havoc Pennington    }
2345e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
23469edb08492d09a36caf389f639f45c8c1c8315f10Havoc Pennington#ifdef G_THREADS_ENABLED
23479edb08492d09a36caf389f639f45c8c1c8315f10Havoc Pennington  context->poll_changed = FALSE;
2348e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor#endif
2349e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2350e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  if (timeout)
2351cbfb32bcff83eeb9d792eee824c7d5fa01e1e1f3Matthias Clasen    {
2352e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      *timeout = context->timeout;
2353e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      if (*timeout != 0)
2354e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	context->time_is_current = FALSE;
2355e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    }
2356beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
2357e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  UNLOCK_CONTEXT (context);
2358e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2359beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  return n_poll;
2360e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor}
2361e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2362e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor/**
2363e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * g_main_context_check:
2364e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * @context: a #GMainContext
2365e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * @max_priority: the maximum numerical priority of sources to check
2366e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * @fds: array of #GPollFD's that was passed to the last call to
2367e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *       g_main_context_query()
2368a52e2986cd4a2147cfc8d41ae23d98907caaf3a0Matthias Clasen * @n_fds: return value of g_main_context_query()
2369e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *
2370e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * Passes the results of polling back to the main loop.
2371e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *
2372e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * Return value: %TRUE if some sources are ready to be dispatched.
2373e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor **/
2374e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorgboolean
2375e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorg_main_context_check (GMainContext *context,
2376e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor		      gint          max_priority,
2377e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor		      GPollFD      *fds,
2378e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor		      gint          n_fds)
2379e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor{
2380e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  GSource *source;
2381e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  GPollRec *pollrec;
2382ce4d6765c92bbcd142937ef56f2dc76f47d6c047Tim Janik  gint n_ready = 0;
2383e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  gint i;
2384beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
2385e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  LOCK_CONTEXT (context);
2386e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2387e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  if (context->in_check_or_prepare)
2388e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    {
2389e28e398eb03fcfc467524d17fed666d1afc6dc82Tim Janik      g_warning ("g_main_context_check() called recursively from within a source's check() or "
2390e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor		 "prepare() member.");
2391e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      UNLOCK_CONTEXT (context);
2392beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor      return FALSE;
2393e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    }
2394e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2395beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor#ifdef G_THREADS_ENABLED
2396e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  if (!context->poll_waiting)
2397540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen    {
2398540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen#ifndef G_OS_WIN32
2399e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      gchar a;
2400e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      read (context->wake_up_pipe[0], &a, 1);
2401e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor#endif
2402e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    }
2403beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  else
2404e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    context->poll_waiting = FALSE;
2405e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2406e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  /* If the set of poll file descriptors changed, bail out
2407e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor   * and let the main loop rerun
2408e28e398eb03fcfc467524d17fed666d1afc6dc82Tim Janik   */
2409e28e398eb03fcfc467524d17fed666d1afc6dc82Tim Janik  if (context->poll_changed)
2410e28e398eb03fcfc467524d17fed666d1afc6dc82Tim Janik    {
2411e28e398eb03fcfc467524d17fed666d1afc6dc82Tim Janik      UNLOCK_CONTEXT (context);
24129edb08492d09a36caf389f639f45c8c1c8315f10Havoc Pennington      return 0;
24139edb08492d09a36caf389f639f45c8c1c8315f10Havoc Pennington    }
2414e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor#endif /* G_THREADS_ENABLED */
2415e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2416e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  pollrec = context->poll_records;
2417e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  i = 0;
2418e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  while (i < n_fds)
241900e064d2af719c4a630156cef361de6365342aaeTim Janik    {
2420e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      if (pollrec->fd->events)
2421e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	{
242200e064d2af719c4a630156cef361de6365342aaeTim Janik	  pollrec->fd->revents = fds[i].revents;
2423e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	  i++;
2424e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	}
2425e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      pollrec = pollrec->next;
2426e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    }
2427e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2428e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  source = next_valid_source (context, NULL);
2429e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  while (source)
2430beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor    {
2431e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      if ((n_ready > 0) && (source->priority > max_priority))
2432e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	{
2433beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor	  SOURCE_UNREF (source, context);
24349753964fe6c17b34857a80b4b8144d9810b4ba8aOwen Taylor	  break;
2435e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	}
2436beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor      if (SOURCE_BLOCKED (source))
2437e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	goto next;
2438beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
2439e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      if (!(source->flags & G_SOURCE_READY))
2440e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	{
2441f26256fe182bc1249d3058d9f18402d0ac26974cOwen Taylor	  gboolean result;
2442e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	  gboolean (*check) (GSource  *source);
2443f26256fe182bc1249d3058d9f18402d0ac26974cOwen Taylor
2444e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	  check = source->source_funcs->check;
2445e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2446e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	  context->in_check_or_prepare++;
2447e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	  UNLOCK_CONTEXT (context);
2448e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2449e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	  result = (*check) (source);
2450e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2451e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	  LOCK_CONTEXT (context);
2452e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	  context->in_check_or_prepare--;
2453e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2454f26256fe182bc1249d3058d9f18402d0ac26974cOwen Taylor	  if (result)
2455f26256fe182bc1249d3058d9f18402d0ac26974cOwen Taylor	    source->flags |= G_SOURCE_READY;
2456e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	}
2457f26256fe182bc1249d3058d9f18402d0ac26974cOwen Taylor
2458e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      if (source->flags & G_SOURCE_READY)
2459e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	{
24608be41eae4d0077069ecf77a8904b5f624d5ea5ffTim Janik	  source->ref_count++;
2461e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	  g_ptr_array_add (context->pending_dispatches, source);
2462ad24759fc104d4c3b155c70394179708dd85d8a1Havoc Pennington
2463ad24759fc104d4c3b155c70394179708dd85d8a1Havoc Pennington	  n_ready++;
2464ad24759fc104d4c3b155c70394179708dd85d8a1Havoc Pennington
2465ad24759fc104d4c3b155c70394179708dd85d8a1Havoc Pennington          /* never dispatch sources with less priority than the first
2466ad24759fc104d4c3b155c70394179708dd85d8a1Havoc Pennington           * one we choose to dispatch
2467beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor           */
2468e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor          max_priority = source->priority;
2469e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	}
2470e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2471beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor    next:
2472beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor      source = next_valid_source (context, source);
2473e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    }
2474e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2475e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  UNLOCK_CONTEXT (context);
2476e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2477e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  return n_ready > 0;
2478e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor}
2479e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2480e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor/**
2481e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * g_main_context_dispatch:
2482a52e2986cd4a2147cfc8d41ae23d98907caaf3a0Matthias Clasen * @context: a #GMainContext
2483e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *
2484e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * Dispatches all pending sources.
2485e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor **/
2486e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorvoid
2487e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorg_main_context_dispatch (GMainContext *context)
2488e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor{
2489e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  LOCK_CONTEXT (context);
2490beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
2491e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  if (context->pending_dispatches->len > 0)
2492beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor    {
2493931ea952650b013b834041b91b0c37a748ffd449Owen Taylor      g_main_dispatch (context);
2494e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    }
2495e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2496e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  UNLOCK_CONTEXT (context);
24978951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor}
2498e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2499e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor/* HOLDS context lock */
2500e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorstatic gboolean
25018951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylorg_main_context_iterate (GMainContext *context,
25028951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor			gboolean      block,
2503e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor			gboolean      dispatch,
2504e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor			GThread      *self)
2505e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor{
2506e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  gint max_priority;
25078951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  gint timeout;
25088951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  gboolean some_ready;
2509e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  gint nfds, allocated_nfds;
25108951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  GPollFD *fds = NULL;
2511e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
25128951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  UNLOCK_CONTEXT (context);
25138951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor
2514e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor#ifdef G_THREADS_ENABLED
25158951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  if (!g_main_context_acquire (context))
25168951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor    {
25178951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor      gboolean got_ownership;
2518e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
25198951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor      g_return_val_if_fail (g_thread_supported (), FALSE);
25208951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor
25218951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor      if (!block)
25228951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor	return FALSE;
25238951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor
25248951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor      LOCK_CONTEXT (context);
25258951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor
25268951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor      if (!context->cond)
25278951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor	context->cond = g_cond_new ();
25288951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor
25298951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor      got_ownership = g_main_context_wait (context,
25308951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor					   context->cond,
25318951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor					   g_static_mutex_get_mutex (&context->mutex));
2532e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
25338951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor      if (!got_ownership)
25348951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor	{
2535e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	  UNLOCK_CONTEXT (context);
25368951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor	  return FALSE;
25378951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor	}
25388951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor    }
2539624a3c9689a9538af7df04aab389423edc82b51aDarin Adler  else
25408951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor    LOCK_CONTEXT (context);
25418951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor#endif /* G_THREADS_ENABLED */
25428951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor
25438951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  if (!context->cached_poll_array)
25448951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor    {
25458951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor      context->cached_poll_array_size = context->n_poll_records;
2546e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      context->cached_poll_array = g_new (GPollFD, context->n_poll_records);
25478951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor    }
25488951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor
2549e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  allocated_nfds = context->cached_poll_array_size;
25508951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  fds = context->cached_poll_array;
25518951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor
25523f1a49ea41a20dacbabea33d4dbcbd62c8c4bb2bOwen Taylor  UNLOCK_CONTEXT (context);
25538951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor
25548951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  g_main_context_prepare (context, &max_priority);
25558951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor
25568951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  while ((nfds = g_main_context_query (context, max_priority, &timeout, fds,
25578951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor				       allocated_nfds)) > allocated_nfds)
25588951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor    {
25598951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor      LOCK_CONTEXT (context);
25608951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor      g_free (fds);
25618951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor      context->cached_poll_array_size = allocated_nfds = nfds;
2562e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      context->cached_poll_array = fds = g_new (GPollFD, nfds);
2563e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      UNLOCK_CONTEXT (context);
2564e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    }
2565e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2566e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  if (!block)
25678951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor    timeout = 0;
2568e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
25693f1a49ea41a20dacbabea33d4dbcbd62c8c4bb2bOwen Taylor  g_main_context_poll (context, timeout, max_priority, fds, nfds);
2570e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2571e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  some_ready = g_main_context_check (context, max_priority, fds, nfds);
2572e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
25738951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  if (dispatch)
25748951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor    g_main_context_dispatch (context);
25758951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor
25768951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor#ifdef G_THREADS_ENABLED
25778951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  g_main_context_release (context);
25788951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor#endif /* G_THREADS_ENABLED */
2579e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2580e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  LOCK_CONTEXT (context);
2581beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
2582beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  return some_ready;
2583e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor}
2584e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2585e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor/**
2586e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * g_main_context_pending:
2587a52e2986cd4a2147cfc8d41ae23d98907caaf3a0Matthias Clasen * @context: a #GMainContext (if %NULL, the default context will be used)
2588e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *
2589e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * Checks if any sources have pending events for the given context.
2590e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *
2591beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor * Return value: %TRUE if events are pending.
2592e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor **/
2593beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylorgboolean
25948951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylorg_main_context_pending (GMainContext *context)
25958951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor{
2596e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  gboolean retval;
2597e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
25988951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  if (!context)
25998951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor    context = g_main_context_default();
26008951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor
26018951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  LOCK_CONTEXT (context);
2602e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  retval = g_main_context_iterate (context, FALSE, FALSE, G_THREAD_SELF);
26038951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  UNLOCK_CONTEXT (context);
2604beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
2605beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  return retval;
2606e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor}
2607e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2608e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor/**
2609e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * g_main_context_iteration:
2610e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * @context: a #GMainContext (if %NULL, the default context will be used)
2611a52e2986cd4a2147cfc8d41ae23d98907caaf3a0Matthias Clasen * @may_block: whether the call may block.
2612e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *
2613e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * Runs a single iteration for the given main loop. This involves
2614e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * checking to see if any event sources are ready to be processed,
2615e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * then if no events sources are ready and @may_block is %TRUE, waiting
2616e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * for a source to become ready, then dispatching the highest priority
2617e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * events sources that are ready. Note that even when @may_block is %TRUE,
2618e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * it is still possible for g_main_context_iteration() to return
2619e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * %FALSE, since the the wait may be interrupted for other
2620e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * reasons than an event source becoming ready.
2621e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *
2622beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor * Return value: %TRUE if events were dispatched.
2623e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor **/
2624beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylorgboolean
26258951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylorg_main_context_iteration (GMainContext *context, gboolean may_block)
26268951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor{
2627e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  gboolean retval;
2628e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2629e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  if (!context)
26308951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor    context = g_main_context_default();
26318951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor
26328951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  LOCK_CONTEXT (context);
26338951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  retval = g_main_context_iterate (context, may_block, TRUE, G_THREAD_SELF);
26348951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  UNLOCK_CONTEXT (context);
2635beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
2636beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  return retval;
2637e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor}
2638e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2639e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor/**
2640a52e2986cd4a2147cfc8d41ae23d98907caaf3a0Matthias Clasen * g_main_loop_new:
264109a6f7be5382444d472be2974eeede94ecb1df51Manish Singh * @context: a #GMainContext  (if %NULL, the default context will be used).
2642a52e2986cd4a2147cfc8d41ae23d98907caaf3a0Matthias Clasen * @is_running: set to %TRUE to indicate that the loop is running. This
2643e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * is not very important since calling g_main_loop_run() will set this to
2644a52e2986cd4a2147cfc8d41ae23d98907caaf3a0Matthias Clasen * %TRUE anyway.
2645e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *
2646a52e2986cd4a2147cfc8d41ae23d98907caaf3a0Matthias Clasen * Creates a new #GMainLoop structure.
2647e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *
2648e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * Return value: a new #GMainLoop.
2649e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor **/
2650e2fd4e2bd0589b159f87b491095565d16fac2789Owen TaylorGMainLoop *
2651beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylorg_main_loop_new (GMainContext *context,
26528be41eae4d0077069ecf77a8904b5f624d5ea5ffTim Janik		 gboolean      is_running)
2653e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor{
2654e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  GMainLoop *loop;
2655e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2656e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  if (!context)
26578951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor    context = g_main_context_default();
26588951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor
26598be41eae4d0077069ecf77a8904b5f624d5ea5ffTim Janik  g_main_context_ref (context);
2660e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
26618be41eae4d0077069ecf77a8904b5f624d5ea5ffTim Janik  loop = g_new0 (GMainLoop, 1);
26623ae4c59e3f9a155436970a7d97d64676178a709cOwen Taylor  loop->context = context;
26633ae4c59e3f9a155436970a7d97d64676178a709cOwen Taylor  loop->is_running = is_running != FALSE;
26648be41eae4d0077069ecf77a8904b5f624d5ea5ffTim Janik  loop->ref_count = 1;
2665beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
2666beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  return loop;
2667e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor}
26683ae4c59e3f9a155436970a7d97d64676178a709cOwen Taylor
26693ae4c59e3f9a155436970a7d97d64676178a709cOwen Taylor/**
26703ae4c59e3f9a155436970a7d97d64676178a709cOwen Taylor * g_main_loop_ref:
2671a52e2986cd4a2147cfc8d41ae23d98907caaf3a0Matthias Clasen * @loop: a #GMainLoop
26723ae4c59e3f9a155436970a7d97d64676178a709cOwen Taylor *
26733ae4c59e3f9a155436970a7d97d64676178a709cOwen Taylor * Increases the reference count on a #GMainLoop object by one.
26743ae4c59e3f9a155436970a7d97d64676178a709cOwen Taylor *
26753ae4c59e3f9a155436970a7d97d64676178a709cOwen Taylor * Return value: @loop
26763ae4c59e3f9a155436970a7d97d64676178a709cOwen Taylor **/
26773ae4c59e3f9a155436970a7d97d64676178a709cOwen TaylorGMainLoop *
26783ae4c59e3f9a155436970a7d97d64676178a709cOwen Taylorg_main_loop_ref (GMainLoop *loop)
2679c40b15fc6b37d152d67c2d2ec18d0e635ea70f90Sebastian Wilhelmi{
26803ae4c59e3f9a155436970a7d97d64676178a709cOwen Taylor  g_return_val_if_fail (loop != NULL, NULL);
2681c40b15fc6b37d152d67c2d2ec18d0e635ea70f90Sebastian Wilhelmi  g_return_val_if_fail (g_atomic_int_get (&loop->ref_count) > 0, NULL);
26823ae4c59e3f9a155436970a7d97d64676178a709cOwen Taylor
26833ae4c59e3f9a155436970a7d97d64676178a709cOwen Taylor  g_atomic_int_inc (&loop->ref_count);
26843ae4c59e3f9a155436970a7d97d64676178a709cOwen Taylor
26853ae4c59e3f9a155436970a7d97d64676178a709cOwen Taylor  return loop;
26863ae4c59e3f9a155436970a7d97d64676178a709cOwen Taylor}
26873ae4c59e3f9a155436970a7d97d64676178a709cOwen Taylor
26883ae4c59e3f9a155436970a7d97d64676178a709cOwen Taylor/**
26893ae4c59e3f9a155436970a7d97d64676178a709cOwen Taylor * g_main_loop_unref:
26903ae4c59e3f9a155436970a7d97d64676178a709cOwen Taylor * @loop: a #GMainLoop
26913ae4c59e3f9a155436970a7d97d64676178a709cOwen Taylor *
26923ae4c59e3f9a155436970a7d97d64676178a709cOwen Taylor * Decreases the reference count on a #GMainLoop object by one. If
26933ae4c59e3f9a155436970a7d97d64676178a709cOwen Taylor * the result is zero, free the loop and free all associated memory.
26943ae4c59e3f9a155436970a7d97d64676178a709cOwen Taylor **/
26953ae4c59e3f9a155436970a7d97d64676178a709cOwen Taylorvoid
26963ae4c59e3f9a155436970a7d97d64676178a709cOwen Taylorg_main_loop_unref (GMainLoop *loop)
2697c40b15fc6b37d152d67c2d2ec18d0e635ea70f90Sebastian Wilhelmi{
26983ae4c59e3f9a155436970a7d97d64676178a709cOwen Taylor  g_return_if_fail (loop != NULL);
2699c40b15fc6b37d152d67c2d2ec18d0e635ea70f90Sebastian Wilhelmi  g_return_if_fail (g_atomic_int_get (&loop->ref_count) > 0);
2700c40b15fc6b37d152d67c2d2ec18d0e635ea70f90Sebastian Wilhelmi
2701c40b15fc6b37d152d67c2d2ec18d0e635ea70f90Sebastian Wilhelmi  if (!g_atomic_int_dec_and_test (&loop->ref_count))
2702c40b15fc6b37d152d67c2d2ec18d0e635ea70f90Sebastian Wilhelmi    return;
2703c40b15fc6b37d152d67c2d2ec18d0e635ea70f90Sebastian Wilhelmi
27043ae4c59e3f9a155436970a7d97d64676178a709cOwen Taylor  g_main_context_unref (loop->context);
27053ae4c59e3f9a155436970a7d97d64676178a709cOwen Taylor  g_free (loop);
27063ae4c59e3f9a155436970a7d97d64676178a709cOwen Taylor}
2707e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2708e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor/**
2709e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * g_main_loop_run:
271009a6f7be5382444d472be2974eeede94ecb1df51Manish Singh * @loop: a #GMainLoop
2711e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *
2712e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * Runs a main loop until g_main_loop_quit() is called on the loop.
2713e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * If this is called for the thread of the loop's #GMainContext,
2714e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * it will process events from the loop, otherwise it will
2715beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor * simply wait.
2716e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor **/
2717beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylorvoid
27188951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylorg_main_loop_run (GMainLoop *loop)
27198951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor{
27208be41eae4d0077069ecf77a8904b5f624d5ea5ffTim Janik  GThread *self = G_THREAD_SELF;
2721c40b15fc6b37d152d67c2d2ec18d0e635ea70f90Sebastian Wilhelmi
27228be41eae4d0077069ecf77a8904b5f624d5ea5ffTim Janik  g_return_if_fail (loop != NULL);
2723e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  g_return_if_fail (g_atomic_int_get (&loop->ref_count) > 0);
27248951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor
2725e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor#ifdef G_THREADS_ENABLED
27268951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  if (!g_main_context_acquire (loop->context))
27273ae4c59e3f9a155436970a7d97d64676178a709cOwen Taylor    {
27288951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor      gboolean got_ownership = FALSE;
2729e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2730e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      /* Another thread owns this context */
2731cf67c99825f7da76636451c70b48b077236337afManish Singh      if (!g_thread_supported ())
2732e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	{
2733e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	  g_warning ("g_main_loop_run() was called from second thread but "
2734e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor		     "g_thread_init() was never called.");
2735e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	  return;
27368951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor	}
2737e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2738c40b15fc6b37d152d67c2d2ec18d0e635ea70f90Sebastian Wilhelmi      LOCK_CONTEXT (loop->context);
27398951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor
27408951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor      g_atomic_int_inc (&loop->ref_count);
27418951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor
27428951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor      if (!loop->is_running)
27438951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor	loop->is_running = TRUE;
27448951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor
27458951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor      if (!loop->context->cond)
27465b4af3060f292551e189f458406251319a54501dOwen Taylor	loop->context->cond = g_cond_new ();
27478951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor
27488951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor      while (loop->is_running && !got_ownership)
27498951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor	got_ownership = g_main_context_wait (loop->context,
27508951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor					     loop->context->cond,
27518951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor					     g_static_mutex_get_mutex (&loop->context->mutex));
2752e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
27531107552617653b80ef9fff77437569e1ac8e2408Sebastian Wilhelmi      if (!loop->is_running)
27548951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor	{
27558951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor	  UNLOCK_CONTEXT (loop->context);
27561107552617653b80ef9fff77437569e1ac8e2408Sebastian Wilhelmi	  if (got_ownership)
27578951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor	    g_main_context_release (loop->context);
2758e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	  g_main_loop_unref (loop);
27598951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor	  return;
27608951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor	}
27613ae4c59e3f9a155436970a7d97d64676178a709cOwen Taylor
27628951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor      g_assert (got_ownership);
27638951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor    }
27648951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  else
27653ae4c59e3f9a155436970a7d97d64676178a709cOwen Taylor    LOCK_CONTEXT (loop->context);
27668951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor#endif /* G_THREADS_ENABLED */
27673ae4c59e3f9a155436970a7d97d64676178a709cOwen Taylor
2768cf67c99825f7da76636451c70b48b077236337afManish Singh  if (loop->context->in_check_or_prepare)
276909a6f7be5382444d472be2974eeede94ecb1df51Manish Singh    {
27708951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor      g_warning ("g_main_loop_run(): called recursively from within a source's "
277108425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik		 "check() or prepare() member, iteration not possible.");
27728951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor      return;
2773c40b15fc6b37d152d67c2d2ec18d0e635ea70f90Sebastian Wilhelmi    }
27748951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor
27758951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  g_atomic_int_inc (&loop->ref_count);
27768951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  loop->is_running = TRUE;
27778951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  while (loop->is_running)
277824915b9a10e21b38dceaf3c493d117c79509990dHavoc Pennington    g_main_context_iterate (loop->context, TRUE, TRUE, self);
277924915b9a10e21b38dceaf3c493d117c79509990dHavoc Pennington
27808951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  UNLOCK_CONTEXT (loop->context);
27818951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor
27828951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor#ifdef G_THREADS_ENABLED
27838951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  g_main_context_release (loop->context);
278424915b9a10e21b38dceaf3c493d117c79509990dHavoc Pennington#endif /* G_THREADS_ENABLED */
2785beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
2786beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  g_main_loop_unref (loop);
2787e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor}
2788e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2789e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor/**
2790e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * g_main_loop_quit:
2791e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * @loop: a #GMainLoop
2792e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *
2793e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * Stops a #GMainLoop from running. Any calls to g_main_loop_run()
2794beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor * for the loop will return.
2795e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor **/
2796beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylorvoid
27978be41eae4d0077069ecf77a8904b5f624d5ea5ffTim Janikg_main_loop_quit (GMainLoop *loop)
2798c40b15fc6b37d152d67c2d2ec18d0e635ea70f90Sebastian Wilhelmi{
27998be41eae4d0077069ecf77a8904b5f624d5ea5ffTim Janik  g_return_if_fail (loop != NULL);
28008951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  g_return_if_fail (g_atomic_int_get (&loop->ref_count) > 0);
28018be41eae4d0077069ecf77a8904b5f624d5ea5ffTim Janik
28028951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  LOCK_CONTEXT (loop->context);
2803e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  loop->is_running = FALSE;
28047f7a422ce55725b312030cbe05e8fa4236583483Sebastian Wilhelmi  g_main_context_wakeup_unlocked (loop->context);
28058951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor
28068951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor#ifdef G_THREADS_ENABLED
28077f7a422ce55725b312030cbe05e8fa4236583483Sebastian Wilhelmi  if (loop->context->cond)
28087f7a422ce55725b312030cbe05e8fa4236583483Sebastian Wilhelmi    g_cond_broadcast (loop->context->cond);
2809e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor#endif /* G_THREADS_ENABLED */
2810beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
2811beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  UNLOCK_CONTEXT (loop->context);
2812e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor}
2813e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2814e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor/**
2815e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * g_main_loop_is_running:
281609a6f7be5382444d472be2974eeede94ecb1df51Manish Singh * @loop: a #GMainLoop.
2817e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *
2818e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * Checks to see if the main loop is currently being run via g_main_loop_run().
2819e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *
28208be41eae4d0077069ecf77a8904b5f624d5ea5ffTim Janik * Return value: %TRUE if the mainloop is currently being run.
2821e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor **/
28228be41eae4d0077069ecf77a8904b5f624d5ea5ffTim Janikgboolean
28238be41eae4d0077069ecf77a8904b5f624d5ea5ffTim Janikg_main_loop_is_running (GMainLoop *loop)
2824c40b15fc6b37d152d67c2d2ec18d0e635ea70f90Sebastian Wilhelmi{
28258be41eae4d0077069ecf77a8904b5f624d5ea5ffTim Janik  g_return_val_if_fail (loop != NULL, FALSE);
28268951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  g_return_val_if_fail (g_atomic_int_get (&loop->ref_count) > 0, FALSE);
28278951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor
2828e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  return loop->is_running;
28298951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor}
28308951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor
28318951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor/**
28328951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor * g_main_loop_get_context:
28338951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor * @loop: a #GMainLoop.
28348951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor *
28358951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor * Returns the #GMainContext of @loop.
28368951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor *
28378951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor * Return value: the #GMainContext of @loop
28388951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor **/
28398951f96c50fda95a8cfaf48e8e378136a9268365Owen TaylorGMainContext *
28408951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylorg_main_loop_get_context (GMainLoop *loop)
2841c40b15fc6b37d152d67c2d2ec18d0e635ea70f90Sebastian Wilhelmi{
28428951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  g_return_val_if_fail (loop != NULL, NULL);
28438951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  g_return_val_if_fail (g_atomic_int_get (&loop->ref_count) > 0, NULL);
28448be41eae4d0077069ecf77a8904b5f624d5ea5ffTim Janik
28458be41eae4d0077069ecf77a8904b5f624d5ea5ffTim Janik  return loop->context;
2846e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor}
2847beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
2848e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor/* HOLDS: context's lock */
2849e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorstatic void
2850e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorg_main_context_poll (GMainContext *context,
2851e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor		     gint          timeout,
2852e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor		     gint          priority,
2853beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor		     GPollFD      *fds,
285487c7aeb93bd654776f59805a342ad913031034f3Tim Janik		     gint          n_fds)
285587c7aeb93bd654776f59805a342ad913031034f3Tim Janik{
2856beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor#ifdef  G_MAIN_POLL_DEBUG
2857beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  GTimer *poll_timer;
2858e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  GPollRec *pollrec;
285987c7aeb93bd654776f59805a342ad913031034f3Tim Janik  gint i;
2860e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor#endif
2861931ea952650b013b834041b91b0c37a748ffd449Owen Taylor
2862e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  GPollFunc poll_func;
286387c7aeb93bd654776f59805a342ad913031034f3Tim Janik
286487c7aeb93bd654776f59805a342ad913031034f3Tim Janik  if (n_fds || timeout != 0)
2865e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    {
286687c7aeb93bd654776f59805a342ad913031034f3Tim Janik#ifdef	G_MAIN_POLL_DEBUG
286787c7aeb93bd654776f59805a342ad913031034f3Tim Janik      g_print ("g_main_poll(%d) timeout: %d\n", n_fds, timeout);
2868e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      poll_timer = g_timer_new ();
2869e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor#endif
2870e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2871e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      LOCK_CONTEXT (context);
287287c7aeb93bd654776f59805a342ad913031034f3Tim Janik
2873e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      poll_func = context->poll_func;
2874e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
28751cf610e216072fdb49d170d898bd4b7178ea3d2bTor Lillqvist      UNLOCK_CONTEXT (context);
28761cf610e216072fdb49d170d898bd4b7178ea3d2bTor Lillqvist      if ((*poll_func) (fds, n_fds, timeout) < 0 && errno != EINTR)
28771cf610e216072fdb49d170d898bd4b7178ea3d2bTor Lillqvist	{
28781cf610e216072fdb49d170d898bd4b7178ea3d2bTor Lillqvist#ifndef G_OS_WIN32
28791cf610e216072fdb49d170d898bd4b7178ea3d2bTor Lillqvist	  g_warning ("poll(2) failed due to: %s.",
28801cf610e216072fdb49d170d898bd4b7178ea3d2bTor Lillqvist		     g_strerror (errno));
28811cf610e216072fdb49d170d898bd4b7178ea3d2bTor Lillqvist#else
28821cf610e216072fdb49d170d898bd4b7178ea3d2bTor Lillqvist	  /* If g_poll () returns -1, it has already called g_warning() */
288387c7aeb93bd654776f59805a342ad913031034f3Tim Janik#endif
288487c7aeb93bd654776f59805a342ad913031034f3Tim Janik	}
2885e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2886e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor#ifdef	G_MAIN_POLL_DEBUG
288787c7aeb93bd654776f59805a342ad913031034f3Tim Janik      LOCK_CONTEXT (context);
2888e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
288987c7aeb93bd654776f59805a342ad913031034f3Tim Janik      g_print ("g_main_poll(%d) timeout: %d - elapsed %12.10f seconds",
289087c7aeb93bd654776f59805a342ad913031034f3Tim Janik	       n_fds,
289187c7aeb93bd654776f59805a342ad913031034f3Tim Janik	       timeout,
2892e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	       g_timer_elapsed (poll_timer, NULL));
289387c7aeb93bd654776f59805a342ad913031034f3Tim Janik      g_timer_destroy (poll_timer);
2894e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      pollrec = context->poll_records;
289587c7aeb93bd654776f59805a342ad913031034f3Tim Janik      i = 0;
289687c7aeb93bd654776f59805a342ad913031034f3Tim Janik      while (i < n_fds)
289787c7aeb93bd654776f59805a342ad913031034f3Tim Janik	{
2898e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	  if (pollrec->fd->events)
289987c7aeb93bd654776f59805a342ad913031034f3Tim Janik	    {
2900e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	      if (fds[i].revents)
2901e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor		{
290287c7aeb93bd654776f59805a342ad913031034f3Tim Janik		  g_print (" [%d:", fds[i].fd);
2903e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor		  if (fds[i].revents & G_IO_IN)
290487c7aeb93bd654776f59805a342ad913031034f3Tim Janik		    g_print ("i");
2905e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor		  if (fds[i].revents & G_IO_OUT)
290687c7aeb93bd654776f59805a342ad913031034f3Tim Janik		    g_print ("o");
2907e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor		  if (fds[i].revents & G_IO_PRI)
290887c7aeb93bd654776f59805a342ad913031034f3Tim Janik		    g_print ("p");
2909e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor		  if (fds[i].revents & G_IO_ERR)
291087c7aeb93bd654776f59805a342ad913031034f3Tim Janik		    g_print ("e");
2911e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor		  if (fds[i].revents & G_IO_HUP)
291287c7aeb93bd654776f59805a342ad913031034f3Tim Janik		    g_print ("h");
291387c7aeb93bd654776f59805a342ad913031034f3Tim Janik		  if (fds[i].revents & G_IO_NVAL)
291487c7aeb93bd654776f59805a342ad913031034f3Tim Janik		    g_print ("n");
291587c7aeb93bd654776f59805a342ad913031034f3Tim Janik		  g_print ("]");
291687c7aeb93bd654776f59805a342ad913031034f3Tim Janik		}
291787c7aeb93bd654776f59805a342ad913031034f3Tim Janik	      i++;
291887c7aeb93bd654776f59805a342ad913031034f3Tim Janik	    }
291987c7aeb93bd654776f59805a342ad913031034f3Tim Janik	  pollrec = pollrec->next;
2920e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	}
2921e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      g_print ("\n");
292287c7aeb93bd654776f59805a342ad913031034f3Tim Janik
2923e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      UNLOCK_CONTEXT (context);
2924beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor#endif
2925beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor    } /* if (n_fds || timeout != 0) */
2926e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor}
2927e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2928e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor/**
2929e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * g_main_context_add_poll:
2930e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * @context: a #GMainContext (or %NULL for the default context)
2931e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * @fd: a #GPollFD structure holding information about a file
2932e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *      descriptor to watch.
2933e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * @priority: the priority for this file descriptor which should be
2934e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *      the same as the priority used for g_source_attach() to ensure that the
2935a52e2986cd4a2147cfc8d41ae23d98907caaf3a0Matthias Clasen *      file descriptor is polled whenever the results may be needed.
2936a52e2986cd4a2147cfc8d41ae23d98907caaf3a0Matthias Clasen *
2937e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * Adds a file descriptor to the set of file descriptors polled for
2938e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * this context. This will very seldomly be used directly. Instead
2939e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * a typical event source will use g_source_add_poll() instead.
2940e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor **/
2941e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorvoid
2942e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorg_main_context_add_poll (GMainContext *context,
2943beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor			 GPollFD      *fd,
2944e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor			 gint          priority)
2945e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor{
2946e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  if (!context)
2947c40b15fc6b37d152d67c2d2ec18d0e635ea70f90Sebastian Wilhelmi    context = g_main_context_default ();
29488951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor
29498951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  g_return_if_fail (g_atomic_int_get (&context->ref_count) > 0);
2950e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  g_return_if_fail (fd);
2951e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2952e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  LOCK_CONTEXT (context);
2953931ea952650b013b834041b91b0c37a748ffd449Owen Taylor  g_main_context_add_poll_unlocked (context, priority, fd);
2954931ea952650b013b834041b91b0c37a748ffd449Owen Taylor  UNLOCK_CONTEXT (context);
29552e57a3643891f41c238c5ee3793afcd8706a4060Sebastian Wilhelmi}
2956931ea952650b013b834041b91b0c37a748ffd449Owen Taylor
2957e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor/* HOLDS: main_loop_lock */
2958e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorstatic void
2959e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorg_main_context_add_poll_unlocked (GMainContext *context,
2960931ea952650b013b834041b91b0c37a748ffd449Owen Taylor				  gint          priority,
2961beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor				  GPollFD      *fd)
2962beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor{
2963e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  GPollRec *lastrec, *pollrec, *newrec;
2964e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2965beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  if (!context->poll_chunk)
2966e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    context->poll_chunk = g_mem_chunk_create (GPollRec, 32, G_ALLOC_ONLY);
2967931ea952650b013b834041b91b0c37a748ffd449Owen Taylor
2968e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  if (context->poll_free_list)
2969e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    {
2970931ea952650b013b834041b91b0c37a748ffd449Owen Taylor      newrec = context->poll_free_list;
2971931ea952650b013b834041b91b0c37a748ffd449Owen Taylor      context->poll_free_list = newrec->next;
2972e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    }
2973931ea952650b013b834041b91b0c37a748ffd449Owen Taylor  else
2974e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    newrec = g_chunk_new (GPollRec, context->poll_chunk);
2975e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2976beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  /* This file descriptor may be checked before we ever poll */
2977beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  fd->revents = 0;
2978beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  newrec->fd = fd;
2979beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  newrec->priority = priority;
2980e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
2981beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  lastrec = NULL;
2982beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  pollrec = context->poll_records;
2983beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  while (pollrec && priority >= pollrec->priority)
2984beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor    {
2985beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor      lastrec = pollrec;
2986beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor      pollrec = pollrec->next;
2987beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor    }
2988beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
2989beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  if (lastrec)
2990e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    lastrec->next = newrec;
2991beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  else
2992beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor    context->poll_records = newrec;
2993beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
2994e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  newrec->next = pollrec;
299587c7aeb93bd654776f59805a342ad913031034f3Tim Janik
299687c7aeb93bd654776f59805a342ad913031034f3Tim Janik  context->n_poll_records++;
2997e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
299887c7aeb93bd654776f59805a342ad913031034f3Tim Janik#ifdef G_THREADS_ENABLED
299987c7aeb93bd654776f59805a342ad913031034f3Tim Janik  context->poll_changed = TRUE;
30008951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor
300187c7aeb93bd654776f59805a342ad913031034f3Tim Janik  /* Now wake up the main loop if it is waiting in the poll() */
3002beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  g_main_context_wakeup_unlocked (context);
3003beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor#endif
3004e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor}
3005e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
3006e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor/**
3007e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * g_main_context_remove_poll:
3008e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * @context:a #GMainContext
3009a52e2986cd4a2147cfc8d41ae23d98907caaf3a0Matthias Clasen * @fd: a #GPollFD descriptor previously added with g_main_context_add_poll()
3010e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *
3011e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * Removes file descriptor from the set of file descriptors to be
3012e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * polled for a particular context.
3013e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor **/
3014e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorvoid
3015beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylorg_main_context_remove_poll (GMainContext *context,
3016e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor			    GPollFD      *fd)
3017e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor{
3018e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  if (!context)
3019c40b15fc6b37d152d67c2d2ec18d0e635ea70f90Sebastian Wilhelmi    context = g_main_context_default ();
30208951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor
3021beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  g_return_if_fail (g_atomic_int_get (&context->ref_count) > 0);
30228951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  g_return_if_fail (fd);
3023e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
3024e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  LOCK_CONTEXT (context);
3025e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  g_main_context_remove_poll_unlocked (context, fd);
3026e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  UNLOCK_CONTEXT (context);
3027e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor}
3028e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
3029e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorstatic void
3030e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorg_main_context_remove_poll_unlocked (GMainContext *context,
3031e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor				     GPollFD      *fd)
3032e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor{
3033beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  GPollRec *pollrec, *lastrec;
3034e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
3035beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  lastrec = NULL;
3036beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  pollrec = context->poll_records;
3037beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
3038beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  while (pollrec)
3039beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor    {
3040beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor      if (pollrec->fd == fd)
3041beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor	{
3042beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor	  if (lastrec != NULL)
3043e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	    lastrec->next = pollrec->next;
3044beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor	  else
30458c90d7766b1708a8bcb3cb96988b6b7fc92c2e59Sebastian Wilhelmi	    context->poll_records = pollrec->next;
30468c90d7766b1708a8bcb3cb96988b6b7fc92c2e59Sebastian Wilhelmi
30478c90d7766b1708a8bcb3cb96988b6b7fc92c2e59Sebastian Wilhelmi#ifdef ENABLE_GC_FRIENDLY
30488c90d7766b1708a8bcb3cb96988b6b7fc92c2e59Sebastian Wilhelmi	  pollrec->fd = NULL;
3049e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor#endif /* ENABLE_GC_FRIENDLY */
3050e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
3051931ea952650b013b834041b91b0c37a748ffd449Owen Taylor	  pollrec->next = context->poll_free_list;
3052e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor	  context->poll_free_list = pollrec;
3053931ea952650b013b834041b91b0c37a748ffd449Owen Taylor
3054beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor	  context->n_poll_records--;
3055beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor	  break;
3056beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor	}
3057beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor      lastrec = pollrec;
3058beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor      pollrec = pollrec->next;
305987c7aeb93bd654776f59805a342ad913031034f3Tim Janik    }
3060e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
306187c7aeb93bd654776f59805a342ad913031034f3Tim Janik#ifdef G_THREADS_ENABLED
306287c7aeb93bd654776f59805a342ad913031034f3Tim Janik  context->poll_changed = TRUE;
30638951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor
306487c7aeb93bd654776f59805a342ad913031034f3Tim Janik  /* Now wake up the main loop if it is waiting in the poll() */
3065e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  g_main_context_wakeup_unlocked (context);
306687c7aeb93bd654776f59805a342ad913031034f3Tim Janik#endif
3067e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor}
3068e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
3069e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor/**
3070e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * g_source_get_current_time:
3071e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * @source:  a #GSource
3072e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * @timeval: #GTimeVal structure in which to store current time.
3073e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *
3074e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * Gets the "current time" to be used when checking
3075e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * this source. The advantage of calling this function over
3076e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * calling g_get_current_time() directly is that when
3077e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * checking multiple sources, GLib can cache a single value
3078e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * instead of having to repeatedly get the system time.
3079e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor **/
3080e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorvoid
3081e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorg_source_get_current_time (GSource  *source,
3082e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor			   GTimeVal *timeval)
3083e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor{
3084e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  GMainContext *context;
3085e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
3086e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  g_return_if_fail (source->context != NULL);
3087e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
3088e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  context = source->context;
3089e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
3090e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  LOCK_CONTEXT (context);
3091e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
3092e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  if (!context->time_is_current)
3093e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    {
3094e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      g_get_current_time (&context->current_time);
3095e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      context->time_is_current = TRUE;
3096e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    }
3097e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
3098e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  *timeval = context->current_time;
3099beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
3100beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  UNLOCK_CONTEXT (context);
3101e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor}
3102e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
3103e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor/**
3104e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * g_main_context_set_poll_func:
3105e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * @context: a #GMainContext
3106e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * @func: the function to call to poll all file descriptors
3107a412fb16541620ed72da86daac0774afe4703d9dMatthias Clasen *
3108a52e2986cd4a2147cfc8d41ae23d98907caaf3a0Matthias Clasen * Sets the function to use to handle polling of file descriptors. It
3109a412fb16541620ed72da86daac0774afe4703d9dMatthias Clasen * will be used instead of the poll() system call
3110e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * (or GLib's replacement function, which is used where
3111e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * poll() isn't available).
3112e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *
3113e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * This function could possibly be used to integrate the GLib event
3114e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * loop with an external event loop.
3115e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor **/
3116e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorvoid
3117beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylorg_main_context_set_poll_func (GMainContext *context,
3118e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor			      GPollFunc     func)
3119e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor{
3120e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  if (!context)
3121c40b15fc6b37d152d67c2d2ec18d0e635ea70f90Sebastian Wilhelmi    context = g_main_context_default ();
31228951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor
3123e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  g_return_if_fail (g_atomic_int_get (&context->ref_count) > 0);
3124e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
3125beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  LOCK_CONTEXT (context);
3126e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
3127beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  if (func)
3128e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    context->poll_func = func;
3129738864a1a758b2421211e4ecf1ce6102842428eaManish Singh  else
3130e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    {
3131738864a1a758b2421211e4ecf1ce6102842428eaManish Singh#ifdef HAVE_POLL
3132e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      context->poll_func = (GPollFunc) poll;
3133738864a1a758b2421211e4ecf1ce6102842428eaManish Singh#else
3134e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      context->poll_func = (GPollFunc) g_poll;
3135e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor#endif
3136e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    }
3137beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
3138beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  UNLOCK_CONTEXT (context);
3139e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor}
3140e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
3141e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor/**
3142e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * g_main_context_get_poll_func:
3143a52e2986cd4a2147cfc8d41ae23d98907caaf3a0Matthias Clasen * @context: a #GMainContext
3144e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *
3145e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * Gets the poll function set by g_main_context_set_poll_func().
3146e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *
3147b965bb5db1732cee8e0ed92d6484921a1431d6a9Tor Lillqvist * Return value: the poll function
3148e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor **/
3149b965bb5db1732cee8e0ed92d6484921a1431d6a9Tor LillqvistGPollFunc
3150b74e7d2f4780c159f7583bd4eecd07ee222d1d9cTor Lillqvistg_main_context_get_poll_func (GMainContext *context)
3151e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor{
3152e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  GPollFunc result;
3153e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
3154e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  if (!context)
3155c40b15fc6b37d152d67c2d2ec18d0e635ea70f90Sebastian Wilhelmi    context = g_main_context_default ();
31568951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor
3157e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  g_return_val_if_fail (g_atomic_int_get (&context->ref_count) > 0, NULL);
3158e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
3159e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  LOCK_CONTEXT (context);
3160b965bb5db1732cee8e0ed92d6484921a1431d6a9Tor Lillqvist  result = context->poll_func;
3161b74e7d2f4780c159f7583bd4eecd07ee222d1d9cTor Lillqvist  UNLOCK_CONTEXT (context);
3162b74e7d2f4780c159f7583bd4eecd07ee222d1d9cTor Lillqvist
3163b965bb5db1732cee8e0ed92d6484921a1431d6a9Tor Lillqvist  return result;
3164e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor}
316587c7aeb93bd654776f59805a342ad913031034f3Tim Janik
316687c7aeb93bd654776f59805a342ad913031034f3Tim Janik/* HOLDS: context's lock */
31678951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor/* Wake the main loop up from a poll() */
316887c7aeb93bd654776f59805a342ad913031034f3Tim Janikstatic void
316987c7aeb93bd654776f59805a342ad913031034f3Tim Janikg_main_context_wakeup_unlocked (GMainContext *context)
3170e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor{
317187c7aeb93bd654776f59805a342ad913031034f3Tim Janik#ifdef G_THREADS_ENABLED
3172e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  if (g_thread_supported() && context->poll_waiting)
31737ea73a019935e1118935433c86480acc5eee2e05Manish Singh    {
3174e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      context->poll_waiting = FALSE;
317587c7aeb93bd654776f59805a342ad913031034f3Tim Janik#ifndef G_OS_WIN32
3176b74e7d2f4780c159f7583bd4eecd07ee222d1d9cTor Lillqvist      write (context->wake_up_pipe[1], "A", 1);
317787c7aeb93bd654776f59805a342ad913031034f3Tim Janik#else
317887c7aeb93bd654776f59805a342ad913031034f3Tim Janik      ReleaseSemaphore (context->wake_up_semaphore, 1, NULL);
317987c7aeb93bd654776f59805a342ad913031034f3Tim Janik#endif
318087c7aeb93bd654776f59805a342ad913031034f3Tim Janik    }
318187c7aeb93bd654776f59805a342ad913031034f3Tim Janik#endif
31828951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor}
31838951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor
31848951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor/**
31858951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor * g_main_context_wakeup:
3186a412fb16541620ed72da86daac0774afe4703d9dMatthias Clasen * @context: a #GMainContext
3187a412fb16541620ed72da86daac0774afe4703d9dMatthias Clasen *
31888951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor * If @context is currently waiting in a poll(), interrupt
31898951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor * the poll(), and continue the iteration process.
31908951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor **/
31918951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylorvoid
31928951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylorg_main_context_wakeup (GMainContext *context)
31938951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor{
31948951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  if (!context)
3195c40b15fc6b37d152d67c2d2ec18d0e635ea70f90Sebastian Wilhelmi    context = g_main_context_default ();
31968951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor
31978951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  g_return_if_fail (g_atomic_int_get (&context->ref_count) > 0);
31988951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor
31998951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  LOCK_CONTEXT (context);
32008951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  g_main_context_wakeup_unlocked (context);
32018951f96c50fda95a8cfaf48e8e378136a9268365Owen Taylor  UNLOCK_CONTEXT (context);
3202beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor}
3203beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
3204db8baf697889c80c0632d7cc91343c18a2647429Tim Janik/* Timeouts */
3205e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
3206e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorstatic void
3207db8baf697889c80c0632d7cc91343c18a2647429Tim Janikg_timeout_set_expiration (GTimeoutSource *timeout_source,
3208e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor			  GTimeVal       *current_time)
3209e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor{
3210db8baf697889c80c0632d7cc91343c18a2647429Tim Janik  guint seconds = timeout_source->interval / 1000;
3211e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  guint msecs = timeout_source->interval - seconds * 1000;
3212e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
3213e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  timeout_source->expiration.tv_sec = current_time->tv_sec + seconds;
3214db8baf697889c80c0632d7cc91343c18a2647429Tim Janik  timeout_source->expiration.tv_usec = current_time->tv_usec + msecs * 1000;
3215e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  if (timeout_source->expiration.tv_usec >= 1000000)
3216e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    {
3217db8baf697889c80c0632d7cc91343c18a2647429Tim Janik      timeout_source->expiration.tv_usec -= 1000000;
3218db8baf697889c80c0632d7cc91343c18a2647429Tim Janik      timeout_source->expiration.tv_sec++;
3219db8baf697889c80c0632d7cc91343c18a2647429Tim Janik    }
3220db8baf697889c80c0632d7cc91343c18a2647429Tim Janik}
3221e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
3222e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorstatic gboolean
3223beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylorg_timeout_prepare  (GSource  *source,
3224f5c28ce4ab8e8015a1432060b6cfe547183b2f9eOwen Taylor		    gint     *timeout)
3225beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor{
3226e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  glong sec;
3227db8baf697889c80c0632d7cc91343c18a2647429Tim Janik  glong msec;
3228e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  GTimeVal current_time;
3229e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
3230e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  GTimeoutSource *timeout_source = (GTimeoutSource *)source;
3231e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
3232f5c28ce4ab8e8015a1432060b6cfe547183b2f9eOwen Taylor  g_source_get_current_time (source, &current_time);
3233f5c28ce4ab8e8015a1432060b6cfe547183b2f9eOwen Taylor
3234f5c28ce4ab8e8015a1432060b6cfe547183b2f9eOwen Taylor  sec = timeout_source->expiration.tv_sec - current_time.tv_sec;
3235f5c28ce4ab8e8015a1432060b6cfe547183b2f9eOwen Taylor  msec = (timeout_source->expiration.tv_usec - current_time.tv_usec) / 1000;
3236f5c28ce4ab8e8015a1432060b6cfe547183b2f9eOwen Taylor
3237f5c28ce4ab8e8015a1432060b6cfe547183b2f9eOwen Taylor  /* We do the following in a rather convoluted fashion to deal with
3238f5c28ce4ab8e8015a1432060b6cfe547183b2f9eOwen Taylor   * the fact that we don't have an integral type big enough to hold
3239f5c28ce4ab8e8015a1432060b6cfe547183b2f9eOwen Taylor   * the difference of two timevals in millseconds.
3240db8baf697889c80c0632d7cc91343c18a2647429Tim Janik   */
3241f5c28ce4ab8e8015a1432060b6cfe547183b2f9eOwen Taylor  if (sec < 0 || (sec == 0 && msec < 0))
3242db8baf697889c80c0632d7cc91343c18a2647429Tim Janik    msec = 0;
3243f5c28ce4ab8e8015a1432060b6cfe547183b2f9eOwen Taylor  else
3244f5c28ce4ab8e8015a1432060b6cfe547183b2f9eOwen Taylor    {
3245f5c28ce4ab8e8015a1432060b6cfe547183b2f9eOwen Taylor      glong interval_sec = timeout_source->interval / 1000;
3246f5c28ce4ab8e8015a1432060b6cfe547183b2f9eOwen Taylor      glong interval_msec = timeout_source->interval % 1000;
3247f5c28ce4ab8e8015a1432060b6cfe547183b2f9eOwen Taylor
3248f5c28ce4ab8e8015a1432060b6cfe547183b2f9eOwen Taylor      if (msec < 0)
3249f5c28ce4ab8e8015a1432060b6cfe547183b2f9eOwen Taylor	{
3250f5c28ce4ab8e8015a1432060b6cfe547183b2f9eOwen Taylor	  msec += 1000;
3251f5c28ce4ab8e8015a1432060b6cfe547183b2f9eOwen Taylor	  sec -= 1;
3252f5c28ce4ab8e8015a1432060b6cfe547183b2f9eOwen Taylor	}
3253f5c28ce4ab8e8015a1432060b6cfe547183b2f9eOwen Taylor
3254f5c28ce4ab8e8015a1432060b6cfe547183b2f9eOwen Taylor      if (sec > interval_sec ||
3255f5c28ce4ab8e8015a1432060b6cfe547183b2f9eOwen Taylor	  (sec == interval_sec && msec > interval_msec))
3256f5c28ce4ab8e8015a1432060b6cfe547183b2f9eOwen Taylor	{
3257f5c28ce4ab8e8015a1432060b6cfe547183b2f9eOwen Taylor	  /* The system time has been set backwards, so we
3258f5c28ce4ab8e8015a1432060b6cfe547183b2f9eOwen Taylor	   * reset the expiration time to now + timeout_source->interval;
3259f5c28ce4ab8e8015a1432060b6cfe547183b2f9eOwen Taylor	   * this at least avoids hanging for long periods of time.
326052644b08e77ddb3c146556451982dd3ff53bc1efOwen Taylor	   */
3261f5c28ce4ab8e8015a1432060b6cfe547183b2f9eOwen Taylor	  g_timeout_set_expiration (timeout_source, &current_time);
3262f5c28ce4ab8e8015a1432060b6cfe547183b2f9eOwen Taylor	  msec = MIN (G_MAXINT, timeout_source->interval);
3263f5c28ce4ab8e8015a1432060b6cfe547183b2f9eOwen Taylor	}
326452644b08e77ddb3c146556451982dd3ff53bc1efOwen Taylor      else
3265f5c28ce4ab8e8015a1432060b6cfe547183b2f9eOwen Taylor	{
3266db8baf697889c80c0632d7cc91343c18a2647429Tim Janik	  msec = MIN (G_MAXINT, (guint)msec + 1000 * (guint)sec);
3267f5c28ce4ab8e8015a1432060b6cfe547183b2f9eOwen Taylor	}
3268f5c28ce4ab8e8015a1432060b6cfe547183b2f9eOwen Taylor    }
3269db8baf697889c80c0632d7cc91343c18a2647429Tim Janik
3270db8baf697889c80c0632d7cc91343c18a2647429Tim Janik  *timeout = (gint)msec;
3271beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
3272beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  return msec == 0;
3273beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor}
3274e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
3275beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylorstatic gboolean
3276e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorg_timeout_check (GSource  *source)
3277e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor{
3278e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  GTimeVal current_time;
3279e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  GTimeoutSource *timeout_source = (GTimeoutSource *)source;
3280db8baf697889c80c0632d7cc91343c18a2647429Tim Janik
3281e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  g_source_get_current_time (source, &current_time);
3282e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
3283e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  return ((timeout_source->expiration.tv_sec < current_time.tv_sec) ||
3284beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor	  ((timeout_source->expiration.tv_sec == current_time.tv_sec) &&
3285beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor	   (timeout_source->expiration.tv_usec <= current_time.tv_usec)));
3286beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor}
3287e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
3288e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorstatic gboolean
3289e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorg_timeout_dispatch (GSource    *source,
3290beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor		    GSourceFunc callback,
3291e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor		    gpointer    user_data)
3292beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor{
3293e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  GTimeoutSource *timeout_source = (GTimeoutSource *)source;
3294e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
3295e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  if (!callback)
3296e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    {
3297e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      g_warning ("Timeout source dispatched without callback\n"
3298e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor		 "You must call g_source_set_callback().");
3299e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      return FALSE;
3300e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    }
3301beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
3302e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  if (callback (user_data))
3303e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    {
3304e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      GTimeVal current_time;
3305e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
33062623d2831ab006459da71d8a869a7a9a55869df2Owen Taylor      g_source_get_current_time (source, &current_time);
3307beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor      g_timeout_set_expiration (timeout_source, &current_time);
3308beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
3309beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor      return TRUE;
3310beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor    }
3311beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  else
3312beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor    return FALSE;
3313e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor}
3314e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
3315e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor/**
3316e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * g_timeout_source_new:
3317a52e2986cd4a2147cfc8d41ae23d98907caaf3a0Matthias Clasen * @interval: the timeout interval in milliseconds.
3318e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *
3319e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * Creates a new timeout source.
3320e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *
3321e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * The source will not initially be associated with any #GMainContext
3322e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * and must be added to one with g_source_attach() before it will be
3323a52e2986cd4a2147cfc8d41ae23d98907caaf3a0Matthias Clasen * executed.
3324e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *
3325e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * Return value: the newly-created timeout source
3326e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor **/
3327e2fd4e2bd0589b159f87b491095565d16fac2789Owen TaylorGSource *
3328b4c3107c7a1dc5dd9e8050ed06f24d6be408e840Owen Taylorg_timeout_source_new (guint interval)
3329e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor{
3330e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  GSource *source = g_source_new (&g_timeout_funcs, sizeof (GTimeoutSource));
3331e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  GTimeoutSource *timeout_source = (GTimeoutSource *)source;
3332e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  GTimeVal current_time;
3333e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
3334e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  timeout_source->interval = interval;
3335e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
3336e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  g_get_current_time (&current_time);
3337e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  g_timeout_set_expiration (timeout_source, &current_time);
3338e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
3339e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  return source;
3340e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor}
3341e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
3342e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor/**
3343a52e2986cd4a2147cfc8d41ae23d98907caaf3a0Matthias Clasen * g_timeout_add_full:
3344e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * @priority: the priority of the idle source. Typically this will be in the
3345a52e2986cd4a2147cfc8d41ae23d98907caaf3a0Matthias Clasen *            range between #G_PRIORITY_DEFAULT_IDLE and #G_PRIORITY_HIGH_IDLE.
3346e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * @interval: the time between calls to the function, in milliseconds
3347e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *             (1/1000ths of a second)
3348e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * @function: function to call
3349e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * @data:     data to pass to @function
3350e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * @notify:   function to call when the idle is removed, or %NULL
3351e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *
3352a52e2986cd4a2147cfc8d41ae23d98907caaf3a0Matthias Clasen * Sets a function to be called at regular intervals, with the given
3353e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * priority.  The function is called repeatedly until it returns
3354e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * %FALSE, at which point the timeout is automatically destroyed and
3355e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * the function will not be called again.  The @notify function is
3356e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * called when the timeout is destroyed.  The first call to the
3357e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * function will be at the end of the first @interval.
3358e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *
3359e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * Note that timeout functions may be delayed, due to the processing of other
3360e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * event sources. Thus they should not be relied on for precise timing.
3361e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * After each call to the timeout function, the time of the next
3362e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * timeout is recalculated based on the current time and the given interval
3363e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * (it does not try to 'catch up' time lost in delays).
3364e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *
3365db8baf697889c80c0632d7cc91343c18a2647429Tim Janik * Return value: the id of event source.
3366beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor **/
3367db8baf697889c80c0632d7cc91343c18a2647429Tim Janikguint
3368beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylorg_timeout_add_full (gint           priority,
3369beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor		    guint          interval,
3370beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor		    GSourceFunc    function,
3371beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor		    gpointer       data,
3372e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor		    GDestroyNotify notify)
33731084477e032113aefa2aad6d8c0a7360fafaae91Owen Taylor{
3374e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  GSource *source;
3375e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  guint id;
3376beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
3377e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  g_return_val_if_fail (function != NULL, 0);
33782623d2831ab006459da71d8a869a7a9a55869df2Owen Taylor
3379e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  source = g_timeout_source_new (interval);
3380e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
3381beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  if (priority != G_PRIORITY_DEFAULT)
3382e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    g_source_set_priority (source, priority);
33831084477e032113aefa2aad6d8c0a7360fafaae91Owen Taylor
33841084477e032113aefa2aad6d8c0a7360fafaae91Owen Taylor  g_source_set_callback (source, function, data, notify);
33851084477e032113aefa2aad6d8c0a7360fafaae91Owen Taylor  id = g_source_attach (source, NULL);
33861084477e032113aefa2aad6d8c0a7360fafaae91Owen Taylor  g_source_unref (source);
3387beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
3388beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  return id;
3389e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor}
3390e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
3391e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor/**
3392a52e2986cd4a2147cfc8d41ae23d98907caaf3a0Matthias Clasen * g_timeout_add:
3393e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * @interval: the time between calls to the function, in milliseconds
3394e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *             (1/1000ths of a second)
3395e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * @function: function to call
3396e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * @data:     data to pass to @function
3397e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *
3398a52e2986cd4a2147cfc8d41ae23d98907caaf3a0Matthias Clasen * Sets a function to be called at regular intervals, with the default
33991d3b965d0792818bea32260f957cfab49791f833Owen Taylor * priority, #G_PRIORITY_DEFAULT.  The function is called repeatedly
3400e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * until it returns %FALSE, at which point the timeout is automatically
3401e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * destroyed and the function will not be called again.  The first call
3402e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * to the function will be at the end of the first @interval.
3403e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *
3404e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * Note that timeout functions may be delayed, due to the processing of other
3405e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * event sources. Thus they should not be relied on for precise timing.
3406e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * After each call to the timeout function, the time of the next
3407e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * timeout is recalculated based on the current time and the given interval
3408e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * (it does not try to 'catch up' time lost in delays).
3409e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *
3410beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor * Return value: the id of event source.
3411beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor **/
3412beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylorguint
3413beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylorg_timeout_add (guint32        interval,
3414beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor	       GSourceFunc    function,
34157f237f6fcd00ad9888ef459ccdc8d02e12c311fdOwen Taylor	       gpointer       data)
34167f237f6fcd00ad9888ef459ccdc8d02e12c311fdOwen Taylor{
3417beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  return g_timeout_add_full (G_PRIORITY_DEFAULT,
3418beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor			     interval, function, data, NULL);
3419540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen}
3420540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen
34214d470362b20627044ed9e56fa47ba012cb9b4c54Hans Breuer/* Child watch functions */
34224d470362b20627044ed9e56fa47ba012cb9b4c54Hans Breuer
34234d470362b20627044ed9e56fa47ba012cb9b4c54Hans Breuer#ifdef G_OS_WIN32
34244d470362b20627044ed9e56fa47ba012cb9b4c54Hans Breuer
34254d470362b20627044ed9e56fa47ba012cb9b4c54Hans Breuerstatic gboolean
34264d470362b20627044ed9e56fa47ba012cb9b4c54Hans Breuerg_child_watch_prepare (GSource *source,
34274d470362b20627044ed9e56fa47ba012cb9b4c54Hans Breuer		       gint    *timeout)
34284d470362b20627044ed9e56fa47ba012cb9b4c54Hans Breuer{
34294d470362b20627044ed9e56fa47ba012cb9b4c54Hans Breuer  *timeout = -1;
34304d470362b20627044ed9e56fa47ba012cb9b4c54Hans Breuer  return FALSE;
34314d470362b20627044ed9e56fa47ba012cb9b4c54Hans Breuer}
34324d470362b20627044ed9e56fa47ba012cb9b4c54Hans Breuer
34334d470362b20627044ed9e56fa47ba012cb9b4c54Hans Breuer
34344d470362b20627044ed9e56fa47ba012cb9b4c54Hans Breuerstatic gboolean
34354d470362b20627044ed9e56fa47ba012cb9b4c54Hans Breuerg_child_watch_check (GSource  *source)
34364d470362b20627044ed9e56fa47ba012cb9b4c54Hans Breuer{
34374d470362b20627044ed9e56fa47ba012cb9b4c54Hans Breuer  GChildWatchSource *child_watch_source;
34384d470362b20627044ed9e56fa47ba012cb9b4c54Hans Breuer  gboolean child_exited;
34394d470362b20627044ed9e56fa47ba012cb9b4c54Hans Breuer
34404d470362b20627044ed9e56fa47ba012cb9b4c54Hans Breuer  child_watch_source = (GChildWatchSource *) source;
34414d470362b20627044ed9e56fa47ba012cb9b4c54Hans Breuer
34424d470362b20627044ed9e56fa47ba012cb9b4c54Hans Breuer  child_exited = child_watch_source->poll.revents & G_IO_IN;
34434d470362b20627044ed9e56fa47ba012cb9b4c54Hans Breuer
34444d470362b20627044ed9e56fa47ba012cb9b4c54Hans Breuer  if (child_exited)
34454d470362b20627044ed9e56fa47ba012cb9b4c54Hans Breuer    {
34464d470362b20627044ed9e56fa47ba012cb9b4c54Hans Breuer      DWORD child_status;
34474d470362b20627044ed9e56fa47ba012cb9b4c54Hans Breuer
34484d470362b20627044ed9e56fa47ba012cb9b4c54Hans Breuer      /*
34494d470362b20627044ed9e56fa47ba012cb9b4c54Hans Breuer       * Note: We do _not_ check for the special value of STILL_ACTIVE
34504d470362b20627044ed9e56fa47ba012cb9b4c54Hans Breuer       * since we know that the process has exited and doing so runs into
34514d470362b20627044ed9e56fa47ba012cb9b4c54Hans Breuer       * problems if the child process "happens to return STILL_ACTIVE(259)"
34524d470362b20627044ed9e56fa47ba012cb9b4c54Hans Breuer       * as Microsoft's Platform SDK puts it.
34534d470362b20627044ed9e56fa47ba012cb9b4c54Hans Breuer       */
34544d470362b20627044ed9e56fa47ba012cb9b4c54Hans Breuer      if (!GetExitCodeProcess (child_watch_source->pid, &child_status))
34554d470362b20627044ed9e56fa47ba012cb9b4c54Hans Breuer        {
34564d470362b20627044ed9e56fa47ba012cb9b4c54Hans Breuer	  gchar *emsg = g_win32_error_message (GetLastError ());
34574d470362b20627044ed9e56fa47ba012cb9b4c54Hans Breuer	  g_warning (G_STRLOC ": GetExitCodeProcess() failed: %s", emsg);
34584d470362b20627044ed9e56fa47ba012cb9b4c54Hans Breuer	  g_free (emsg);
34594d470362b20627044ed9e56fa47ba012cb9b4c54Hans Breuer
34604d470362b20627044ed9e56fa47ba012cb9b4c54Hans Breuer	  child_watch_source->child_status = -1;
34614d470362b20627044ed9e56fa47ba012cb9b4c54Hans Breuer	}
34624d470362b20627044ed9e56fa47ba012cb9b4c54Hans Breuer      else
34634d470362b20627044ed9e56fa47ba012cb9b4c54Hans Breuer	child_watch_source->child_status = child_status;
34644d470362b20627044ed9e56fa47ba012cb9b4c54Hans Breuer    }
34654d470362b20627044ed9e56fa47ba012cb9b4c54Hans Breuer
34664d470362b20627044ed9e56fa47ba012cb9b4c54Hans Breuer  return child_exited;
34674d470362b20627044ed9e56fa47ba012cb9b4c54Hans Breuer}
34684d470362b20627044ed9e56fa47ba012cb9b4c54Hans Breuer
346944ef9006758b4bfd899b4ba9b46b69528ed070f5Owen Taylor#else /* G_OS_WIN32 */
3470540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen
3471540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasenstatic gboolean
3472540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasencheck_for_child_exited (GSource *source)
3473540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen{
3474540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  GChildWatchSource *child_watch_source;
3475540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  gint count;
3476540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen
3477540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  /* protect against another SIGCHLD in the middle of this call */
3478540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  count = child_watch_count;
3479540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen
348044ef9006758b4bfd899b4ba9b46b69528ed070f5Owen Taylor  child_watch_source = (GChildWatchSource *) source;
348144ef9006758b4bfd899b4ba9b46b69528ed070f5Owen Taylor
348244ef9006758b4bfd899b4ba9b46b69528ed070f5Owen Taylor  if (child_watch_source->child_exited)
3483540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen    return TRUE;
3484540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen
3485540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  if (child_watch_source->count < count)
3486540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen    {
3487540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen      gint child_status;
3488540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen
3489540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen      if (waitpid (child_watch_source->pid, &child_status, WNOHANG) > 0)
3490540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen	{
3491540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen	  child_watch_source->child_status = child_status;
3492540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen	  child_watch_source->child_exited = TRUE;
3493540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen	}
349444ef9006758b4bfd899b4ba9b46b69528ed070f5Owen Taylor      child_watch_source->count = count;
349544ef9006758b4bfd899b4ba9b46b69528ed070f5Owen Taylor    }
3496540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen
3497540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  return child_watch_source->child_exited;
3498540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen}
3499540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen
3500540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasenstatic gboolean
3501540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Claseng_child_watch_prepare (GSource *source,
3502540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen		       gint    *timeout)
3503540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen{
3504540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  GChildWatchSource *child_watch_source;
3505540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  *timeout = -1;
3506540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen
350744ef9006758b4bfd899b4ba9b46b69528ed070f5Owen Taylor  child_watch_source = (GChildWatchSource *) source;
3508540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen
3509540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  return check_for_child_exited (source);
3510540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen}
3511540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen
3512540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen
3513540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasenstatic gboolean
3514540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Claseng_child_watch_check (GSource  *source)
3515540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen{
3516540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  GChildWatchSource *child_watch_source;
3517540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen
351844ef9006758b4bfd899b4ba9b46b69528ed070f5Owen Taylor  child_watch_source = (GChildWatchSource *) source;
3519540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen
3520540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  return check_for_child_exited (source);
35214d470362b20627044ed9e56fa47ba012cb9b4c54Hans Breuer}
35224d470362b20627044ed9e56fa47ba012cb9b4c54Hans Breuer
3523540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen#endif /* G_OS_WIN32 */
3524540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen
3525540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasenstatic gboolean
3526540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Claseng_child_watch_dispatch (GSource    *source,
3527540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen			GSourceFunc callback,
3528540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen			gpointer    user_data)
3529540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen{
3530540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  GChildWatchSource *child_watch_source;
3531540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  GChildWatchFunc child_watch_callback = (GChildWatchFunc) callback;
3532540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen
3533540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  child_watch_source = (GChildWatchSource *) source;
3534540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen
3535540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  if (!callback)
3536540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen    {
3537540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen      g_warning ("Child watch source dispatched without callback\n"
3538540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen		 "You must call g_source_set_callback().");
3539540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen      return FALSE;
3540540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen    }
3541540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen
3542540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  (child_watch_callback) (child_watch_source->pid, child_watch_source->child_status, user_data);
3543540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen
3544540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  /* We never keep a child watch source around as the child is gone */
3545540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  return FALSE;
35464d470362b20627044ed9e56fa47ba012cb9b4c54Hans Breuer}
35474d470362b20627044ed9e56fa47ba012cb9b4c54Hans Breuer
3548540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen#ifndef G_OS_WIN32
3549540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen
3550540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasenstatic void
3551540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Claseng_child_watch_signal_handler (int signum)
3552540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen{
3553540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  child_watch_count ++;
3554540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen
3555540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  if (child_watch_init_state == CHILD_WATCH_INITIALIZED_THREADED)
3556540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen    {
3557540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen      write (child_watch_wake_up_pipe[1], "B", 1);
3558540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen    }
3559540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  else
3560540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen    {
3561540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen      /* We count on the signal interrupting the poll in the same thread.
3562540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen       */
3563540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen    }
3564540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen}
3565540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen
3566540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasenstatic void
3567540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Claseng_child_watch_source_init_single (void)
3568540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen{
3569540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  g_assert (! g_thread_supported());
3570540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  g_assert (child_watch_init_state == CHILD_WATCH_UNINITIALIZED);
3571540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen
3572540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  child_watch_init_state = CHILD_WATCH_INITIALIZED_SINGLE;
3573540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen
3574540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  signal (SIGCHLD, g_child_watch_signal_handler);
3575540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen}
3576540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen
3577540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasenstatic gpointer
3578540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasenchild_watch_helper_thread (gpointer data)
3579540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen{
3580540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  GPollFD fds;
3581540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  GPollFunc poll_func;
3582540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen
3583540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen#ifdef HAVE_POLL
3584540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen      poll_func = (GPollFunc)poll;
3585540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen#else
3586540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen      poll_func = g_poll;
3587540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen#endif
3588540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen
3589540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  fds.fd = child_watch_wake_up_pipe[0];
3590540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  fds.events = G_IO_IN;
3591540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen
3592540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  while (1)
3593540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen    {
3594540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen      gchar b[20];
3595540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen      GSList *list;
3596540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen
3597540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen      read (child_watch_wake_up_pipe[0], b, 20);
3598c40b15fc6b37d152d67c2d2ec18d0e635ea70f90Sebastian Wilhelmi
3599540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen      /* We were woken up.  Wake up all other contexts in all other threads */
3600540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen      G_LOCK (main_context_list);
3601540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen      for (list = main_context_list; list; list = list->next)
3602540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen	{
3603540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen	  GMainContext *context;
3604c40b15fc6b37d152d67c2d2ec18d0e635ea70f90Sebastian Wilhelmi
3605c40b15fc6b37d152d67c2d2ec18d0e635ea70f90Sebastian Wilhelmi	  context = list->data;
3606c40b15fc6b37d152d67c2d2ec18d0e635ea70f90Sebastian Wilhelmi	  if (g_atomic_int_get (&context->ref_count) > 0)
3607c40b15fc6b37d152d67c2d2ec18d0e635ea70f90Sebastian Wilhelmi	    /* Due to racing conditions we can find ref_count == 0, in
3608c40b15fc6b37d152d67c2d2ec18d0e635ea70f90Sebastian Wilhelmi	     * that case, however, the context is still not destroyed
3609c40b15fc6b37d152d67c2d2ec18d0e635ea70f90Sebastian Wilhelmi	     * and no poll can be active, otherwise the ref_count
3610540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen	     * wouldn't be 0 */
3611c40b15fc6b37d152d67c2d2ec18d0e635ea70f90Sebastian Wilhelmi	    g_main_context_wakeup (context);
3612540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen	}
3613540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen      G_UNLOCK (main_context_list);
3614540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen    }
3615540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  return NULL;
3616540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen}
3617540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen
3618540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasenstatic void
3619540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Claseng_child_watch_source_init_multi_threaded (void)
3620540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen{
3621540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  GError *error = NULL;
3622540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen
3623540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  g_assert (g_thread_supported());
3624540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen
3625540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  if (pipe (child_watch_wake_up_pipe) < 0)
3626540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen    g_error ("Cannot create wake up pipe: %s\n", g_strerror (errno));
3627540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  fcntl (child_watch_wake_up_pipe[1], F_SETFL, O_NONBLOCK | fcntl (child_watch_wake_up_pipe[1], F_GETFL));
3628540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen
3629540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  /* We create a helper thread that polls on the wakeup pipe indefinitely */
3630540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  /* FIXME: Think this through for races */
3631540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  if (g_thread_create (child_watch_helper_thread, NULL, FALSE, &error) == NULL)
3632540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen    g_error ("Cannot create a thread to monitor child exit status: %s\n", error->message);
3633540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  child_watch_init_state = CHILD_WATCH_INITIALIZED_THREADED;
3634540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  signal (SIGCHLD, g_child_watch_signal_handler);
3635540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen}
3636540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen
3637540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasenstatic void
3638540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Claseng_child_watch_source_init_promote_single_to_threaded (void)
3639540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen{
3640540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  g_child_watch_source_init_multi_threaded ();
3641540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen}
3642540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen
3643540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasenstatic void
3644540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Claseng_child_watch_source_init (void)
3645540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen{
3646540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  if (g_thread_supported())
3647540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen    {
3648540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen      if (child_watch_init_state == CHILD_WATCH_UNINITIALIZED)
3649540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen	g_child_watch_source_init_multi_threaded ();
3650540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen      else if (child_watch_init_state == CHILD_WATCH_INITIALIZED_SINGLE)
3651540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen	g_child_watch_source_init_promote_single_to_threaded ();
3652540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen    }
3653540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  else
3654540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen    {
3655540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen      if (child_watch_init_state == CHILD_WATCH_UNINITIALIZED)
3656540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen	g_child_watch_source_init_single ();
3657540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen    }
36584d470362b20627044ed9e56fa47ba012cb9b4c54Hans Breuer}
36594d470362b20627044ed9e56fa47ba012cb9b4c54Hans Breuer
3660540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen#endif /* !G_OS_WIN32 */
3661540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen
36629b4080611ac14c5579ca7491c512f07a0a9b8347Tor Lillqvist/**
36639b4080611ac14c5579ca7491c512f07a0a9b8347Tor Lillqvist * g_child_watch_source_new:
3664540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen * @pid: process id of a child process to watch. On Windows, a HANDLE
3665540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen * for the process to watch (which actually doesn't have to be a child).
3666540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen *
3667540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen * Creates a new child_watch source.
3668540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen *
3669540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen * The source will not initially be associated with any #GMainContext
3670540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen * and must be added to one with g_source_attach() before it will be
367138cbfaeb7a2ca063ec600de2220ba1c6796647a4Owen Taylor * executed.
367238cbfaeb7a2ca063ec600de2220ba1c6796647a4Owen Taylor *
367338cbfaeb7a2ca063ec600de2220ba1c6796647a4Owen Taylor * Note that on platforms where #GPid must be explicitely closed
367438cbfaeb7a2ca063ec600de2220ba1c6796647a4Owen Taylor * (see g_spawn_close_pid()) @pid must not be closed while the
367538cbfaeb7a2ca063ec600de2220ba1c6796647a4Owen Taylor * source is still active. Typically, you will want to call
3676540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen * g_spawn_close_pid() in the callback function for the source.
3677540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen *
3678540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen * Return value: the newly-created child watch source
3679540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen *
3680540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen * Since: 2.4
3681540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen **/
3682540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias ClasenGSource *
3683540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Claseng_child_watch_source_new (GPid pid)
3684540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen{
3685540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  GSource *source = g_source_new (&g_child_watch_funcs, sizeof (GChildWatchSource));
36864d470362b20627044ed9e56fa47ba012cb9b4c54Hans Breuer  GChildWatchSource *child_watch_source = (GChildWatchSource *)source;
36874d470362b20627044ed9e56fa47ba012cb9b4c54Hans Breuer
36884d470362b20627044ed9e56fa47ba012cb9b4c54Hans Breuer#ifdef G_OS_WIN32
36894d470362b20627044ed9e56fa47ba012cb9b4c54Hans Breuer  child_watch_source->poll.fd = (int)pid;
36904d470362b20627044ed9e56fa47ba012cb9b4c54Hans Breuer  child_watch_source->poll.events = G_IO_IN;
36914d470362b20627044ed9e56fa47ba012cb9b4c54Hans Breuer
3692540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  g_source_add_poll (source, &child_watch_source->poll);
36934d470362b20627044ed9e56fa47ba012cb9b4c54Hans Breuer#else /* G_OS_WIN32 */
3694540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  g_child_watch_source_init ();
3695540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen#endif /* G_OS_WIN32 */
3696540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen
3697540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  child_watch_source->pid = pid;
3698540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen
3699540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  return source;
3700540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen}
3701540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen
3702540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen/**
3703540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen * g_child_watch_add_full:
3704540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen * @priority: the priority of the idle source. Typically this will be in the
3705540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen *            range between #G_PRIORITY_DEFAULT_IDLE and #G_PRIORITY_HIGH_IDLE.
3706540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen * @pid:      process id of a child process to watch
3707540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen * @function: function to call
3708540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen * @data:     data to pass to @function
3709540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen * @notify:   function to call when the idle is removed, or %NULL
3710540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen *
3711540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen * Sets a function to be called when the child indicated by @pid exits, at a
371238cbfaeb7a2ca063ec600de2220ba1c6796647a4Owen Taylor * default priority, #G_PRIORITY_DEFAULT.
371338cbfaeb7a2ca063ec600de2220ba1c6796647a4Owen Taylor *
371438cbfaeb7a2ca063ec600de2220ba1c6796647a4Owen Taylor * Note that on platforms where #GPid must be explicitely closed
371538cbfaeb7a2ca063ec600de2220ba1c6796647a4Owen Taylor * (see g_spawn_close_pid()) @pid must not be closed while the
371638cbfaeb7a2ca063ec600de2220ba1c6796647a4Owen Taylor * source is still active. Typically, you will want to call
37174bc720a4a4971035d97f0ab191e21952dceb9c69Matthias Clasen * g_spawn_close_pid() in the callback function for the source.
37184bc720a4a4971035d97f0ab191e21952dceb9c69Matthias Clasen *
3719540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen * GLib supports only a single callback per process id.
3720540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen *
3721540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen * Return value: the id of event source.
3722540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen *
3723540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen * Since: 2.4
3724540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen **/
3725540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasenguint
3726540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Claseng_child_watch_add_full (gint            priority,
3727540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen			GPid            pid,
3728540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen			GChildWatchFunc function,
3729540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen			gpointer        data,
3730540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen			GDestroyNotify  notify)
3731540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen{
3732540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  GSource *source;
3733540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  guint id;
3734540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen
3735540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  g_return_val_if_fail (function != NULL, 0);
3736540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen
3737540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  source = g_child_watch_source_new (pid);
3738540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen
3739540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  if (priority != G_PRIORITY_DEFAULT)
3740540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen    g_source_set_priority (source, priority);
3741540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen
3742540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  g_source_set_callback (source, (GSourceFunc) function, data, notify);
3743540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  id = g_source_attach (source, NULL);
3744540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  g_source_unref (source);
3745540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen
3746540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  return id;
3747540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen}
3748540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen
3749540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen/**
3750540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen * g_child_watch_add:
3751540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen * @pid:      process id of a child process to watch
3752540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen * @function: function to call
3753540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen * @data:     data to pass to @function
3754540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen *
3755540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen * Sets a function to be called when the child indicated by @pid exits, at a
375638cbfaeb7a2ca063ec600de2220ba1c6796647a4Owen Taylor * default priority, #G_PRIORITY_DEFAULT.
375738cbfaeb7a2ca063ec600de2220ba1c6796647a4Owen Taylor *
375838cbfaeb7a2ca063ec600de2220ba1c6796647a4Owen Taylor * Note that on platforms where #GPid must be explicitely closed
375938cbfaeb7a2ca063ec600de2220ba1c6796647a4Owen Taylor * (see g_spawn_close_pid()) @pid must not be closed while the
376038cbfaeb7a2ca063ec600de2220ba1c6796647a4Owen Taylor * source is still active. Typically, you will want to call
37614bc720a4a4971035d97f0ab191e21952dceb9c69Matthias Clasen * g_spawn_close_pid() in the callback function for the source.
37624bc720a4a4971035d97f0ab191e21952dceb9c69Matthias Clasen *
3763540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen * GLib supports only a single callback per process id.
3764540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen *
3765540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen * Return value: the id of event source.
3766540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen *
3767540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen * Since: 2.4
3768540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen **/
3769540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasenguint
3770540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Claseng_child_watch_add (GPid            pid,
3771540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen		   GChildWatchFunc function,
3772540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen		   gpointer        data)
3773540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen{
3774540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen  return g_child_watch_add_full (G_PRIORITY_DEFAULT, pid, function, data, NULL);
3775540d02ba8b6ad0b1aa0c32f20f8c4f53cb305b7dMatthias Clasen}
3776beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
3777beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
3778beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor/* Idle functions */
3779e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
3780e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorstatic gboolean
3781beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylorg_idle_prepare  (GSource  *source,
37821e5d06d4ceb07ae8ddbd596cb69936fb3807a116Tim Janik		 gint     *timeout)
37831e5d06d4ceb07ae8ddbd596cb69936fb3807a116Tim Janik{
3784beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  *timeout = 0;
3785beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
3786beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  return TRUE;
3787beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor}
3788e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
3789beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylorstatic gboolean
3790beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylorg_idle_check    (GSource  *source)
3791beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor{
3792beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  return TRUE;
3793beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor}
3794e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
3795e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorstatic gboolean
3796e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylorg_idle_dispatch (GSource    *source,
3797beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor		 GSourceFunc callback,
3798e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor		 gpointer    user_data)
3799e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor{
3800e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  if (!callback)
3801e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    {
3802e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      g_warning ("Idle source dispatched without callback\n"
3803e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor		 "You must call g_source_set_callback().");
3804e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor      return FALSE;
3805e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    }
3806e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
3807beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  return callback (user_data);
3808e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor}
3809e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
3810e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor/**
3811a52e2986cd4a2147cfc8d41ae23d98907caaf3a0Matthias Clasen * g_idle_source_new:
3812e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *
3813e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * Creates a new idle source.
3814e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *
3815b51c0d2f7057d64b59a5eef209d5d7b693349cdeOwen Taylor * The source will not initially be associated with any #GMainContext
3816b51c0d2f7057d64b59a5eef209d5d7b693349cdeOwen Taylor * and must be added to one with g_source_attach() before it will be
3817b51c0d2f7057d64b59a5eef209d5d7b693349cdeOwen Taylor * executed. Note that the default priority for idle sources is
3818e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * %G_PRIORITY_DEFAULT_IDLE, as compared to other sources which
3819a52e2986cd4a2147cfc8d41ae23d98907caaf3a0Matthias Clasen * have a default priority of %G_PRIORITY_DEFAULT.
3820e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *
3821e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * Return value: the newly-created idle source
3822e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor **/
3823e2fd4e2bd0589b159f87b491095565d16fac2789Owen TaylorGSource *
3824b51c0d2f7057d64b59a5eef209d5d7b693349cdeOwen Taylorg_idle_source_new (void)
3825b51c0d2f7057d64b59a5eef209d5d7b693349cdeOwen Taylor{
3826b51c0d2f7057d64b59a5eef209d5d7b693349cdeOwen Taylor  GSource *source;
3827b51c0d2f7057d64b59a5eef209d5d7b693349cdeOwen Taylor
3828b51c0d2f7057d64b59a5eef209d5d7b693349cdeOwen Taylor  source = g_source_new (&g_idle_funcs, sizeof (GSource));
3829b51c0d2f7057d64b59a5eef209d5d7b693349cdeOwen Taylor  g_source_set_priority (source, G_PRIORITY_DEFAULT_IDLE);
3830beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
3831beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  return source;
3832e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor}
3833e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
3834e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor/**
3835e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * g_idle_add_full:
3836e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * @priority: the priority of the idle source. Typically this will be in the
3837e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *            range btweeen #G_PRIORITY_DEFAULT_IDLE and #G_PRIORITY_HIGH_IDLE.
3838e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * @function: function to call
3839e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * @data:     data to pass to @function
3840e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * @notify:   function to call when the idle is removed, or %NULL
3841a52e2986cd4a2147cfc8d41ae23d98907caaf3a0Matthias Clasen *
3842e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * Adds a function to be called whenever there are no higher priority
3843e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * events pending.  If the function returns %FALSE it is automatically
3844e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * removed from the list of event sources and will not be called again.
3845e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *
3846beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor * Return value: the id of the event source.
384708425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik **/
3848beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylorguint
3849beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylorg_idle_add_full (gint           priority,
3850beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor		 GSourceFunc    function,
3851beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor		 gpointer       data,
3852e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor		 GDestroyNotify notify)
38531084477e032113aefa2aad6d8c0a7360fafaae91Owen Taylor{
3854e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  GSource *source;
385508425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik  guint id;
3856beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
3857e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  g_return_val_if_fail (function != NULL, 0);
3858e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
3859b51c0d2f7057d64b59a5eef209d5d7b693349cdeOwen Taylor  source = g_idle_source_new ();
3860e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
3861e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  if (priority != G_PRIORITY_DEFAULT_IDLE)
3862e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor    g_source_set_priority (source, priority);
38631084477e032113aefa2aad6d8c0a7360fafaae91Owen Taylor
38641084477e032113aefa2aad6d8c0a7360fafaae91Owen Taylor  g_source_set_callback (source, function, data, notify);
38651084477e032113aefa2aad6d8c0a7360fafaae91Owen Taylor  id = g_source_attach (source, NULL);
38661084477e032113aefa2aad6d8c0a7360fafaae91Owen Taylor  g_source_unref (source);
3867beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
3868beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  return id;
3869e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor}
3870e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
3871e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor/**
3872e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * g_idle_add:
3873e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * @function: function to call
3874e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * @data: data to pass to @function.
3875e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *
3876e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * Adds a function to be called whenever there are no higher priority
3877a52e2986cd4a2147cfc8d41ae23d98907caaf3a0Matthias Clasen * events pending to the default main loop. The function is given the
3878e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * default idle priority, #G_PRIORITY_DEFAULT_IDLE.  If the function
3879e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * returns %FALSE it is automatically removed from the list of event
3880e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * sources and will not be called again.
3881e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *
3882beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor * Return value: the id of the event source.
3883beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor **/
3884beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylorguint
3885beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylorg_idle_add (GSourceFunc    function,
38867f237f6fcd00ad9888ef459ccdc8d02e12c311fdOwen Taylor	    gpointer       data)
3887beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor{
388808425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik  return g_idle_add_full (G_PRIORITY_DEFAULT_IDLE, function, data, NULL);
3889e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor}
3890e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor
3891e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor/**
3892e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * g_idle_remove_by_data:
3893e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * @data: the data for the idle source's callback.
3894e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *
3895e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor * Removes the idle function with the given data.
3896e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor *
389708425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik * Return value: %TRUE if an idle source was found and removed.
389808425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik **/
389908425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janikgboolean
3900b4c3107c7a1dc5dd9e8050ed06f24d6be408e840Owen Taylorg_idle_remove_by_data (gpointer data)
390108425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik{
3902e2fd4e2bd0589b159f87b491095565d16fac2789Owen Taylor  return g_source_remove_by_funcs_user_data (&g_idle_funcs, data);
3903}
3904
3905