gmain.c revision f26256fe182bc1249d3058d9f18402d0ac26974c
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
8beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor * modify it under the terms of the GNU Library 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
15beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor * Library General Public License for more details.
16beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor *
17beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor * You should have received a copy of the GNU Library 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
23931ea952650b013b834041b91b0c37a748ffd449Owen Taylor/*
24931ea952650b013b834041b91b0c37a748ffd449Owen Taylor * MT safe
25931ea952650b013b834041b91b0c37a748ffd449Owen Taylor */
26931ea952650b013b834041b91b0c37a748ffd449Owen Taylor
27f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist#include "config.h"
28f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist
29beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor#include "glib.h"
30e0153773a69fe64b2643c0d74c40af2dee7eb38fTim Janik#include <sys/types.h>
31f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist#include <time.h>
32f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist#ifdef HAVE_SYS_TIME_H
33beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor#include <sys/time.h>
3408425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik#endif /* HAVE_SYS_TIME_H */
3508425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik#ifdef GLIB_HAVE_SYS_POLL_H
36250d1a07bb4687135793fa61bafe79f100b50e66Tim Janik#  include <sys/poll.h>
37250d1a07bb4687135793fa61bafe79f100b50e66Tim Janik#  undef events	 /* AIX 4.1.5 & 4.3.2 define this for SVR3,4 compatibility */
38250d1a07bb4687135793fa61bafe79f100b50e66Tim Janik#  undef revents /* AIX 4.1.5 & 4.3.2 define this for SVR3,4 compatibility */
3908425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik#endif /* GLIB_HAVE_SYS_POLL_H */
40f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist#ifdef HAVE_UNISTD_H
41beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor#include <unistd.h>
4208425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik#endif /* HAVE_UNISTD_H */
43931ea952650b013b834041b91b0c37a748ffd449Owen Taylor#include <errno.h>
44f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist
45f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist#ifdef NATIVE_WIN32
46f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist#define STRICT
47f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist#include <windows.h>
4808425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik#endif /* NATIVE_WIN32 */
49f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist
50f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist#ifdef _MSC_VER
51f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist#include <fcntl.h>
52f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist#include <io.h>
5308425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik#endif /* _MSC_VER */
54beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
55beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor/* Types */
56beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
57beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylortypedef struct _GTimeoutData GTimeoutData;
58beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylortypedef struct _GSource GSource;
59beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylortypedef struct _GPollRec GPollRec;
60beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
61a62ebb0e757c972ef4bc5892d7e3e673c6426015Tim Janiktypedef enum
62a62ebb0e757c972ef4bc5892d7e3e673c6426015Tim Janik{
63beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  G_SOURCE_READY = 1 << G_HOOK_FLAG_USER_SHIFT,
64beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  G_SOURCE_CAN_RECURSE = 1 << (G_HOOK_FLAG_USER_SHIFT + 1)
65beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor} GSourceFlags;
66beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
67a62ebb0e757c972ef4bc5892d7e3e673c6426015Tim Janikstruct _GSource
68a62ebb0e757c972ef4bc5892d7e3e673c6426015Tim Janik{
69beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  GHook hook;
70beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  gint priority;
71beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  gpointer source_data;
72beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor};
73beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
74a62ebb0e757c972ef4bc5892d7e3e673c6426015Tim Janikstruct _GMainLoop
75a62ebb0e757c972ef4bc5892d7e3e673c6426015Tim Janik{
768be41eae4d0077069ecf77a8904b5f624d5ea5ffTim Janik  gboolean is_running;
77beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor};
78beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
79a62ebb0e757c972ef4bc5892d7e3e673c6426015Tim Janikstruct _GTimeoutData
80a62ebb0e757c972ef4bc5892d7e3e673c6426015Tim Janik{
81beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  GTimeVal    expiration;
82beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  gint        interval;
83beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  GSourceFunc callback;
84beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor};
85beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
86a62ebb0e757c972ef4bc5892d7e3e673c6426015Tim Janikstruct _GPollRec
87a62ebb0e757c972ef4bc5892d7e3e673c6426015Tim Janik{
88beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  gint priority;
89beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  GPollFD *fd;
90beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  GPollRec *next;
91beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor};
92beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
93beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor/* Forward declarations */
94beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
95dc602866312bff134f4d827190f5c24934970e19Owen Taylorstatic gint     g_source_compare          (GHook      *a,
96dc602866312bff134f4d827190f5c24934970e19Owen Taylor					   GHook      *b);
9708425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janikstatic void     g_source_destroy_func     (GHookList  *hook_list,
98dc602866312bff134f4d827190f5c24934970e19Owen Taylor					   GHook      *hook);
992e57a3643891f41c238c5ee3793afcd8706a4060Sebastian Wilhelmistatic void     g_main_poll               (gint      timeout,
1002e57a3643891f41c238c5ee3793afcd8706a4060Sebastian Wilhelmi					   gboolean  use_priority,
1012e57a3643891f41c238c5ee3793afcd8706a4060Sebastian Wilhelmi					   gint      priority);
102bb19315fbdb4ae54704778e6dec7b7319c95419aOwen Taylorstatic void     g_main_add_poll_unlocked  (gint      priority,
1032e57a3643891f41c238c5ee3793afcd8706a4060Sebastian Wilhelmi					   GPollFD  *fd);
104931ea952650b013b834041b91b0c37a748ffd449Owen Taylor
105beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylorstatic gboolean g_timeout_prepare      (gpointer  source_data,
106beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor					GTimeVal *current_time,
107beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor					gint     *timeout);
108beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylorstatic gboolean g_timeout_check        (gpointer  source_data,
109beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor					GTimeVal *current_time);
110beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylorstatic gboolean g_timeout_dispatch     (gpointer  source_data,
111beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor					GTimeVal *current_time,
112beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor					gpointer  user_data);
113beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylorstatic gboolean g_idle_prepare         (gpointer  source_data,
114beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor					GTimeVal *current_time,
115beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor					gint     *timeout);
116beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylorstatic gboolean g_idle_check           (gpointer  source_data,
117beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor					GTimeVal *current_time);
118beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylorstatic gboolean g_idle_dispatch        (gpointer  source_data,
119beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor					GTimeVal *current_time,
120beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor					gpointer  user_data);
121beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
122beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor/* Data */
123beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
124beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylorstatic GSList *pending_dispatches = NULL;
125beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylorstatic GHookList source_list = { 0 };
12608425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janikstatic gint in_check_or_prepare = 0;
127beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
128931ea952650b013b834041b91b0c37a748ffd449Owen Taylor/* The following lock is used for both the list of sources
129931ea952650b013b834041b91b0c37a748ffd449Owen Taylor * and the list of poll records
130931ea952650b013b834041b91b0c37a748ffd449Owen Taylor */
131b2e318ff3ecc50d72121a4e8561442a6d79a7a84Tim JanikG_LOCK_DECLARE_STATIC (main_loop);
132931ea952650b013b834041b91b0c37a748ffd449Owen Taylor
13308425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janikstatic GSourceFuncs timeout_funcs =
13408425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik{
135beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  g_timeout_prepare,
136beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  g_timeout_check,
137beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  g_timeout_dispatch,
13808425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik  g_free,
139beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor};
140beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
14108425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janikstatic GSourceFuncs idle_funcs =
14208425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik{
143beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  g_idle_prepare,
144beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  g_idle_check,
145beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  g_idle_dispatch,
14608425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik  NULL,
147beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor};
148beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
149931ea952650b013b834041b91b0c37a748ffd449Owen Taylorstatic GPollRec *poll_records = NULL;
150931ea952650b013b834041b91b0c37a748ffd449Owen Taylorstatic GPollRec *poll_free_list = NULL;
151931ea952650b013b834041b91b0c37a748ffd449Owen Taylorstatic GMemChunk *poll_chunk;
152931ea952650b013b834041b91b0c37a748ffd449Owen Taylorstatic guint n_poll_records = 0;
153931ea952650b013b834041b91b0c37a748ffd449Owen Taylor
154f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist#ifdef G_THREADS_ENABLED
155f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist#ifndef NATIVE_WIN32
156931ea952650b013b834041b91b0c37a748ffd449Owen Taylor/* this pipe is used to wake up the main loop when a source is added.
157931ea952650b013b834041b91b0c37a748ffd449Owen Taylor */
158931ea952650b013b834041b91b0c37a748ffd449Owen Taylorstatic gint wake_up_pipe[2] = { -1, -1 };
15908425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik#else /* NATIVE_WIN32 */
160f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqviststatic HANDLE wake_up_semaphore = NULL;
16108425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik#endif /* NATIVE_WIN32 */
162931ea952650b013b834041b91b0c37a748ffd449Owen Taylorstatic GPollFD wake_up_rec;
163931ea952650b013b834041b91b0c37a748ffd449Owen Taylorstatic gboolean poll_waiting = FALSE;
16408425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik#endif /* G_THREADS_ENABLED */
165931ea952650b013b834041b91b0c37a748ffd449Owen Taylor
166beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor#ifdef HAVE_POLL
167a62ebb0e757c972ef4bc5892d7e3e673c6426015Tim Janikstatic GPollFunc poll_func = (GPollFunc) poll;
168a62ebb0e757c972ef4bc5892d7e3e673c6426015Tim Janik#else	/* !HAVE_POLL */
169f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist#ifdef NATIVE_WIN32
170f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist
171f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqviststatic gint
172f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvistg_poll (GPollFD *fds, guint nfds, gint timeout)
173f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist{
174f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist  HANDLE handles[MAXIMUM_WAIT_OBJECTS];
175f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist  GPollFD *f;
176f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist  DWORD ready;
177f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist  MSG msg;
178f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist  UINT timer;
179f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist  LONG prevcnt;
180f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist  gint poll_msgs = -1;
181f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist  gint nhandles = 0;
182f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist
183f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist  for (f = fds; f < &fds[nfds]; ++f)
184f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist    if (f->fd >= 0)
185f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist      {
186f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist	if (f->events & G_IO_IN)
187f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist	  if (f->fd == G_WIN32_MSG_HANDLE)
188f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist	    poll_msgs = f - fds;
189f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist	  else
190f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist	    {
191f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist	      /* g_print ("g_poll: waiting for handle %#x\n", f->fd); */
192f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist	      handles[nhandles++] = (HANDLE) f->fd;
193f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist	    }
194f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist      }
195f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist
196f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist  if (timeout == -1)
197f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist    timeout = INFINITE;
198f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist
199f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist  if (poll_msgs >= 0)
200f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist    {
201f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist      /* Waiting for messages, and maybe events */
202f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist      if (nhandles == 0)
203f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist	{
204f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist	  if (timeout == INFINITE)
205f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist	    {
206f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist	      /* Waiting just for messages, infinite timeout
207f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist	       * -> Use PeekMessage, then WaitMessage
208f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist	       */
209f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist	      /* g_print ("WaitMessage, PeekMessage\n"); */
210f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist	      if (PeekMessage (&msg, NULL, 0, 0, PM_NOREMOVE))
211f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist		ready = WAIT_OBJECT_0;
212f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist	      else if (!WaitMessage ())
213f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist		g_warning ("g_poll: WaitMessage failed");
214f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist	      ready = WAIT_OBJECT_0;
215f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist	    }
216f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist	  else if (timeout == 0)
217f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist	    {
218f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist	      /* Waiting just for messages, zero timeout
219f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist	       * -> Use PeekMessage
220f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist	       */
221f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist	      /* g_print ("PeekMessage\n"); */
222f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist	      if (PeekMessage (&msg, NULL, 0, 0, PM_NOREMOVE))
223f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist		ready = WAIT_OBJECT_0;
224f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist	      else
225f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist		ready = WAIT_TIMEOUT;
226f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist	    }
227f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist	  else
228f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist	    {
229f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist	      /* Waiting just for messages, some timeout
230f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist	       * -> First try PeekMessage, then set a timer, wait for message,
231f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist	       * kill timer, use PeekMessage
232f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist	       */
233f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist	      /* g_print ("PeekMessage\n"); */
234f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist	      if (PeekMessage (&msg, NULL, 0, 0, PM_NOREMOVE))
235f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist		ready = WAIT_OBJECT_0;
236f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist	      else if ((timer = SetTimer (NULL, 0, timeout, NULL)) == 0)
237f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist		g_warning ("g_poll: SetTimer failed");
238f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist	      else
239f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist		{
240f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist		  /* g_print ("WaitMessage\n"); */
241f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist		  WaitMessage ();
242f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist		  KillTimer (NULL, timer);
243f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist		  if (PeekMessage (&msg, NULL, 0, 0, PM_NOREMOVE))
244f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist		    ready = WAIT_OBJECT_0;
245f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist		  else
246f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist		    ready = WAIT_TIMEOUT;
247f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist		}
248f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist	    }
249f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist	}
250f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist      else
251f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist	{
252f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist	  /* Wait for either message or event
253f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist	   * -> Use MsgWaitForMultipleObjects
254f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist	   */
255f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist	  /* g_print ("MsgWaitForMultipleObjects(%d, %d)\n", nhandles, timeout); */
256f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist	  ready = MsgWaitForMultipleObjects (nhandles, handles, FALSE,
257f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist					     timeout, QS_ALLINPUT);
258f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist	  /* g_print("=%d\n", ready); */
259f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist	  if (ready == WAIT_FAILED)
260f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist	    g_warning ("g_poll: MsgWaitForMultipleObjects failed");
261f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist	}
262f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist    }
263f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist  else if (nhandles == 0)
264f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist    {
265f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist      /* Wait for nothing (huh?) */
266f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist      return 0;
267f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist    }
268f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist  else
269f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist    {
270f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist      /* Wait for just events
271f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist       * -> Use WaitForMultipleObjects
272f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist       */
273f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist      /* g_print ("WaitForMultipleObjects(%d, %d)\n", nhandles, timeout); */
274f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist      ready = WaitForMultipleObjects (nhandles, handles, FALSE, timeout);
275f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist      /* g_print("=%d\n", ready); */
276f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist      if (ready == WAIT_FAILED)
277f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist	g_warning ("g_poll: WaitForMultipleObjects failed");
278f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist    }
279f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist
280f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist  for (f = fds; f < &fds[nfds]; ++f)
281f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist    f->revents = 0;
282f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist
283f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist  if (ready == WAIT_FAILED)
284f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist    return -1;
285f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist  else if (poll_msgs >= 0 && ready == WAIT_OBJECT_0 + nhandles)
286f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist    {
287f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist      fds[poll_msgs].revents |= G_IO_IN;
288f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist    }
289f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist  else if (ready >= WAIT_OBJECT_0 && ready < WAIT_OBJECT_0 + nhandles)
290f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist    for (f = fds; f < &fds[nfds]; ++f)
291f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist      {
292f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist	if ((f->events & G_IO_IN)
293f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist	    && f->fd == (gint) handles[ready - WAIT_OBJECT_0])
294f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist	  {
295f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist	    f->revents |= G_IO_IN;
296f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist	    /* g_print ("event %#x\n", f->fd); */
297f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist	    ResetEvent ((HANDLE) f->fd);
298f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist	  }
299f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist      }
300f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist
301f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist  if (ready == WAIT_TIMEOUT)
302f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist    return 0;
303f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist  else
304f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist    return 1;
305f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist}
306f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist
307f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist#else  /* !NATIVE_WIN32 */
308beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
309beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor/* The following implementation of poll() comes from the GNU C Library.
310beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor * Copyright (C) 1994, 1996, 1997 Free Software Foundation, Inc.
311beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor */
312beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
313738864a1a758b2421211e4ecf1ce6102842428eaManish Singh#include <string.h> /* for bzero on BSD systems */
314738864a1a758b2421211e4ecf1ce6102842428eaManish Singh
315beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor#ifdef HAVE_SYS_SELECT_H
316beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor#include <sys/select.h>
317beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor#endif /* HAVE_SYS_SELECT_H_ */
318beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
319beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor#ifndef NO_FD_SET
320beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor#  define SELECT_MASK fd_set
32108425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik#else /* !NO_FD_SET */
322beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor#  ifndef _AIX
323beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylortypedef long fd_mask;
32408425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik#  endif /* _AIX */
32508425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik#  ifdef _IBMR2
326beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor#    define SELECT_MASK void
32708425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik#  else /* !_IBMR2 */
328beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor#    define SELECT_MASK int
32908425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik#  endif /* !_IBMR2 */
33008425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik#endif /* !NO_FD_SET */
331beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
332beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylorstatic gint
33308425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janikg_poll (GPollFD *fds,
33408425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik	guint    nfds,
33508425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik	gint     timeout)
336beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor{
337beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  struct timeval tv;
338beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  SELECT_MASK rset, wset, xset;
339beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  GPollFD *f;
340beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  int ready;
341beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  int maxfd = 0;
342beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
343beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  FD_ZERO (&rset);
344beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  FD_ZERO (&wset);
345beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  FD_ZERO (&xset);
346beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
347beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  for (f = fds; f < &fds[nfds]; ++f)
348beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor    if (f->fd >= 0)
349beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor      {
350beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor	if (f->events & G_IO_IN)
351beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor	  FD_SET (f->fd, &rset);
352beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor	if (f->events & G_IO_OUT)
353beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor	  FD_SET (f->fd, &wset);
354beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor	if (f->events & G_IO_PRI)
355beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor	  FD_SET (f->fd, &xset);
356738864a1a758b2421211e4ecf1ce6102842428eaManish Singh	if (f->fd > maxfd && (f->events & (G_IO_IN|G_IO_OUT|G_IO_PRI)))
357beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor	  maxfd = f->fd;
358beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor      }
359beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
360beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  tv.tv_sec = timeout / 1000;
361beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  tv.tv_usec = (timeout % 1000) * 1000;
362beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
363beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  ready = select (maxfd + 1, &rset, &wset, &xset,
364beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor		  timeout == -1 ? NULL : &tv);
365beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  if (ready > 0)
366beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor    for (f = fds; f < &fds[nfds]; ++f)
367beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor      {
368beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor	f->revents = 0;
369beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor	if (f->fd >= 0)
370beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor	  {
371beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor	    if (FD_ISSET (f->fd, &rset))
372beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor	      f->revents |= G_IO_IN;
373beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor	    if (FD_ISSET (f->fd, &wset))
374beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor	      f->revents |= G_IO_OUT;
375beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor	    if (FD_ISSET (f->fd, &xset))
376beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor	      f->revents |= G_IO_PRI;
377beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor	  }
378beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor      }
379beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
380beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  return ready;
381beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor}
38208425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik
383f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist#endif /* !NATIVE_WIN32 */
384f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist
385beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylorstatic GPollFunc poll_func = g_poll;
386a62ebb0e757c972ef4bc5892d7e3e673c6426015Tim Janik#endif	/* !HAVE_POLL */
387beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
388beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor/* Hooks for adding to the main loop */
389beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
390beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor/* Use knowledge of insert_sorted algorithm here to make
391beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor * sure we insert at the end of equal priority items
392beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor */
393beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylorstatic gint
394a62ebb0e757c972ef4bc5892d7e3e673c6426015Tim Janikg_source_compare (GHook *a,
395a62ebb0e757c972ef4bc5892d7e3e673c6426015Tim Janik		  GHook *b)
396beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor{
397beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  GSource *source_a = (GSource *)a;
398beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  GSource *source_b = (GSource *)b;
399beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
400beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  return (source_a->priority < source_b->priority) ? -1 : 1;
401beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor}
402beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
4035c2fb3762f9174d78213b2b2d8934883919b4f67Tim Janik/* HOLDS: main_loop lock */
404dc602866312bff134f4d827190f5c24934970e19Owen Taylorstatic void
40508425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janikg_source_destroy_func (GHookList *hook_list,
40608425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik		       GHook     *hook)
407dc602866312bff134f4d827190f5c24934970e19Owen Taylor{
40808425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik  GSource *source = (GSource*) hook;
40908425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik  GDestroyNotify destroy;
410dc602866312bff134f4d827190f5c24934970e19Owen Taylor
41108425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik  G_UNLOCK (main_loop);
41208425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik
41308425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik  destroy = hook->destroy;
41408425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik  if (destroy)
41508425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik    destroy (hook->data);
41608425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik
41708425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik  destroy = ((GSourceFuncs*) hook->func)->destroy;
41808425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik  if (destroy)
41908425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik    destroy (source->source_data);
42008425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik
42108425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik  G_LOCK (main_loop);
422dc602866312bff134f4d827190f5c24934970e19Owen Taylor}
423dc602866312bff134f4d827190f5c24934970e19Owen Taylor
424beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylorguint
425beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylorg_source_add (gint           priority,
426beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor	      gboolean       can_recurse,
427beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor	      GSourceFuncs  *funcs,
428beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor	      gpointer       source_data,
429beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor	      gpointer       user_data,
430beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor	      GDestroyNotify notify)
431beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor{
432931ea952650b013b834041b91b0c37a748ffd449Owen Taylor  guint return_val;
433beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  GSource *source;
434beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
435b2e318ff3ecc50d72121a4e8561442a6d79a7a84Tim Janik  G_LOCK (main_loop);
436931ea952650b013b834041b91b0c37a748ffd449Owen Taylor
437beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  if (!source_list.is_setup)
4385c2fb3762f9174d78213b2b2d8934883919b4f67Tim Janik    {
4395c2fb3762f9174d78213b2b2d8934883919b4f67Tim Janik      g_hook_list_init (&source_list, sizeof (GSource));
440beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
4415c2fb3762f9174d78213b2b2d8934883919b4f67Tim Janik      source_list.hook_destroy = G_HOOK_DEFERRED_DESTROY;
4425c2fb3762f9174d78213b2b2d8934883919b4f67Tim Janik      source_list.hook_free = g_source_destroy_func;
4435c2fb3762f9174d78213b2b2d8934883919b4f67Tim Janik    }
444dc602866312bff134f4d827190f5c24934970e19Owen Taylor
4455c2fb3762f9174d78213b2b2d8934883919b4f67Tim Janik  source = (GSource*) g_hook_alloc (&source_list);
446beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  source->priority = priority;
447beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  source->source_data = source_data;
448beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  source->hook.func = funcs;
449beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  source->hook.data = user_data;
450beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  source->hook.destroy = notify;
451beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
452beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  g_hook_insert_sorted (&source_list,
453beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor			(GHook *)source,
454beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor			g_source_compare);
455beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
456beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  if (can_recurse)
457beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor    source->hook.flags |= G_SOURCE_CAN_RECURSE;
458beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
459931ea952650b013b834041b91b0c37a748ffd449Owen Taylor  return_val = source->hook.hook_id;
460931ea952650b013b834041b91b0c37a748ffd449Owen Taylor
461f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist#ifdef G_THREADS_ENABLED
462931ea952650b013b834041b91b0c37a748ffd449Owen Taylor  /* Now wake up the main loop if it is waiting in the poll() */
463931ea952650b013b834041b91b0c37a748ffd449Owen Taylor
464931ea952650b013b834041b91b0c37a748ffd449Owen Taylor  if (poll_waiting)
465931ea952650b013b834041b91b0c37a748ffd449Owen Taylor    {
466931ea952650b013b834041b91b0c37a748ffd449Owen Taylor      poll_waiting = FALSE;
467f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist#ifndef NATIVE_WIN32
468931ea952650b013b834041b91b0c37a748ffd449Owen Taylor      write (wake_up_pipe[1], "A", 1);
469f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist#else
470f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist      ReleaseSemaphore (wake_up_semaphore, 1, NULL);
471f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist#endif
472931ea952650b013b834041b91b0c37a748ffd449Owen Taylor    }
473f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist#endif
474b2e318ff3ecc50d72121a4e8561442a6d79a7a84Tim Janik  G_UNLOCK (main_loop);
475931ea952650b013b834041b91b0c37a748ffd449Owen Taylor
476931ea952650b013b834041b91b0c37a748ffd449Owen Taylor  return return_val;
477beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor}
478beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
47908425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janikgboolean
480beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylorg_source_remove (guint tag)
481beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor{
482931ea952650b013b834041b91b0c37a748ffd449Owen Taylor  GHook *hook;
483931ea952650b013b834041b91b0c37a748ffd449Owen Taylor
48408425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik  g_return_val_if_fail (tag > 0, FALSE);
48508425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik
486b2e318ff3ecc50d72121a4e8561442a6d79a7a84Tim Janik  G_LOCK (main_loop);
487931ea952650b013b834041b91b0c37a748ffd449Owen Taylor
488931ea952650b013b834041b91b0c37a748ffd449Owen Taylor  hook = g_hook_get (&source_list, tag);
489beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  if (hook)
490dc602866312bff134f4d827190f5c24934970e19Owen Taylor    g_hook_destroy_link (&source_list, hook);
491931ea952650b013b834041b91b0c37a748ffd449Owen Taylor
492b2e318ff3ecc50d72121a4e8561442a6d79a7a84Tim Janik  G_UNLOCK (main_loop);
49308425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik
49408425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik  return hook != NULL;
495beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor}
496beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
49708425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janikgboolean
498beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylorg_source_remove_by_user_data (gpointer user_data)
499beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor{
500931ea952650b013b834041b91b0c37a748ffd449Owen Taylor  GHook *hook;
501931ea952650b013b834041b91b0c37a748ffd449Owen Taylor
502b2e318ff3ecc50d72121a4e8561442a6d79a7a84Tim Janik  G_LOCK (main_loop);
503931ea952650b013b834041b91b0c37a748ffd449Owen Taylor
504931ea952650b013b834041b91b0c37a748ffd449Owen Taylor  hook = g_hook_find_data (&source_list, TRUE, user_data);
505beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  if (hook)
506dc602866312bff134f4d827190f5c24934970e19Owen Taylor    g_hook_destroy_link (&source_list, hook);
507931ea952650b013b834041b91b0c37a748ffd449Owen Taylor
508b2e318ff3ecc50d72121a4e8561442a6d79a7a84Tim Janik  G_UNLOCK (main_loop);
50908425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik
51008425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik  return hook != NULL;
511beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor}
512beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
513beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylorstatic gboolean
514beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylorg_source_find_source_data (GHook	*hook,
515beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor			   gpointer	 data)
516beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor{
517beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  GSource *source = (GSource *)hook;
518a62ebb0e757c972ef4bc5892d7e3e673c6426015Tim Janik
519beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  return (source->source_data == data);
520beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor}
521beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
52208425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janikgboolean
523beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylorg_source_remove_by_source_data (gpointer source_data)
524beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor{
525931ea952650b013b834041b91b0c37a748ffd449Owen Taylor  GHook *hook;
526931ea952650b013b834041b91b0c37a748ffd449Owen Taylor
527b2e318ff3ecc50d72121a4e8561442a6d79a7a84Tim Janik  G_LOCK (main_loop);
528931ea952650b013b834041b91b0c37a748ffd449Owen Taylor
529931ea952650b013b834041b91b0c37a748ffd449Owen Taylor  hook = g_hook_find (&source_list, TRUE,
530a62ebb0e757c972ef4bc5892d7e3e673c6426015Tim Janik		      g_source_find_source_data, source_data);
531beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  if (hook)
532dc602866312bff134f4d827190f5c24934970e19Owen Taylor    g_hook_destroy_link (&source_list, hook);
533931ea952650b013b834041b91b0c37a748ffd449Owen Taylor
534b2e318ff3ecc50d72121a4e8561442a6d79a7a84Tim Janik  G_UNLOCK (main_loop);
53508425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik
53608425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik  return hook != NULL;
53708425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik}
53808425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik
53908425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janikstatic gboolean
54008425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janikg_source_find_funcs_user_data (GHook   *hook,
54108425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik			       gpointer data)
54208425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik{
54308425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik  gpointer *d = data;
54408425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik
54508425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik  return hook->func == d[0] && hook->data == d[1];
54608425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik}
54708425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik
54808425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janikgboolean
54908425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janikg_source_remove_by_funcs_user_data (GSourceFuncs *funcs,
55008425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik				    gpointer      user_data)
55108425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik{
55208425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik  gpointer d[2];
55308425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik  GHook *hook;
55408425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik
55508425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik  g_return_val_if_fail (funcs != NULL, FALSE);
55608425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik
55708425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik  G_LOCK (main_loop);
55808425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik
55908425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik  d[0] = funcs;
56008425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik  d[1] = user_data;
56108425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik
56208425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik  hook = g_hook_find (&source_list, TRUE,
56308425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik		      g_source_find_funcs_user_data, d);
56408425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik  if (hook)
56508425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik    g_hook_destroy_link (&source_list, hook);
56608425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik
56708425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik  G_UNLOCK (main_loop);
56808425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik
56908425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik  return hook != NULL;
570beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor}
571beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
572a62ebb0e757c972ef4bc5892d7e3e673c6426015Tim Janikvoid
573a62ebb0e757c972ef4bc5892d7e3e673c6426015Tim Janikg_get_current_time (GTimeVal *result)
574beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor{
575f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist#ifndef _MSC_VER
5764277349743343e0e2b608e8aa11e5bdb9f5acf1fGeorge Lebl  struct timeval r;
577a62ebb0e757c972ef4bc5892d7e3e673c6426015Tim Janik  g_return_if_fail (result != NULL);
578a62ebb0e757c972ef4bc5892d7e3e673c6426015Tim Janik
5794277349743343e0e2b608e8aa11e5bdb9f5acf1fGeorge Lebl  /*this is required on alpha, there the timeval structs are int's
5804277349743343e0e2b608e8aa11e5bdb9f5acf1fGeorge Lebl    not longs and a cast only would fail horribly*/
5814277349743343e0e2b608e8aa11e5bdb9f5acf1fGeorge Lebl  gettimeofday (&r, NULL);
5824277349743343e0e2b608e8aa11e5bdb9f5acf1fGeorge Lebl  result->tv_sec = r.tv_sec;
5834277349743343e0e2b608e8aa11e5bdb9f5acf1fGeorge Lebl  result->tv_usec = r.tv_usec;
584f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist#else
585f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist  /* Avoid calling time() except for the first time.
586f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist   * GetTickCount() should be pretty fast and low-level?
587f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist   * I could also use ftime() but it seems unnecessarily overheady.
588f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist   */
589f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist  static DWORD start_tick = 0;
590f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist  static time_t start_time;
591f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist  DWORD tick;
592f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist  time_t t;
593f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist
594f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist  g_return_if_fail (result != NULL);
595f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist
596f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist  if (start_tick == 0)
597f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist    {
598f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist      start_tick = GetTickCount ();
599f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist      time (&start_time);
600f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist    }
601f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist
602f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist  tick = GetTickCount ();
603f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist
604f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist  result->tv_sec = (tick - start_tick) / 1000 + start_time;
605f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist  result->tv_usec = ((tick - start_tick) % 1000) * 1000;
606f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist#endif
607beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor}
608beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
609beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor/* Running the main loop */
610beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
611931ea952650b013b834041b91b0c37a748ffd449Owen Taylor/* HOLDS: main_loop_lock */
612beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylorstatic void
613beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylorg_main_dispatch (GTimeVal *current_time)
614beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor{
615beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  while (pending_dispatches != NULL)
616beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor    {
617beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor      gboolean need_destroy;
618beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor      GSource *source = pending_dispatches->data;
619beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor      GSList *tmp_list;
620beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
621beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor      tmp_list = pending_dispatches;
622beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor      pending_dispatches = g_slist_remove_link (pending_dispatches, pending_dispatches);
623beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor      g_slist_free_1 (tmp_list);
624beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
625beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor      if (G_HOOK_IS_VALID (source))
626beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor	{
6278be41eae4d0077069ecf77a8904b5f624d5ea5ffTim Janik	  gboolean was_in_call;
628931ea952650b013b834041b91b0c37a748ffd449Owen Taylor	  gpointer hook_data = source->hook.data;
629931ea952650b013b834041b91b0c37a748ffd449Owen Taylor	  gpointer source_data = source->source_data;
630a62ebb0e757c972ef4bc5892d7e3e673c6426015Tim Janik	  gboolean (*dispatch) (gpointer,
631a62ebb0e757c972ef4bc5892d7e3e673c6426015Tim Janik				GTimeVal *,
632a62ebb0e757c972ef4bc5892d7e3e673c6426015Tim Janik				gpointer);
633931ea952650b013b834041b91b0c37a748ffd449Owen Taylor
634a62ebb0e757c972ef4bc5892d7e3e673c6426015Tim Janik	  dispatch = ((GSourceFuncs *) source->hook.func)->dispatch;
635931ea952650b013b834041b91b0c37a748ffd449Owen Taylor
6368be41eae4d0077069ecf77a8904b5f624d5ea5ffTim Janik	  was_in_call = G_HOOK_IN_CALL (source);
637beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor	  source->hook.flags |= G_HOOK_FLAG_IN_CALL;
638931ea952650b013b834041b91b0c37a748ffd449Owen Taylor
639b2e318ff3ecc50d72121a4e8561442a6d79a7a84Tim Janik	  G_UNLOCK (main_loop);
640a62ebb0e757c972ef4bc5892d7e3e673c6426015Tim Janik	  need_destroy = ! dispatch (source_data,
641a62ebb0e757c972ef4bc5892d7e3e673c6426015Tim Janik				     current_time,
642a62ebb0e757c972ef4bc5892d7e3e673c6426015Tim Janik				     hook_data);
643b2e318ff3ecc50d72121a4e8561442a6d79a7a84Tim Janik	  G_LOCK (main_loop);
644931ea952650b013b834041b91b0c37a748ffd449Owen Taylor
6458be41eae4d0077069ecf77a8904b5f624d5ea5ffTim Janik	  if (!was_in_call)
6468be41eae4d0077069ecf77a8904b5f624d5ea5ffTim Janik	    source->hook.flags &= ~G_HOOK_FLAG_IN_CALL;
647beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
6488be41eae4d0077069ecf77a8904b5f624d5ea5ffTim Janik	  if (need_destroy && G_HOOK_IS_VALID (source))
649dc602866312bff134f4d827190f5c24934970e19Owen Taylor	    g_hook_destroy_link (&source_list, (GHook *) source);
650beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor	}
651beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
65200e064d2af719c4a630156cef361de6365342aaeTim Janik      g_hook_unref (&source_list, (GHook*) source);
653beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor    }
654beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor}
655beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
6568be41eae4d0077069ecf77a8904b5f624d5ea5ffTim Janik/* g_main_iterate () runs a single iteration of the mainloop, or,
6578be41eae4d0077069ecf77a8904b5f624d5ea5ffTim Janik * if !dispatch checks to see if any sources need dispatching.
6588be41eae4d0077069ecf77a8904b5f624d5ea5ffTim Janik * basic algorithm for dispatch=TRUE:
6598be41eae4d0077069ecf77a8904b5f624d5ea5ffTim Janik *
6608be41eae4d0077069ecf77a8904b5f624d5ea5ffTim Janik * 1) while the list of currently pending sources is non-empty,
6618be41eae4d0077069ecf77a8904b5f624d5ea5ffTim Janik *    we call (*dispatch) on those that are !IN_CALL or can_recurse,
6628be41eae4d0077069ecf77a8904b5f624d5ea5ffTim Janik *    removing sources from the list after each returns.
6638be41eae4d0077069ecf77a8904b5f624d5ea5ffTim Janik *    the return value of (*dispatch) determines whether the source
6648be41eae4d0077069ecf77a8904b5f624d5ea5ffTim Janik *    itself is kept alive.
6658be41eae4d0077069ecf77a8904b5f624d5ea5ffTim Janik *
6668be41eae4d0077069ecf77a8904b5f624d5ea5ffTim Janik * 2) call (*prepare) for sources that are not yet SOURCE_READY and
6678be41eae4d0077069ecf77a8904b5f624d5ea5ffTim Janik *    are !IN_CALL or can_recurse. a return value of TRUE determines
6688be41eae4d0077069ecf77a8904b5f624d5ea5ffTim Janik *    that the source would like to be dispatched immediatedly, it
6698be41eae4d0077069ecf77a8904b5f624d5ea5ffTim Janik *    is then flagged as SOURCE_READY.
6708be41eae4d0077069ecf77a8904b5f624d5ea5ffTim Janik *
6718be41eae4d0077069ecf77a8904b5f624d5ea5ffTim Janik * 3) poll with the pollfds from all sources at the priority of the
6728be41eae4d0077069ecf77a8904b5f624d5ea5ffTim Janik *    first source flagged as SOURCE_READY. if there are any sources
6738be41eae4d0077069ecf77a8904b5f624d5ea5ffTim Janik *    flagged as SOURCE_READY, we use a timeout of 0 or the minimum
6748be41eae4d0077069ecf77a8904b5f624d5ea5ffTim Janik *    of all timouts otherwise.
6758be41eae4d0077069ecf77a8904b5f624d5ea5ffTim Janik *
6768be41eae4d0077069ecf77a8904b5f624d5ea5ffTim Janik * 4) for each source !IN_CALL or can_recurse, if SOURCE_READY or
6778be41eae4d0077069ecf77a8904b5f624d5ea5ffTim Janik *    (*check) returns true, add the source to the pending list.
6788be41eae4d0077069ecf77a8904b5f624d5ea5ffTim Janik *    once one source returns true, stop after checking all sources
6798be41eae4d0077069ecf77a8904b5f624d5ea5ffTim Janik *    at that priority.
6808be41eae4d0077069ecf77a8904b5f624d5ea5ffTim Janik *
6818be41eae4d0077069ecf77a8904b5f624d5ea5ffTim Janik * 5) while the list of currently pending sources is non-empty,
6828be41eae4d0077069ecf77a8904b5f624d5ea5ffTim Janik *    call (*dispatch) on each source, removing the source
6838be41eae4d0077069ecf77a8904b5f624d5ea5ffTim Janik *    after the call.
6848be41eae4d0077069ecf77a8904b5f624d5ea5ffTim Janik *
685beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor */
686beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylorstatic gboolean
687a62ebb0e757c972ef4bc5892d7e3e673c6426015Tim Janikg_main_iterate (gboolean block,
688a62ebb0e757c972ef4bc5892d7e3e673c6426015Tim Janik		gboolean dispatch)
689beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor{
690beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  GHook *hook;
69185755f7e77f5283cc13d2e8f7d841d2e151bfc33Tim Janik  GTimeVal current_time  ={ 0, 0 };
6928be41eae4d0077069ecf77a8904b5f624d5ea5ffTim Janik  gint n_ready = 0;
693beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  gint current_priority = 0;
694beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  gint timeout;
695931ea952650b013b834041b91b0c37a748ffd449Owen Taylor  gboolean retval = FALSE;
696beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
697beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  g_return_val_if_fail (!block || dispatch, FALSE);
698beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
699beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  g_get_current_time (&current_time);
700931ea952650b013b834041b91b0c37a748ffd449Owen Taylor
701b2e318ff3ecc50d72121a4e8561442a6d79a7a84Tim Janik  G_LOCK (main_loop);
702beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
703beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  /* If recursing, finish up current dispatch, before starting over */
704beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  if (pending_dispatches)
705beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor    {
706beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor      if (dispatch)
707beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor	g_main_dispatch (&current_time);
708beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
709b2e318ff3ecc50d72121a4e8561442a6d79a7a84Tim Janik      G_UNLOCK (main_loop);
7108be41eae4d0077069ecf77a8904b5f624d5ea5ffTim Janik
711beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor      return TRUE;
712beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor    }
713beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
714beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  /* Prepare all sources */
715beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
716beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  timeout = block ? -1 : 0;
717beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
718beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  hook = g_hook_first_valid (&source_list, TRUE);
719beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  while (hook)
720beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor    {
721beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor      GSource *source = (GSource *)hook;
72285755f7e77f5283cc13d2e8f7d841d2e151bfc33Tim Janik      gint source_timeout = -1;
723beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
7248be41eae4d0077069ecf77a8904b5f624d5ea5ffTim Janik      if ((n_ready > 0) && (source->priority > current_priority))
72500e064d2af719c4a630156cef361de6365342aaeTim Janik	{
72600e064d2af719c4a630156cef361de6365342aaeTim Janik	  g_hook_unref (&source_list, hook);
72700e064d2af719c4a630156cef361de6365342aaeTim Janik	  break;
72800e064d2af719c4a630156cef361de6365342aaeTim Janik	}
7298be41eae4d0077069ecf77a8904b5f624d5ea5ffTim Janik      if (G_HOOK_IN_CALL (hook) && !(hook->flags & G_SOURCE_CAN_RECURSE))
730beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor	{
731097c9b17985efe03bf7d5a1b073d81f526218c87Tim Janik	  hook = g_hook_next_valid (&source_list, hook, TRUE);
732beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor	  continue;
733beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor	}
734beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
735f26256fe182bc1249d3058d9f18402d0ac26974cOwen Taylor      if (!(hook->flags & G_SOURCE_READY))
736beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor	{
737f26256fe182bc1249d3058d9f18402d0ac26974cOwen Taylor	  gboolean (*prepare)  (gpointer  source_data,
738f26256fe182bc1249d3058d9f18402d0ac26974cOwen Taylor				GTimeVal *current_time,
739f26256fe182bc1249d3058d9f18402d0ac26974cOwen Taylor				gint     *timeout);
740f26256fe182bc1249d3058d9f18402d0ac26974cOwen Taylor
741f26256fe182bc1249d3058d9f18402d0ac26974cOwen Taylor	  prepare = ((GSourceFuncs *) hook->func)->prepare;
742f26256fe182bc1249d3058d9f18402d0ac26974cOwen Taylor	  in_check_or_prepare++;
743f26256fe182bc1249d3058d9f18402d0ac26974cOwen Taylor	  G_UNLOCK (main_loop);
744f26256fe182bc1249d3058d9f18402d0ac26974cOwen Taylor
745f26256fe182bc1249d3058d9f18402d0ac26974cOwen Taylor	  if ((*prepare) (source->source_data, &current_time, &source_timeout))
746f26256fe182bc1249d3058d9f18402d0ac26974cOwen Taylor	    hook->flags |= G_SOURCE_READY;
747f26256fe182bc1249d3058d9f18402d0ac26974cOwen Taylor
748f26256fe182bc1249d3058d9f18402d0ac26974cOwen Taylor	  G_LOCK (main_loop);
74908425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik	  in_check_or_prepare--;
750f26256fe182bc1249d3058d9f18402d0ac26974cOwen Taylor	}
751f26256fe182bc1249d3058d9f18402d0ac26974cOwen Taylor
752f26256fe182bc1249d3058d9f18402d0ac26974cOwen Taylor      if (hook->flags & G_SOURCE_READY)
753f26256fe182bc1249d3058d9f18402d0ac26974cOwen Taylor	{
754beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor	  if (!dispatch)
755beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor	    {
756beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor	      g_hook_unref (&source_list, hook);
757b2e318ff3ecc50d72121a4e8561442a6d79a7a84Tim Janik	      G_UNLOCK (main_loop);
7588be41eae4d0077069ecf77a8904b5f624d5ea5ffTim Janik
759beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor	      return TRUE;
760beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor	    }
761beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor	  else
762beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor	    {
7638be41eae4d0077069ecf77a8904b5f624d5ea5ffTim Janik	      n_ready++;
764beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor	      current_priority = source->priority;
765beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor	      timeout = 0;
766beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor	    }
767beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor	}
768beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
769beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor      if (source_timeout >= 0)
770beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor	{
771beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor	  if (timeout < 0)
772beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor	    timeout = source_timeout;
773beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor	  else
774beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor	    timeout = MIN (timeout, source_timeout);
775beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor	}
776beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
77700e064d2af719c4a630156cef361de6365342aaeTim Janik      hook = g_hook_next_valid (&source_list, hook, TRUE);
778beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor    }
779beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
780beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  /* poll(), if necessary */
781beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
7828be41eae4d0077069ecf77a8904b5f624d5ea5ffTim Janik  g_main_poll (timeout, n_ready > 0, current_priority);
783beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
784beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  /* Check to see what sources need to be dispatched */
785beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
7868be41eae4d0077069ecf77a8904b5f624d5ea5ffTim Janik  n_ready = 0;
787beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
788beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  hook = g_hook_first_valid (&source_list, TRUE);
789beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  while (hook)
790beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor    {
791beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor      GSource *source = (GSource *)hook;
792beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
7938be41eae4d0077069ecf77a8904b5f624d5ea5ffTim Janik      if ((n_ready > 0) && (source->priority > current_priority))
79400e064d2af719c4a630156cef361de6365342aaeTim Janik	{
79500e064d2af719c4a630156cef361de6365342aaeTim Janik	  g_hook_unref (&source_list, hook);
79600e064d2af719c4a630156cef361de6365342aaeTim Janik	  break;
79700e064d2af719c4a630156cef361de6365342aaeTim Janik	}
7988be41eae4d0077069ecf77a8904b5f624d5ea5ffTim Janik      if (G_HOOK_IN_CALL (hook) && !(hook->flags & G_SOURCE_CAN_RECURSE))
799beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor	{
800097c9b17985efe03bf7d5a1b073d81f526218c87Tim Janik	  hook = g_hook_next_valid (&source_list, hook, TRUE);
801beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor	  continue;
802beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor	}
803beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
804f26256fe182bc1249d3058d9f18402d0ac26974cOwen Taylor      if (!(hook->flags & G_SOURCE_READY))
805beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor	{
806f26256fe182bc1249d3058d9f18402d0ac26974cOwen Taylor	  gboolean (*check) (gpointer  source_data,
807f26256fe182bc1249d3058d9f18402d0ac26974cOwen Taylor			     GTimeVal *current_time);
808f26256fe182bc1249d3058d9f18402d0ac26974cOwen Taylor
809f26256fe182bc1249d3058d9f18402d0ac26974cOwen Taylor	  check = ((GSourceFuncs *) hook->func)->check;
810f26256fe182bc1249d3058d9f18402d0ac26974cOwen Taylor	  in_check_or_prepare++;
811f26256fe182bc1249d3058d9f18402d0ac26974cOwen Taylor	  G_UNLOCK (main_loop);
812f26256fe182bc1249d3058d9f18402d0ac26974cOwen Taylor
813f26256fe182bc1249d3058d9f18402d0ac26974cOwen Taylor	  if ((*check) (source->source_data, &current_time))
814f26256fe182bc1249d3058d9f18402d0ac26974cOwen Taylor	    hook->flags |= G_SOURCE_READY;
815f26256fe182bc1249d3058d9f18402d0ac26974cOwen Taylor
816f26256fe182bc1249d3058d9f18402d0ac26974cOwen Taylor	  G_LOCK (main_loop);
81708425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik	  in_check_or_prepare--;
818f26256fe182bc1249d3058d9f18402d0ac26974cOwen Taylor	}
819f26256fe182bc1249d3058d9f18402d0ac26974cOwen Taylor
820f26256fe182bc1249d3058d9f18402d0ac26974cOwen Taylor      if (hook->flags & G_SOURCE_READY)
821f26256fe182bc1249d3058d9f18402d0ac26974cOwen Taylor	{
822beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor	  if (dispatch)
823beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor	    {
824beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor	      hook->flags &= ~G_SOURCE_READY;
825beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor	      g_hook_ref (&source_list, hook);
826beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor	      pending_dispatches = g_slist_prepend (pending_dispatches, source);
827beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor	      current_priority = source->priority;
8288be41eae4d0077069ecf77a8904b5f624d5ea5ffTim Janik	      n_ready++;
829beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor	    }
830beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor	  else
831beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor	    {
832beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor	      g_hook_unref (&source_list, hook);
833b2e318ff3ecc50d72121a4e8561442a6d79a7a84Tim Janik	      G_UNLOCK (main_loop);
8348be41eae4d0077069ecf77a8904b5f624d5ea5ffTim Janik
835beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor	      return TRUE;
836beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor	    }
837beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor	}
838beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
83900e064d2af719c4a630156cef361de6365342aaeTim Janik      hook = g_hook_next_valid (&source_list, hook, TRUE);
840beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor    }
841beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
842beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  /* Now invoke the callbacks */
843beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
844beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  if (pending_dispatches)
845beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor    {
846beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor      pending_dispatches = g_slist_reverse (pending_dispatches);
847beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor      g_main_dispatch (&current_time);
848931ea952650b013b834041b91b0c37a748ffd449Owen Taylor      retval = TRUE;
849beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor    }
850931ea952650b013b834041b91b0c37a748ffd449Owen Taylor
851b2e318ff3ecc50d72121a4e8561442a6d79a7a84Tim Janik  G_UNLOCK (main_loop);
852931ea952650b013b834041b91b0c37a748ffd449Owen Taylor
853931ea952650b013b834041b91b0c37a748ffd449Owen Taylor  return retval;
854beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor}
855beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
856beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor/* See if any events are pending
857beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor */
858beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylorgboolean
85908425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janikg_main_pending (void)
860beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor{
86108425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik  return in_check_or_prepare ? FALSE : g_main_iterate (FALSE, FALSE);
862beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor}
863beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
864beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor/* Run a single iteration of the mainloop. If block is FALSE,
865beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor * will never block
866beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor */
867beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylorgboolean
868beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylorg_main_iteration (gboolean block)
869beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor{
87008425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik  if (in_check_or_prepare)
87108425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik    {
87208425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik      g_warning ("g_main_iteration(): called recursively from within a source's check() or "
873f26256fe182bc1249d3058d9f18402d0ac26974cOwen Taylor		 "prepare() member or from a second thread, iteration not possible");
87408425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik      return FALSE;
87508425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik    }
87608425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik  else
87708425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik    return g_main_iterate (block, TRUE);
878beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor}
879beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
8808be41eae4d0077069ecf77a8904b5f624d5ea5ffTim JanikGMainLoop*
8818be41eae4d0077069ecf77a8904b5f624d5ea5ffTim Janikg_main_new (gboolean is_running)
882beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor{
8838be41eae4d0077069ecf77a8904b5f624d5ea5ffTim Janik  GMainLoop *loop;
8848be41eae4d0077069ecf77a8904b5f624d5ea5ffTim Janik
8858be41eae4d0077069ecf77a8904b5f624d5ea5ffTim Janik  loop = g_new0 (GMainLoop, 1);
8868be41eae4d0077069ecf77a8904b5f624d5ea5ffTim Janik  loop->is_running = is_running != FALSE;
887beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
8888be41eae4d0077069ecf77a8904b5f624d5ea5ffTim Janik  return loop;
889beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor}
890beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
891beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylorvoid
892beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylorg_main_run (GMainLoop *loop)
893beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor{
8948be41eae4d0077069ecf77a8904b5f624d5ea5ffTim Janik  g_return_if_fail (loop != NULL);
8958be41eae4d0077069ecf77a8904b5f624d5ea5ffTim Janik
89608425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik  if (in_check_or_prepare)
89708425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik    {
89808425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik      g_warning ("g_main_run(): called recursively from within a source's check() or "
899f26256fe182bc1249d3058d9f18402d0ac26974cOwen Taylor		 "prepare() member or from a second thread, iteration not possible");
90008425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik      return;
90108425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik    }
90208425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik
9038be41eae4d0077069ecf77a8904b5f624d5ea5ffTim Janik  loop->is_running = TRUE;
9048be41eae4d0077069ecf77a8904b5f624d5ea5ffTim Janik  while (loop->is_running)
905beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor    g_main_iterate (TRUE, TRUE);
906beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor}
907beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
908beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylorvoid
909beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylorg_main_quit (GMainLoop *loop)
910beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor{
9118be41eae4d0077069ecf77a8904b5f624d5ea5ffTim Janik  g_return_if_fail (loop != NULL);
9128be41eae4d0077069ecf77a8904b5f624d5ea5ffTim Janik
9138be41eae4d0077069ecf77a8904b5f624d5ea5ffTim Janik  loop->is_running = FALSE;
914beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor}
915beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
916beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylorvoid
917beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylorg_main_destroy (GMainLoop *loop)
918beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor{
9198be41eae4d0077069ecf77a8904b5f624d5ea5ffTim Janik  g_return_if_fail (loop != NULL);
9208be41eae4d0077069ecf77a8904b5f624d5ea5ffTim Janik
921beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  g_free (loop);
922beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor}
923beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
9248be41eae4d0077069ecf77a8904b5f624d5ea5ffTim Janikgboolean
9258be41eae4d0077069ecf77a8904b5f624d5ea5ffTim Janikg_main_is_running (GMainLoop *loop)
9268be41eae4d0077069ecf77a8904b5f624d5ea5ffTim Janik{
9278be41eae4d0077069ecf77a8904b5f624d5ea5ffTim Janik  g_return_val_if_fail (loop != NULL, FALSE);
9288be41eae4d0077069ecf77a8904b5f624d5ea5ffTim Janik
9298be41eae4d0077069ecf77a8904b5f624d5ea5ffTim Janik  return loop->is_running;
9308be41eae4d0077069ecf77a8904b5f624d5ea5ffTim Janik}
9318be41eae4d0077069ecf77a8904b5f624d5ea5ffTim Janik
932931ea952650b013b834041b91b0c37a748ffd449Owen Taylor/* HOLDS: main_loop_lock */
933beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylorstatic void
9348be41eae4d0077069ecf77a8904b5f624d5ea5ffTim Janikg_main_poll (gint     timeout,
9358be41eae4d0077069ecf77a8904b5f624d5ea5ffTim Janik	     gboolean use_priority,
9368be41eae4d0077069ecf77a8904b5f624d5ea5ffTim Janik	     gint     priority)
937beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor{
938bb19315fbdb4ae54704778e6dec7b7319c95419aOwen Taylor  GPollFD *fd_array;
939beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  GPollRec *pollrec;
940beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
941beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  gint i;
942beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  gint npoll;
943f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist#ifdef G_THREADS_ENABLED
944f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist#ifndef NATIVE_WIN32
945931ea952650b013b834041b91b0c37a748ffd449Owen Taylor  if (wake_up_pipe[0] < 0)
946931ea952650b013b834041b91b0c37a748ffd449Owen Taylor    {
947931ea952650b013b834041b91b0c37a748ffd449Owen Taylor      if (pipe (wake_up_pipe) < 0)
948931ea952650b013b834041b91b0c37a748ffd449Owen Taylor	g_error ("Cannot create pipe main loop wake-up: %s\n",
9498be41eae4d0077069ecf77a8904b5f624d5ea5ffTim Janik		 g_strerror (errno));
950931ea952650b013b834041b91b0c37a748ffd449Owen Taylor
951931ea952650b013b834041b91b0c37a748ffd449Owen Taylor      wake_up_rec.fd = wake_up_pipe[0];
952931ea952650b013b834041b91b0c37a748ffd449Owen Taylor      wake_up_rec.events = G_IO_IN;
953bb19315fbdb4ae54704778e6dec7b7319c95419aOwen Taylor      g_main_add_poll_unlocked (0, &wake_up_rec);
954931ea952650b013b834041b91b0c37a748ffd449Owen Taylor    }
955f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist#else
956f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist  if (wake_up_semaphore == NULL)
957f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist    {
958f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist      if ((wake_up_semaphore = CreateSemaphore (NULL, 0, 100, NULL)) == NULL)
959f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist	g_error ("Cannot create wake-up semaphore: %d", GetLastError ());
960f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist      wake_up_rec.fd = (gint) wake_up_semaphore;
961f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist      wake_up_rec.events = G_IO_IN;
962f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist      g_main_add_poll_unlocked (0, &wake_up_rec);
963f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist    }
964f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist#endif
965f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist#endif
966bb19315fbdb4ae54704778e6dec7b7319c95419aOwen Taylor  fd_array = g_new (GPollFD, n_poll_records);
967bb19315fbdb4ae54704778e6dec7b7319c95419aOwen Taylor
968beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  pollrec = poll_records;
969beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  i = 0;
970beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  while (pollrec && (!use_priority || priority >= pollrec->priority))
971beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor    {
972beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor      fd_array[i].fd = pollrec->fd->fd;
973beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor      fd_array[i].events = pollrec->fd->events;
974beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor      fd_array[i].revents = 0;
975beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
976beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor      pollrec = pollrec->next;
977beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor      i++;
978beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor    }
979f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist#ifdef G_THREADS_ENABLED
980931ea952650b013b834041b91b0c37a748ffd449Owen Taylor  poll_waiting = TRUE;
981f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist#endif
982b2e318ff3ecc50d72121a4e8561442a6d79a7a84Tim Janik  G_UNLOCK (main_loop);
983beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  npoll = i;
984beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  (*poll_func) (fd_array, npoll, timeout);
985b2e318ff3ecc50d72121a4e8561442a6d79a7a84Tim Janik  G_LOCK (main_loop);
986931ea952650b013b834041b91b0c37a748ffd449Owen Taylor
987f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist#ifdef G_THREADS_ENABLED
988931ea952650b013b834041b91b0c37a748ffd449Owen Taylor  if (!poll_waiting)
989931ea952650b013b834041b91b0c37a748ffd449Owen Taylor    {
990f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist#ifndef NATIVE_WIN32
991931ea952650b013b834041b91b0c37a748ffd449Owen Taylor      gchar c;
992931ea952650b013b834041b91b0c37a748ffd449Owen Taylor      read (wake_up_pipe[0], &c, 1);
993f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist#endif
994931ea952650b013b834041b91b0c37a748ffd449Owen Taylor    }
995931ea952650b013b834041b91b0c37a748ffd449Owen Taylor  else
996931ea952650b013b834041b91b0c37a748ffd449Owen Taylor    poll_waiting = FALSE;
997f477518c3af60dccfdd172abee0c7368e8f44189Tor Lillqvist#endif
998beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
999beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  pollrec = poll_records;
1000beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  i = 0;
1001beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  while (i < npoll)
1002beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor    {
1003beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor      pollrec->fd->revents = fd_array[i].revents;
1004beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor      pollrec = pollrec->next;
1005beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor      i++;
1006beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor    }
1007beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
1008beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  g_free (fd_array);
1009beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor}
1010beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
1011beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylorvoid
10128be41eae4d0077069ecf77a8904b5f624d5ea5ffTim Janikg_main_add_poll (GPollFD *fd,
10138be41eae4d0077069ecf77a8904b5f624d5ea5ffTim Janik		 gint     priority)
1014beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor{
1015b2e318ff3ecc50d72121a4e8561442a6d79a7a84Tim Janik  G_LOCK (main_loop);
1016bb19315fbdb4ae54704778e6dec7b7319c95419aOwen Taylor  g_main_add_poll_unlocked (priority, fd);
1017b2e318ff3ecc50d72121a4e8561442a6d79a7a84Tim Janik  G_UNLOCK (main_loop);
1018931ea952650b013b834041b91b0c37a748ffd449Owen Taylor}
1019931ea952650b013b834041b91b0c37a748ffd449Owen Taylor
10202e57a3643891f41c238c5ee3793afcd8706a4060Sebastian Wilhelmi/* HOLDS: main_loop_lock */
1021931ea952650b013b834041b91b0c37a748ffd449Owen Taylorstatic void
1022bb19315fbdb4ae54704778e6dec7b7319c95419aOwen Taylorg_main_add_poll_unlocked (gint     priority,
1023bb19315fbdb4ae54704778e6dec7b7319c95419aOwen Taylor			  GPollFD *fd)
1024931ea952650b013b834041b91b0c37a748ffd449Owen Taylor{
1025beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  GPollRec *lastrec, *pollrec, *newrec;
1026beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
1027beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  if (!poll_chunk)
1028beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor    poll_chunk = g_mem_chunk_create (GPollRec, 32, G_ALLOC_ONLY);
1029beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
1030931ea952650b013b834041b91b0c37a748ffd449Owen Taylor  if (poll_free_list)
1031931ea952650b013b834041b91b0c37a748ffd449Owen Taylor    {
1032931ea952650b013b834041b91b0c37a748ffd449Owen Taylor      newrec = poll_free_list;
1033931ea952650b013b834041b91b0c37a748ffd449Owen Taylor      poll_free_list = newrec->next;
1034931ea952650b013b834041b91b0c37a748ffd449Owen Taylor    }
1035931ea952650b013b834041b91b0c37a748ffd449Owen Taylor  else
1036931ea952650b013b834041b91b0c37a748ffd449Owen Taylor    newrec = g_chunk_new (GPollRec, poll_chunk);
1037931ea952650b013b834041b91b0c37a748ffd449Owen Taylor
1038beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  newrec->fd = fd;
1039beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  newrec->priority = priority;
1040beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
1041beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  lastrec = NULL;
1042beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  pollrec = poll_records;
1043beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  while (pollrec && priority >= pollrec->priority)
1044beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor    {
1045beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor      lastrec = pollrec;
1046beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor      pollrec = pollrec->next;
1047beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor    }
1048beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
1049beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  if (lastrec)
1050beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor    lastrec->next = newrec;
1051beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  else
1052beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor    poll_records = newrec;
1053beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
1054beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  newrec->next = pollrec;
1055beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
1056beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  n_poll_records++;
1057beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor}
1058beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
1059beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylorvoid
106077ccad4d2fe1dde7927a194fc53fa520cb20d059CSTg_main_remove_poll (GPollFD *fd)
1061beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor{
1062beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  GPollRec *pollrec, *lastrec;
1063beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
1064b2e318ff3ecc50d72121a4e8561442a6d79a7a84Tim Janik  G_LOCK (main_loop);
1065931ea952650b013b834041b91b0c37a748ffd449Owen Taylor
1066beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  lastrec = NULL;
1067beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  pollrec = poll_records;
1068beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
1069beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  while (pollrec)
1070beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor    {
1071beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor      if (pollrec->fd == fd)
1072beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor	{
1073beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor	  if (lastrec != NULL)
1074beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor	    lastrec->next = pollrec->next;
1075beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor	  else
1076beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor	    poll_records = pollrec->next;
1077beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
1078beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor	  pollrec->next = poll_free_list;
1079beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor	  poll_free_list = pollrec;
1080931ea952650b013b834041b91b0c37a748ffd449Owen Taylor
1081931ea952650b013b834041b91b0c37a748ffd449Owen Taylor	  n_poll_records--;
1082931ea952650b013b834041b91b0c37a748ffd449Owen Taylor	  break;
1083beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor	}
1084beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor      lastrec = pollrec;
1085beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor      pollrec = pollrec->next;
1086beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor    }
1087beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
1088b2e318ff3ecc50d72121a4e8561442a6d79a7a84Tim Janik  G_UNLOCK (main_loop);
1089beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor}
1090beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
1091beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylorvoid
1092beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylorg_main_set_poll_func (GPollFunc func)
1093beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor{
1094beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  if (func)
1095beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor    poll_func = func;
1096beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  else
1097738864a1a758b2421211e4ecf1ce6102842428eaManish Singh#ifdef HAVE_POLL
109808425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik    poll_func = (GPollFunc) poll;
1099738864a1a758b2421211e4ecf1ce6102842428eaManish Singh#else
110008425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik    poll_func = (GPollFunc) g_poll;
1101738864a1a758b2421211e4ecf1ce6102842428eaManish Singh#endif
1102beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor}
1103beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
1104beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor/* Timeouts */
1105beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
1106beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylorstatic gboolean
1107beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylorg_timeout_prepare  (gpointer source_data,
1108beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor		    GTimeVal *current_time,
1109beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor		    gint    *timeout)
1110beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor{
1111beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  glong msec;
1112beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  GTimeoutData *data = source_data;
1113beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
1114beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  msec = (data->expiration.tv_sec  - current_time->tv_sec) * 1000 +
1115beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor         (data->expiration.tv_usec - current_time->tv_usec) / 1000;
1116beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
1117beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  *timeout = (msec <= 0) ? 0 : msec;
1118beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
1119beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  return (msec <= 0);
1120beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor}
1121beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
1122beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylorstatic gboolean
1123beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylorg_timeout_check    (gpointer source_data,
1124beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor		    GTimeVal *current_time)
1125beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor{
1126beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  GTimeoutData *data = source_data;
1127beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
1128beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  return (data->expiration.tv_sec < current_time->tv_sec) ||
1129beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor         ((data->expiration.tv_sec == current_time->tv_sec) &&
1130beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor	  (data->expiration.tv_usec <= current_time->tv_usec));
1131beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor}
1132beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
1133beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylorstatic gboolean
1134beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylorg_timeout_dispatch (gpointer source_data,
1135beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor		    GTimeVal *current_time,
1136beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor		    gpointer user_data)
1137beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor{
1138beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  GTimeoutData *data = source_data;
1139beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
114037f659ec1127781395c3523244399514ba99eab7Tim Janik  if (data->callback (user_data))
1141beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor    {
11422623d2831ab006459da71d8a869a7a9a55869df2Owen Taylor      guint seconds = data->interval / 1000;
11432623d2831ab006459da71d8a869a7a9a55869df2Owen Taylor      guint msecs = data->interval - seconds * 1000;
11442623d2831ab006459da71d8a869a7a9a55869df2Owen Taylor
11452623d2831ab006459da71d8a869a7a9a55869df2Owen Taylor      data->expiration.tv_sec = current_time->tv_sec + seconds;
11462623d2831ab006459da71d8a869a7a9a55869df2Owen Taylor      data->expiration.tv_usec = current_time->tv_usec + msecs * 1000;
1147beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor      if (data->expiration.tv_usec >= 1000000)
1148beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor	{
1149beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor	  data->expiration.tv_usec -= 1000000;
1150beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor	  data->expiration.tv_sec++;
1151beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor	}
1152beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor      return TRUE;
1153beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor    }
1154beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  else
1155beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor    return FALSE;
1156beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor}
1157beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
1158beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylorguint
1159beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylorg_timeout_add_full (gint           priority,
1160beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor		    guint          interval,
1161beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor		    GSourceFunc    function,
1162beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor		    gpointer       data,
1163beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor		    GDestroyNotify notify)
1164beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor{
11652623d2831ab006459da71d8a869a7a9a55869df2Owen Taylor  guint seconds;
11662623d2831ab006459da71d8a869a7a9a55869df2Owen Taylor  guint msecs;
1167beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  GTimeoutData *timeout_data = g_new (GTimeoutData, 1);
1168beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
1169beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  timeout_data->interval = interval;
1170beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  timeout_data->callback = function;
1171beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  g_get_current_time (&timeout_data->expiration);
1172beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
11732623d2831ab006459da71d8a869a7a9a55869df2Owen Taylor  seconds = timeout_data->interval / 1000;
11742623d2831ab006459da71d8a869a7a9a55869df2Owen Taylor  msecs = timeout_data->interval - seconds * 1000;
11752623d2831ab006459da71d8a869a7a9a55869df2Owen Taylor
11762623d2831ab006459da71d8a869a7a9a55869df2Owen Taylor  timeout_data->expiration.tv_sec += seconds;
11772623d2831ab006459da71d8a869a7a9a55869df2Owen Taylor  timeout_data->expiration.tv_usec += msecs * 1000;
1178beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  if (timeout_data->expiration.tv_usec >= 1000000)
1179beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor    {
1180beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor      timeout_data->expiration.tv_usec -= 1000000;
1181beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor      timeout_data->expiration.tv_sec++;
1182beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor    }
1183beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
1184beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  return g_source_add (priority, FALSE, &timeout_funcs, timeout_data, data, notify);
1185beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor}
1186beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
1187beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylorguint
1188beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylorg_timeout_add (guint32        interval,
1189beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor	       GSourceFunc    function,
1190beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor	       gpointer       data)
1191beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor{
11927f237f6fcd00ad9888ef459ccdc8d02e12c311fdOwen Taylor  return g_timeout_add_full (G_PRIORITY_DEFAULT,
11937f237f6fcd00ad9888ef459ccdc8d02e12c311fdOwen Taylor			     interval, function, data, NULL);
1194beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor}
1195beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
1196beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor/* Idle functions */
1197beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
1198beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylorstatic gboolean
1199beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylorg_idle_prepare  (gpointer source_data,
1200beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor		 GTimeVal *current_time,
1201beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor		 gint     *timeout)
1202beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor{
1203beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  timeout = 0;
1204beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  return TRUE;
1205beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor}
1206beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
1207beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylorstatic gboolean
1208beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylorg_idle_check    (gpointer  source_data,
1209beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor		 GTimeVal *current_time)
1210beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor{
1211beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor  return TRUE;
1212beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor}
1213beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
1214beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylorstatic gboolean
1215beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylorg_idle_dispatch (gpointer source_data,
1216beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor		 GTimeVal *current_time,
1217beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor		 gpointer user_data)
1218beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor{
121908425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik  GSourceFunc func = source_data;
1220beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
122108425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik  return func (user_data);
1222beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor}
1223beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
1224beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylorguint
122508425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janikg_idle_add_full (gint           priority,
1226beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor		 GSourceFunc    function,
1227beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor		 gpointer       data,
1228beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor		 GDestroyNotify notify)
1229beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor{
123008425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik  g_return_val_if_fail (function != NULL, 0);
1231beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
123208425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik  return g_source_add (priority, FALSE, &idle_funcs, function, data, notify);
1233beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor}
1234beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor
1235beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylorguint
1236beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylorg_idle_add (GSourceFunc    function,
1237beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor	    gpointer       data)
1238beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor{
12397f237f6fcd00ad9888ef459ccdc8d02e12c311fdOwen Taylor  return g_idle_add_full (G_PRIORITY_DEFAULT_IDLE, function, data, NULL);
1240beab982e3b8547c1f7d95e6d8f51d4ad430a7694Owen Taylor}
124108425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik
124208425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janikgboolean
124308425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janikg_idle_remove_by_data (gpointer data)
124408425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik{
124508425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik  return g_source_remove_by_funcs_user_data (&idle_funcs, data);
124608425ac4c2fce32d96295e3fefe31f1ddcc17db0Tim Janik}
1247