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