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 (¤t_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 (¤t_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, ¤t_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, ¤t_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 (¤t_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