nexmon – Blame information for rev 1
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | office | 1 | /* GLIB - Library of useful routines for C programming |
2 | * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald |
||
3 | * |
||
4 | * gmain.c: Main loop abstraction, timeouts, and idle functions |
||
5 | * Copyright 1998 Owen Taylor |
||
6 | * |
||
7 | * This library is free software; you can redistribute it and/or |
||
8 | * modify it under the terms of the GNU Lesser General Public |
||
9 | * License as published by the Free Software Foundation; either |
||
10 | * version 2 of the License, or (at your option) any later version. |
||
11 | * |
||
12 | * This library is distributed in the hope that it will be useful, |
||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
||
15 | * Lesser General Public License for more details. |
||
16 | * |
||
17 | * You should have received a copy of the GNU Lesser General Public |
||
18 | * License along with this library; if not, see <http://www.gnu.org/licenses/>. |
||
19 | */ |
||
20 | |||
21 | /* |
||
22 | * Modified by the GLib Team and others 1997-2000. See the AUTHORS |
||
23 | * file for a list of people on the GLib Team. See the ChangeLog |
||
24 | * files for a list of changes. These files are distributed with |
||
25 | * GLib at ftp://ftp.gtk.org/pub/gtk/. |
||
26 | */ |
||
27 | |||
28 | /* |
||
29 | * MT safe |
||
30 | */ |
||
31 | |||
32 | #include "config.h" |
||
33 | #include "glibconfig.h" |
||
34 | |||
35 | /* Uncomment the next line (and the corresponding line in gpoll.c) to |
||
36 | * enable debugging printouts if the environment variable |
||
37 | * G_MAIN_POLL_DEBUG is set to some value. |
||
38 | */ |
||
39 | /* #define G_MAIN_POLL_DEBUG */ |
||
40 | |||
41 | #ifdef _WIN32 |
||
42 | /* Always enable debugging printout on Windows, as it is more often |
||
43 | * needed there... |
||
44 | */ |
||
45 | #define G_MAIN_POLL_DEBUG |
||
46 | #endif |
||
47 | |||
48 | #ifdef G_OS_UNIX |
||
49 | #include "glib-unix.h" |
||
50 | #include <pthread.h> |
||
51 | #ifdef HAVE_EVENTFD |
||
52 | #include <sys/eventfd.h> |
||
53 | #endif |
||
54 | #endif |
||
55 | |||
56 | #include <signal.h> |
||
57 | #include <sys/types.h> |
||
58 | #include <time.h> |
||
59 | #include <stdlib.h> |
||
60 | #ifdef HAVE_SYS_TIME_H |
||
61 | #include <sys/time.h> |
||
62 | #endif /* HAVE_SYS_TIME_H */ |
||
63 | #ifdef G_OS_UNIX |
||
64 | #include <unistd.h> |
||
65 | #endif /* G_OS_UNIX */ |
||
66 | #include <errno.h> |
||
67 | #include <string.h> |
||
68 | |||
69 | #ifdef G_OS_WIN32 |
||
70 | #define STRICT |
||
71 | #include <windows.h> |
||
72 | #endif /* G_OS_WIN32 */ |
||
73 | |||
74 | #ifdef HAVE_MACH_MACH_TIME_H |
||
75 | #include <mach/mach_time.h> |
||
76 | #endif |
||
77 | |||
78 | #include "glib_trace.h" |
||
79 | |||
80 | #include "gmain.h" |
||
81 | |||
82 | #include "garray.h" |
||
83 | #include "giochannel.h" |
||
84 | #include "ghash.h" |
||
85 | #include "ghook.h" |
||
86 | #include "gqueue.h" |
||
87 | #include "gstrfuncs.h" |
||
88 | #include "gtestutils.h" |
||
89 | |||
90 | #ifdef G_OS_WIN32 |
||
91 | #include "gwin32.h" |
||
92 | #endif |
||
93 | |||
94 | #ifdef G_MAIN_POLL_DEBUG |
||
95 | #include "gtimer.h" |
||
96 | #endif |
||
97 | |||
98 | #include "gwakeup.h" |
||
99 | #include "gmain-internal.h" |
||
100 | #include "glib-init.h" |
||
101 | #include "glib-private.h" |
||
102 | |||
103 | /** |
||
104 | * SECTION:main |
||
105 | * @title: The Main Event Loop |
||
106 | * @short_description: manages all available sources of events |
||
107 | * |
||
108 | * The main event loop manages all the available sources of events for |
||
109 | * GLib and GTK+ applications. These events can come from any number of |
||
110 | * different types of sources such as file descriptors (plain files, |
||
111 | * pipes or sockets) and timeouts. New types of event sources can also |
||
112 | * be added using g_source_attach(). |
||
113 | * |
||
114 | * To allow multiple independent sets of sources to be handled in |
||
115 | * different threads, each source is associated with a #GMainContext. |
||
116 | * A GMainContext can only be running in a single thread, but |
||
117 | * sources can be added to it and removed from it from other threads. |
||
118 | * |
||
119 | * Each event source is assigned a priority. The default priority, |
||
120 | * #G_PRIORITY_DEFAULT, is 0. Values less than 0 denote higher priorities. |
||
121 | * Values greater than 0 denote lower priorities. Events from high priority |
||
122 | * sources are always processed before events from lower priority sources. |
||
123 | * |
||
124 | * Idle functions can also be added, and assigned a priority. These will |
||
125 | * be run whenever no events with a higher priority are ready to be processed. |
||
126 | * |
||
127 | * The #GMainLoop data type represents a main event loop. A GMainLoop is |
||
128 | * created with g_main_loop_new(). After adding the initial event sources, |
||
129 | * g_main_loop_run() is called. This continuously checks for new events from |
||
130 | * each of the event sources and dispatches them. Finally, the processing of |
||
131 | * an event from one of the sources leads to a call to g_main_loop_quit() to |
||
132 | * exit the main loop, and g_main_loop_run() returns. |
||
133 | * |
||
134 | * It is possible to create new instances of #GMainLoop recursively. |
||
135 | * This is often used in GTK+ applications when showing modal dialog |
||
136 | * boxes. Note that event sources are associated with a particular |
||
137 | * #GMainContext, and will be checked and dispatched for all main |
||
138 | * loops associated with that GMainContext. |
||
139 | * |
||
140 | * GTK+ contains wrappers of some of these functions, e.g. gtk_main(), |
||
141 | * gtk_main_quit() and gtk_events_pending(). |
||
142 | * |
||
143 | * ## Creating new source types |
||
144 | * |
||
145 | * One of the unusual features of the #GMainLoop functionality |
||
146 | * is that new types of event source can be created and used in |
||
147 | * addition to the builtin type of event source. A new event source |
||
148 | * type is used for handling GDK events. A new source type is created |
||
149 | * by "deriving" from the #GSource structure. The derived type of |
||
150 | * source is represented by a structure that has the #GSource structure |
||
151 | * as a first element, and other elements specific to the new source |
||
152 | * type. To create an instance of the new source type, call |
||
153 | * g_source_new() passing in the size of the derived structure and |
||
154 | * a table of functions. These #GSourceFuncs determine the behavior of |
||
155 | * the new source type. |
||
156 | * |
||
157 | * New source types basically interact with the main context |
||
158 | * in two ways. Their prepare function in #GSourceFuncs can set a timeout |
||
159 | * to determine the maximum amount of time that the main loop will sleep |
||
160 | * before checking the source again. In addition, or as well, the source |
||
161 | * can add file descriptors to the set that the main context checks using |
||
162 | * g_source_add_poll(). |
||
163 | * |
||
164 | * ## Customizing the main loop iteration |
||
165 | * |
||
166 | * Single iterations of a #GMainContext can be run with |
||
167 | * g_main_context_iteration(). In some cases, more detailed control |
||
168 | * of exactly how the details of the main loop work is desired, for |
||
169 | * instance, when integrating the #GMainLoop with an external main loop. |
||
170 | * In such cases, you can call the component functions of |
||
171 | * g_main_context_iteration() directly. These functions are |
||
172 | * g_main_context_prepare(), g_main_context_query(), |
||
173 | * g_main_context_check() and g_main_context_dispatch(). |
||
174 | * |
||
175 | * ## State of a Main Context # {#mainloop-states} |
||
176 | * |
||
177 | * The operation of these functions can best be seen in terms |
||
178 | * of a state diagram, as shown in this image. |
||
179 | * |
||
180 | *  |
||
181 | * |
||
182 | * On UNIX, the GLib mainloop is incompatible with fork(). Any program |
||
183 | * using the mainloop must either exec() or exit() from the child |
||
184 | * without returning to the mainloop. |
||
185 | * |
||
186 | * ## Memory management of sources # {#mainloop-memory-management} |
||
187 | * |
||
188 | * There are two options for memory management of the user data passed to a |
||
189 | * #GSource to be passed to its callback on invocation. This data is provided |
||
190 | * in calls to g_timeout_add(), g_timeout_add_full(), g_idle_add(), etc. and |
||
191 | * more generally, using g_source_set_callback(). This data is typically an |
||
192 | * object which ‘owns’ the timeout or idle callback, such as a widget or a |
||
193 | * network protocol implementation. In many cases, it is an error for the |
||
194 | * callback to be invoked after this owning object has been destroyed, as that |
||
195 | * results in use of freed memory. |
||
196 | * |
||
197 | * The first, and preferred, option is to store the source ID returned by |
||
198 | * functions such as g_timeout_add() or g_source_attach(), and explicitly |
||
199 | * remove that source from the main context using g_source_remove() when the |
||
200 | * owning object is finalized. This ensures that the callback can only be |
||
201 | * invoked while the object is still alive. |
||
202 | * |
||
203 | * The second option is to hold a strong reference to the object in the |
||
204 | * callback, and to release it in the callback’s #GDestroyNotify. This ensures |
||
205 | * that the object is kept alive until after the source is finalized, which is |
||
206 | * guaranteed to be after it is invoked for the final time. The #GDestroyNotify |
||
207 | * is another callback passed to the ‘full’ variants of #GSource functions (for |
||
208 | * example, g_timeout_add_full()). It is called when the source is finalized, |
||
209 | * and is designed for releasing references like this. |
||
210 | * |
||
211 | * One important caveat of this second approach is that it will keep the object |
||
212 | * alive indefinitely if the main loop is stopped before the #GSource is |
||
213 | * invoked, which may be undesirable. |
||
214 | */ |
||
215 | |||
216 | /* Types */ |
||
217 | |||
218 | typedef struct _GTimeoutSource GTimeoutSource; |
||
219 | typedef struct _GChildWatchSource GChildWatchSource; |
||
220 | typedef struct _GUnixSignalWatchSource GUnixSignalWatchSource; |
||
221 | typedef struct _GPollRec GPollRec; |
||
222 | typedef struct _GSourceCallback GSourceCallback; |
||
223 | |||
224 | typedef enum |
||
225 | { |
||
226 | G_SOURCE_READY = 1 << G_HOOK_FLAG_USER_SHIFT, |
||
227 | G_SOURCE_CAN_RECURSE = 1 << (G_HOOK_FLAG_USER_SHIFT + 1), |
||
228 | G_SOURCE_BLOCKED = 1 << (G_HOOK_FLAG_USER_SHIFT + 2) |
||
229 | } GSourceFlags; |
||
230 | |||
231 | typedef struct _GSourceList GSourceList; |
||
232 | |||
233 | struct _GSourceList |
||
234 | { |
||
235 | GSource *head, *tail; |
||
236 | gint priority; |
||
237 | }; |
||
238 | |||
239 | typedef struct _GMainWaiter GMainWaiter; |
||
240 | |||
241 | struct _GMainWaiter |
||
242 | { |
||
243 | GCond *cond; |
||
244 | GMutex *mutex; |
||
245 | }; |
||
246 | |||
247 | typedef struct _GMainDispatch GMainDispatch; |
||
248 | |||
249 | struct _GMainDispatch |
||
250 | { |
||
251 | gint depth; |
||
252 | GSource *source; |
||
253 | }; |
||
254 | |||
255 | #ifdef G_MAIN_POLL_DEBUG |
||
256 | gboolean _g_main_poll_debug = FALSE; |
||
257 | #endif |
||
258 | |||
259 | struct _GMainContext |
||
260 | { |
||
261 | /* The following lock is used for both the list of sources |
||
262 | * and the list of poll records |
||
263 | */ |
||
264 | GMutex mutex; |
||
265 | GCond cond; |
||
266 | GThread *owner; |
||
267 | guint owner_count; |
||
268 | GSList *waiters; |
||
269 | |||
270 | gint ref_count; |
||
271 | |||
272 | GHashTable *sources; /* guint -> GSource */ |
||
273 | |||
274 | GPtrArray *pending_dispatches; |
||
275 | gint timeout; /* Timeout for current iteration */ |
||
276 | |||
277 | guint next_id; |
||
278 | GList *source_lists; |
||
279 | gint in_check_or_prepare; |
||
280 | |||
281 | GPollRec *poll_records; |
||
282 | guint n_poll_records; |
||
283 | GPollFD *cached_poll_array; |
||
284 | guint cached_poll_array_size; |
||
285 | |||
286 | GWakeup *wakeup; |
||
287 | |||
288 | GPollFD wake_up_rec; |
||
289 | |||
290 | /* Flag indicating whether the set of fd's changed during a poll */ |
||
291 | gboolean poll_changed; |
||
292 | |||
293 | GPollFunc poll_func; |
||
294 | |||
295 | gint64 time; |
||
296 | gboolean time_is_fresh; |
||
297 | }; |
||
298 | |||
299 | struct _GSourceCallback |
||
300 | { |
||
301 | guint ref_count; |
||
302 | GSourceFunc func; |
||
303 | gpointer data; |
||
304 | GDestroyNotify notify; |
||
305 | }; |
||
306 | |||
307 | struct _GMainLoop |
||
308 | { |
||
309 | GMainContext *context; |
||
310 | gboolean is_running; |
||
311 | gint ref_count; |
||
312 | }; |
||
313 | |||
314 | struct _GTimeoutSource |
||
315 | { |
||
316 | GSource source; |
||
317 | guint interval; |
||
318 | gboolean seconds; |
||
319 | }; |
||
320 | |||
321 | struct _GChildWatchSource |
||
322 | { |
||
323 | GSource source; |
||
324 | GPid pid; |
||
325 | gint child_status; |
||
326 | #ifdef G_OS_WIN32 |
||
327 | GPollFD poll; |
||
328 | #else /* G_OS_WIN32 */ |
||
329 | gboolean child_exited; |
||
330 | #endif /* G_OS_WIN32 */ |
||
331 | }; |
||
332 | |||
333 | struct _GUnixSignalWatchSource |
||
334 | { |
||
335 | GSource source; |
||
336 | int signum; |
||
337 | gboolean pending; |
||
338 | }; |
||
339 | |||
340 | struct _GPollRec |
||
341 | { |
||
342 | GPollFD *fd; |
||
343 | GPollRec *prev; |
||
344 | GPollRec *next; |
||
345 | gint priority; |
||
346 | }; |
||
347 | |||
348 | struct _GSourcePrivate |
||
349 | { |
||
350 | GSList *child_sources; |
||
351 | GSource *parent_source; |
||
352 | |||
353 | gint64 ready_time; |
||
354 | |||
355 | /* This is currently only used on UNIX, but we always declare it (and |
||
356 | * let it remain empty on Windows) to avoid #ifdef all over the place. |
||
357 | */ |
||
358 | GSList *fds; |
||
359 | }; |
||
360 | |||
361 | typedef struct _GSourceIter |
||
362 | { |
||
363 | GMainContext *context; |
||
364 | gboolean may_modify; |
||
365 | GList *current_list; |
||
366 | GSource *source; |
||
367 | } GSourceIter; |
||
368 | |||
369 | #define LOCK_CONTEXT(context) g_mutex_lock (&context->mutex) |
||
370 | #define UNLOCK_CONTEXT(context) g_mutex_unlock (&context->mutex) |
||
371 | #define G_THREAD_SELF g_thread_self () |
||
372 | |||
373 | #define SOURCE_DESTROYED(source) (((source)->flags & G_HOOK_FLAG_ACTIVE) == 0) |
||
374 | #define SOURCE_BLOCKED(source) (((source)->flags & G_SOURCE_BLOCKED) != 0) |
||
375 | |||
376 | #define SOURCE_UNREF(source, context) \ |
||
377 | G_STMT_START { \ |
||
378 | if ((source)->ref_count > 1) \ |
||
379 | (source)->ref_count--; \ |
||
380 | else \ |
||
381 | g_source_unref_internal ((source), (context), TRUE); \ |
||
382 | } G_STMT_END |
||
383 | |||
384 | |||
385 | /* Forward declarations */ |
||
386 | |||
387 | static void g_source_unref_internal (GSource *source, |
||
388 | GMainContext *context, |
||
389 | gboolean have_lock); |
||
390 | static void g_source_destroy_internal (GSource *source, |
||
391 | GMainContext *context, |
||
392 | gboolean have_lock); |
||
393 | static void g_source_set_priority_unlocked (GSource *source, |
||
394 | GMainContext *context, |
||
395 | gint priority); |
||
396 | static void g_child_source_remove_internal (GSource *child_source, |
||
397 | GMainContext *context); |
||
398 | |||
399 | static void g_main_context_poll (GMainContext *context, |
||
400 | gint timeout, |
||
401 | gint priority, |
||
402 | GPollFD *fds, |
||
403 | gint n_fds); |
||
404 | static void g_main_context_add_poll_unlocked (GMainContext *context, |
||
405 | gint priority, |
||
406 | GPollFD *fd); |
||
407 | static void g_main_context_remove_poll_unlocked (GMainContext *context, |
||
408 | GPollFD *fd); |
||
409 | |||
410 | static void g_source_iter_init (GSourceIter *iter, |
||
411 | GMainContext *context, |
||
412 | gboolean may_modify); |
||
413 | static gboolean g_source_iter_next (GSourceIter *iter, |
||
414 | GSource **source); |
||
415 | static void g_source_iter_clear (GSourceIter *iter); |
||
416 | |||
417 | static gboolean g_timeout_dispatch (GSource *source, |
||
418 | GSourceFunc callback, |
||
419 | gpointer user_data); |
||
420 | static gboolean g_child_watch_prepare (GSource *source, |
||
421 | gint *timeout); |
||
422 | static gboolean g_child_watch_check (GSource *source); |
||
423 | static gboolean g_child_watch_dispatch (GSource *source, |
||
424 | GSourceFunc callback, |
||
425 | gpointer user_data); |
||
426 | static void g_child_watch_finalize (GSource *source); |
||
427 | #ifdef G_OS_UNIX |
||
428 | static void g_unix_signal_handler (int signum); |
||
429 | static gboolean g_unix_signal_watch_prepare (GSource *source, |
||
430 | gint *timeout); |
||
431 | static gboolean g_unix_signal_watch_check (GSource *source); |
||
432 | static gboolean g_unix_signal_watch_dispatch (GSource *source, |
||
433 | GSourceFunc callback, |
||
434 | gpointer user_data); |
||
435 | static void g_unix_signal_watch_finalize (GSource *source); |
||
436 | #endif |
||
437 | static gboolean g_idle_prepare (GSource *source, |
||
438 | gint *timeout); |
||
439 | static gboolean g_idle_check (GSource *source); |
||
440 | static gboolean g_idle_dispatch (GSource *source, |
||
441 | GSourceFunc callback, |
||
442 | gpointer user_data); |
||
443 | |||
444 | static void block_source (GSource *source); |
||
445 | |||
446 | static GMainContext *glib_worker_context; |
||
447 | |||
448 | G_LOCK_DEFINE_STATIC (main_loop); |
||
449 | static GMainContext *default_main_context; |
||
450 | |||
451 | #ifndef G_OS_WIN32 |
||
452 | |||
453 | |||
454 | /* UNIX signals work by marking one of these variables then waking the |
||
455 | * worker context to check on them and dispatch accordingly. |
||
456 | */ |
||
457 | #ifdef HAVE_SIG_ATOMIC_T |
||
458 | static volatile sig_atomic_t unix_signal_pending[NSIG]; |
||
459 | static volatile sig_atomic_t any_unix_signal_pending; |
||
460 | #else |
||
461 | static volatile int unix_signal_pending[NSIG]; |
||
462 | static volatile int any_unix_signal_pending; |
||
463 | #endif |
||
464 | static volatile guint unix_signal_refcount[NSIG]; |
||
465 | |||
466 | /* Guards all the data below */ |
||
467 | G_LOCK_DEFINE_STATIC (unix_signal_lock); |
||
468 | static GSList *unix_signal_watches; |
||
469 | static GSList *unix_child_watches; |
||
470 | |||
471 | GSourceFuncs g_unix_signal_funcs = |
||
472 | { |
||
473 | g_unix_signal_watch_prepare, |
||
474 | g_unix_signal_watch_check, |
||
475 | g_unix_signal_watch_dispatch, |
||
476 | g_unix_signal_watch_finalize |
||
477 | }; |
||
478 | #endif /* !G_OS_WIN32 */ |
||
479 | G_LOCK_DEFINE_STATIC (main_context_list); |
||
480 | static GSList *main_context_list = NULL; |
||
481 | |||
482 | GSourceFuncs g_timeout_funcs = |
||
483 | { |
||
484 | NULL, /* prepare */ |
||
485 | NULL, /* check */ |
||
486 | g_timeout_dispatch, |
||
487 | NULL |
||
488 | }; |
||
489 | |||
490 | GSourceFuncs g_child_watch_funcs = |
||
491 | { |
||
492 | g_child_watch_prepare, |
||
493 | g_child_watch_check, |
||
494 | g_child_watch_dispatch, |
||
495 | g_child_watch_finalize |
||
496 | }; |
||
497 | |||
498 | GSourceFuncs g_idle_funcs = |
||
499 | { |
||
500 | g_idle_prepare, |
||
501 | g_idle_check, |
||
502 | g_idle_dispatch, |
||
503 | NULL |
||
504 | }; |
||
505 | |||
506 | /** |
||
507 | * g_main_context_ref: |
||
508 | * @context: a #GMainContext |
||
509 | * |
||
510 | * Increases the reference count on a #GMainContext object by one. |
||
511 | * |
||
512 | * Returns: the @context that was passed in (since 2.6) |
||
513 | **/ |
||
514 | GMainContext * |
||
515 | g_main_context_ref (GMainContext *context) |
||
516 | { |
||
517 | g_return_val_if_fail (context != NULL, NULL); |
||
518 | g_return_val_if_fail (g_atomic_int_get (&context->ref_count) > 0, NULL); |
||
519 | |||
520 | g_atomic_int_inc (&context->ref_count); |
||
521 | |||
522 | return context; |
||
523 | } |
||
524 | |||
525 | static inline void |
||
526 | poll_rec_list_free (GMainContext *context, |
||
527 | GPollRec *list) |
||
528 | { |
||
529 | g_slice_free_chain (GPollRec, list, next); |
||
530 | } |
||
531 | |||
532 | /** |
||
533 | * g_main_context_unref: |
||
534 | * @context: a #GMainContext |
||
535 | * |
||
536 | * Decreases the reference count on a #GMainContext object by one. If |
||
537 | * the result is zero, free the context and free all associated memory. |
||
538 | **/ |
||
539 | void |
||
540 | g_main_context_unref (GMainContext *context) |
||
541 | { |
||
542 | GSourceIter iter; |
||
543 | GSource *source; |
||
544 | GList *sl_iter; |
||
545 | GSourceList *list; |
||
546 | guint i; |
||
547 | |||
548 | g_return_if_fail (context != NULL); |
||
549 | g_return_if_fail (g_atomic_int_get (&context->ref_count) > 0); |
||
550 | |||
551 | if (!g_atomic_int_dec_and_test (&context->ref_count)) |
||
552 | return; |
||
553 | |||
554 | G_LOCK (main_context_list); |
||
555 | main_context_list = g_slist_remove (main_context_list, context); |
||
556 | G_UNLOCK (main_context_list); |
||
557 | |||
558 | /* Free pending dispatches */ |
||
559 | for (i = 0; i < context->pending_dispatches->len; i++) |
||
560 | g_source_unref_internal (context->pending_dispatches->pdata[i], context, FALSE); |
||
561 | |||
562 | /* g_source_iter_next() assumes the context is locked. */ |
||
563 | LOCK_CONTEXT (context); |
||
564 | g_source_iter_init (&iter, context, TRUE); |
||
565 | while (g_source_iter_next (&iter, &source)) |
||
566 | { |
||
567 | source->context = NULL; |
||
568 | g_source_destroy_internal (source, context, TRUE); |
||
569 | } |
||
570 | UNLOCK_CONTEXT (context); |
||
571 | |||
572 | for (sl_iter = context->source_lists; sl_iter; sl_iter = sl_iter->next) |
||
573 | { |
||
574 | list = sl_iter->data; |
||
575 | g_slice_free (GSourceList, list); |
||
576 | } |
||
577 | g_list_free (context->source_lists); |
||
578 | |||
579 | g_hash_table_destroy (context->sources); |
||
580 | |||
581 | g_mutex_clear (&context->mutex); |
||
582 | |||
583 | g_ptr_array_free (context->pending_dispatches, TRUE); |
||
584 | g_free (context->cached_poll_array); |
||
585 | |||
586 | poll_rec_list_free (context, context->poll_records); |
||
587 | |||
588 | g_wakeup_free (context->wakeup); |
||
589 | g_cond_clear (&context->cond); |
||
590 | |||
591 | g_free (context); |
||
592 | } |
||
593 | |||
594 | /* Helper function used by mainloop/overflow test. |
||
595 | */ |
||
596 | GMainContext * |
||
597 | g_main_context_new_with_next_id (guint next_id) |
||
598 | { |
||
599 | GMainContext *ret = g_main_context_new (); |
||
600 | |||
601 | ret->next_id = next_id; |
||
602 | |||
603 | return ret; |
||
604 | } |
||
605 | |||
606 | /** |
||
607 | * g_main_context_new: |
||
608 | * |
||
609 | * Creates a new #GMainContext structure. |
||
610 | * |
||
611 | * Returns: the new #GMainContext |
||
612 | **/ |
||
613 | GMainContext * |
||
614 | g_main_context_new (void) |
||
615 | { |
||
616 | static gsize initialised; |
||
617 | GMainContext *context; |
||
618 | |||
619 | if (g_once_init_enter (&initialised)) |
||
620 | { |
||
621 | #ifdef G_MAIN_POLL_DEBUG |
||
622 | if (getenv ("G_MAIN_POLL_DEBUG") != NULL) |
||
623 | _g_main_poll_debug = TRUE; |
||
624 | #endif |
||
625 | |||
626 | g_once_init_leave (&initialised, TRUE); |
||
627 | } |
||
628 | |||
629 | context = g_new0 (GMainContext, 1); |
||
630 | |||
631 | g_mutex_init (&context->mutex); |
||
632 | g_cond_init (&context->cond); |
||
633 | |||
634 | context->sources = g_hash_table_new (NULL, NULL); |
||
635 | context->owner = NULL; |
||
636 | context->waiters = NULL; |
||
637 | |||
638 | context->ref_count = 1; |
||
639 | |||
640 | context->next_id = 1; |
||
641 | |||
642 | context->source_lists = NULL; |
||
643 | |||
644 | context->poll_func = g_poll; |
||
645 | |||
646 | context->cached_poll_array = NULL; |
||
647 | context->cached_poll_array_size = 0; |
||
648 | |||
649 | context->pending_dispatches = g_ptr_array_new (); |
||
650 | |||
651 | context->time_is_fresh = FALSE; |
||
652 | |||
653 | context->wakeup = g_wakeup_new (); |
||
654 | g_wakeup_get_pollfd (context->wakeup, &context->wake_up_rec); |
||
655 | g_main_context_add_poll_unlocked (context, 0, &context->wake_up_rec); |
||
656 | |||
657 | G_LOCK (main_context_list); |
||
658 | main_context_list = g_slist_append (main_context_list, context); |
||
659 | |||
660 | #ifdef G_MAIN_POLL_DEBUG |
||
661 | if (_g_main_poll_debug) |
||
662 | g_print ("created context=%p\n", context); |
||
663 | #endif |
||
664 | |||
665 | G_UNLOCK (main_context_list); |
||
666 | |||
667 | return context; |
||
668 | } |
||
669 | |||
670 | /** |
||
671 | * g_main_context_default: |
||
672 | * |
||
673 | * Returns the global default main context. This is the main context |
||
674 | * used for main loop functions when a main loop is not explicitly |
||
675 | * specified, and corresponds to the "main" main loop. See also |
||
676 | * g_main_context_get_thread_default(). |
||
677 | * |
||
678 | * Returns: (transfer none): the global default main context. |
||
679 | **/ |
||
680 | GMainContext * |
||
681 | g_main_context_default (void) |
||
682 | { |
||
683 | /* Slow, but safe */ |
||
684 | |||
685 | G_LOCK (main_loop); |
||
686 | |||
687 | if (!default_main_context) |
||
688 | { |
||
689 | default_main_context = g_main_context_new (); |
||
690 | #ifdef G_MAIN_POLL_DEBUG |
||
691 | if (_g_main_poll_debug) |
||
692 | g_print ("default context=%p\n", default_main_context); |
||
693 | #endif |
||
694 | } |
||
695 | |||
696 | G_UNLOCK (main_loop); |
||
697 | |||
698 | return default_main_context; |
||
699 | } |
||
700 | |||
701 | static void |
||
702 | free_context (gpointer data) |
||
703 | { |
||
704 | GMainContext *context = data; |
||
705 | |||
706 | g_main_context_release (context); |
||
707 | if (context) |
||
708 | g_main_context_unref (context); |
||
709 | } |
||
710 | |||
711 | static void |
||
712 | free_context_stack (gpointer data) |
||
713 | { |
||
714 | g_queue_free_full((GQueue *) data, (GDestroyNotify) free_context); |
||
715 | } |
||
716 | |||
717 | static GPrivate thread_context_stack = G_PRIVATE_INIT (free_context_stack); |
||
718 | |||
719 | /** |
||
720 | * g_main_context_push_thread_default: |
||
721 | * @context: (allow-none): a #GMainContext, or %NULL for the global default context |
||
722 | * |
||
723 | * Acquires @context and sets it as the thread-default context for the |
||
724 | * current thread. This will cause certain asynchronous operations |
||
725 | * (such as most [gio][gio]-based I/O) which are |
||
726 | * started in this thread to run under @context and deliver their |
||
727 | * results to its main loop, rather than running under the global |
||
728 | * default context in the main thread. Note that calling this function |
||
729 | * changes the context returned by g_main_context_get_thread_default(), |
||
730 | * not the one returned by g_main_context_default(), so it does not affect |
||
731 | * the context used by functions like g_idle_add(). |
||
732 | * |
||
733 | * Normally you would call this function shortly after creating a new |
||
734 | * thread, passing it a #GMainContext which will be run by a |
||
735 | * #GMainLoop in that thread, to set a new default context for all |
||
736 | * async operations in that thread. (In this case, you don't need to |
||
737 | * ever call g_main_context_pop_thread_default().) In some cases |
||
738 | * however, you may want to schedule a single operation in a |
||
739 | * non-default context, or temporarily use a non-default context in |
||
740 | * the main thread. In that case, you can wrap the call to the |
||
741 | * asynchronous operation inside a |
||
742 | * g_main_context_push_thread_default() / |
||
743 | * g_main_context_pop_thread_default() pair, but it is up to you to |
||
744 | * ensure that no other asynchronous operations accidentally get |
||
745 | * started while the non-default context is active. |
||
746 | * |
||
747 | * Beware that libraries that predate this function may not correctly |
||
748 | * handle being used from a thread with a thread-default context. Eg, |
||
749 | * see g_file_supports_thread_contexts(). |
||
750 | * |
||
751 | * Since: 2.22 |
||
752 | **/ |
||
753 | void |
||
754 | g_main_context_push_thread_default (GMainContext *context) |
||
755 | { |
||
756 | GQueue *stack; |
||
757 | gboolean acquired_context; |
||
758 | |||
759 | acquired_context = g_main_context_acquire (context); |
||
760 | g_return_if_fail (acquired_context); |
||
761 | |||
762 | if (context == g_main_context_default ()) |
||
763 | context = NULL; |
||
764 | else if (context) |
||
765 | g_main_context_ref (context); |
||
766 | |||
767 | stack = g_private_get (&thread_context_stack); |
||
768 | if (!stack) |
||
769 | { |
||
770 | stack = g_queue_new (); |
||
771 | g_private_set (&thread_context_stack, stack); |
||
772 | } |
||
773 | |||
774 | g_queue_push_head (stack, context); |
||
775 | } |
||
776 | |||
777 | /** |
||
778 | * g_main_context_pop_thread_default: |
||
779 | * @context: (allow-none): a #GMainContext object, or %NULL |
||
780 | * |
||
781 | * Pops @context off the thread-default context stack (verifying that |
||
782 | * it was on the top of the stack). |
||
783 | * |
||
784 | * Since: 2.22 |
||
785 | **/ |
||
786 | void |
||
787 | g_main_context_pop_thread_default (GMainContext *context) |
||
788 | { |
||
789 | GQueue *stack; |
||
790 | |||
791 | if (context == g_main_context_default ()) |
||
792 | context = NULL; |
||
793 | |||
794 | stack = g_private_get (&thread_context_stack); |
||
795 | |||
796 | g_return_if_fail (stack != NULL); |
||
797 | g_return_if_fail (g_queue_peek_head (stack) == context); |
||
798 | |||
799 | g_queue_pop_head (stack); |
||
800 | |||
801 | g_main_context_release (context); |
||
802 | if (context) |
||
803 | g_main_context_unref (context); |
||
804 | } |
||
805 | |||
806 | /** |
||
807 | * g_main_context_get_thread_default: |
||
808 | * |
||
809 | * Gets the thread-default #GMainContext for this thread. Asynchronous |
||
810 | * operations that want to be able to be run in contexts other than |
||
811 | * the default one should call this method or |
||
812 | * g_main_context_ref_thread_default() to get a #GMainContext to add |
||
813 | * their #GSources to. (Note that even in single-threaded |
||
814 | * programs applications may sometimes want to temporarily push a |
||
815 | * non-default context, so it is not safe to assume that this will |
||
816 | * always return %NULL if you are running in the default thread.) |
||
817 | * |
||
818 | * If you need to hold a reference on the context, use |
||
819 | * g_main_context_ref_thread_default() instead. |
||
820 | * |
||
821 | * Returns: (transfer none): the thread-default #GMainContext, or |
||
822 | * %NULL if the thread-default context is the global default context. |
||
823 | * |
||
824 | * Since: 2.22 |
||
825 | **/ |
||
826 | GMainContext * |
||
827 | g_main_context_get_thread_default (void) |
||
828 | { |
||
829 | GQueue *stack; |
||
830 | |||
831 | stack = g_private_get (&thread_context_stack); |
||
832 | if (stack) |
||
833 | return g_queue_peek_head (stack); |
||
834 | else |
||
835 | return NULL; |
||
836 | } |
||
837 | |||
838 | /** |
||
839 | * g_main_context_ref_thread_default: |
||
840 | * |
||
841 | * Gets the thread-default #GMainContext for this thread, as with |
||
842 | * g_main_context_get_thread_default(), but also adds a reference to |
||
843 | * it with g_main_context_ref(). In addition, unlike |
||
844 | * g_main_context_get_thread_default(), if the thread-default context |
||
845 | * is the global default context, this will return that #GMainContext |
||
846 | * (with a ref added to it) rather than returning %NULL. |
||
847 | * |
||
848 | * Returns: (transfer full): the thread-default #GMainContext. Unref |
||
849 | * with g_main_context_unref() when you are done with it. |
||
850 | * |
||
851 | * Since: 2.32 |
||
852 | */ |
||
853 | GMainContext * |
||
854 | g_main_context_ref_thread_default (void) |
||
855 | { |
||
856 | GMainContext *context; |
||
857 | |||
858 | context = g_main_context_get_thread_default (); |
||
859 | if (!context) |
||
860 | context = g_main_context_default (); |
||
861 | return g_main_context_ref (context); |
||
862 | } |
||
863 | |||
864 | /* Hooks for adding to the main loop */ |
||
865 | |||
866 | /** |
||
867 | * g_source_new: |
||
868 | * @source_funcs: structure containing functions that implement |
||
869 | * the sources behavior. |
||
870 | * @struct_size: size of the #GSource structure to create. |
||
871 | * |
||
872 | * Creates a new #GSource structure. The size is specified to |
||
873 | * allow creating structures derived from #GSource that contain |
||
874 | * additional data. The size passed in must be at least |
||
875 | * `sizeof (GSource)`. |
||
876 | * |
||
877 | * The source will not initially be associated with any #GMainContext |
||
878 | * and must be added to one with g_source_attach() before it will be |
||
879 | * executed. |
||
880 | * |
||
881 | * Returns: the newly-created #GSource. |
||
882 | **/ |
||
883 | GSource * |
||
884 | g_source_new (GSourceFuncs *source_funcs, |
||
885 | guint struct_size) |
||
886 | { |
||
887 | GSource *source; |
||
888 | |||
889 | g_return_val_if_fail (source_funcs != NULL, NULL); |
||
890 | g_return_val_if_fail (struct_size >= sizeof (GSource), NULL); |
||
891 | |||
892 | source = (GSource*) g_malloc0 (struct_size); |
||
893 | source->priv = g_slice_new0 (GSourcePrivate); |
||
894 | source->source_funcs = source_funcs; |
||
895 | source->ref_count = 1; |
||
896 | |||
897 | source->priority = G_PRIORITY_DEFAULT; |
||
898 | |||
899 | source->flags = G_HOOK_FLAG_ACTIVE; |
||
900 | |||
901 | source->priv->ready_time = -1; |
||
902 | |||
903 | /* NULL/0 initialization for all other fields */ |
||
904 | |||
905 | return source; |
||
906 | } |
||
907 | |||
908 | /* Holds context's lock */ |
||
909 | static void |
||
910 | g_source_iter_init (GSourceIter *iter, |
||
911 | GMainContext *context, |
||
912 | gboolean may_modify) |
||
913 | { |
||
914 | iter->context = context; |
||
915 | iter->current_list = NULL; |
||
916 | iter->source = NULL; |
||
917 | iter->may_modify = may_modify; |
||
918 | } |
||
919 | |||
920 | /* Holds context's lock */ |
||
921 | static gboolean |
||
922 | g_source_iter_next (GSourceIter *iter, GSource **source) |
||
923 | { |
||
924 | GSource *next_source; |
||
925 | |||
926 | if (iter->source) |
||
927 | next_source = iter->source->next; |
||
928 | else |
||
929 | next_source = NULL; |
||
930 | |||
931 | if (!next_source) |
||
932 | { |
||
933 | if (iter->current_list) |
||
934 | iter->current_list = iter->current_list->next; |
||
935 | else |
||
936 | iter->current_list = iter->context->source_lists; |
||
937 | |||
938 | if (iter->current_list) |
||
939 | { |
||
940 | GSourceList *source_list = iter->current_list->data; |
||
941 | |||
942 | next_source = source_list->head; |
||
943 | } |
||
944 | } |
||
945 | |||
946 | /* Note: unreffing iter->source could potentially cause its |
||
947 | * GSourceList to be removed from source_lists (if iter->source is |
||
948 | * the only source in its list, and it is destroyed), so we have to |
||
949 | * keep it reffed until after we advance iter->current_list, above. |
||
950 | */ |
||
951 | |||
952 | if (iter->source && iter->may_modify) |
||
953 | SOURCE_UNREF (iter->source, iter->context); |
||
954 | iter->source = next_source; |
||
955 | if (iter->source && iter->may_modify) |
||
956 | iter->source->ref_count++; |
||
957 | |||
958 | *source = iter->source; |
||
959 | return *source != NULL; |
||
960 | } |
||
961 | |||
962 | /* Holds context's lock. Only necessary to call if you broke out of |
||
963 | * the g_source_iter_next() loop early. |
||
964 | */ |
||
965 | static void |
||
966 | g_source_iter_clear (GSourceIter *iter) |
||
967 | { |
||
968 | if (iter->source && iter->may_modify) |
||
969 | { |
||
970 | SOURCE_UNREF (iter->source, iter->context); |
||
971 | iter->source = NULL; |
||
972 | } |
||
973 | } |
||
974 | |||
975 | /* Holds context's lock |
||
976 | */ |
||
977 | static GSourceList * |
||
978 | find_source_list_for_priority (GMainContext *context, |
||
979 | gint priority, |
||
980 | gboolean create) |
||
981 | { |
||
982 | GList *iter, *last; |
||
983 | GSourceList *source_list; |
||
984 | |||
985 | last = NULL; |
||
986 | for (iter = context->source_lists; iter != NULL; last = iter, iter = iter->next) |
||
987 | { |
||
988 | source_list = iter->data; |
||
989 | |||
990 | if (source_list->priority == priority) |
||
991 | return source_list; |
||
992 | |||
993 | if (source_list->priority > priority) |
||
994 | { |
||
995 | if (!create) |
||
996 | return NULL; |
||
997 | |||
998 | source_list = g_slice_new0 (GSourceList); |
||
999 | source_list->priority = priority; |
||
1000 | context->source_lists = g_list_insert_before (context->source_lists, |
||
1001 | iter, |
||
1002 | source_list); |
||
1003 | return source_list; |
||
1004 | } |
||
1005 | } |
||
1006 | |||
1007 | if (!create) |
||
1008 | return NULL; |
||
1009 | |||
1010 | source_list = g_slice_new0 (GSourceList); |
||
1011 | source_list->priority = priority; |
||
1012 | |||
1013 | if (!last) |
||
1014 | context->source_lists = g_list_append (NULL, source_list); |
||
1015 | else |
||
1016 | { |
||
1017 | /* This just appends source_list to the end of |
||
1018 | * context->source_lists without having to walk the list again. |
||
1019 | */ |
||
1020 | last = g_list_append (last, source_list); |
||
1021 | } |
||
1022 | return source_list; |
||
1023 | } |
||
1024 | |||
1025 | /* Holds context's lock |
||
1026 | */ |
||
1027 | static void |
||
1028 | source_add_to_context (GSource *source, |
||
1029 | GMainContext *context) |
||
1030 | { |
||
1031 | GSourceList *source_list; |
||
1032 | GSource *prev, *next; |
||
1033 | |||
1034 | source_list = find_source_list_for_priority (context, source->priority, TRUE); |
||
1035 | |||
1036 | if (source->priv->parent_source) |
||
1037 | { |
||
1038 | g_assert (source_list->head != NULL); |
||
1039 | |||
1040 | /* Put the source immediately before its parent */ |
||
1041 | prev = source->priv->parent_source->prev; |
||
1042 | next = source->priv->parent_source; |
||
1043 | } |
||
1044 | else |
||
1045 | { |
||
1046 | prev = source_list->tail; |
||
1047 | next = NULL; |
||
1048 | } |
||
1049 | |||
1050 | source->next = next; |
||
1051 | if (next) |
||
1052 | next->prev = source; |
||
1053 | else |
||
1054 | source_list->tail = source; |
||
1055 | |||
1056 | source->prev = prev; |
||
1057 | if (prev) |
||
1058 | prev->next = source; |
||
1059 | else |
||
1060 | source_list->head = source; |
||
1061 | } |
||
1062 | |||
1063 | /* Holds context's lock |
||
1064 | */ |
||
1065 | static void |
||
1066 | source_remove_from_context (GSource *source, |
||
1067 | GMainContext *context) |
||
1068 | { |
||
1069 | GSourceList *source_list; |
||
1070 | |||
1071 | source_list = find_source_list_for_priority (context, source->priority, FALSE); |
||
1072 | g_return_if_fail (source_list != NULL); |
||
1073 | |||
1074 | if (source->prev) |
||
1075 | source->prev->next = source->next; |
||
1076 | else |
||
1077 | source_list->head = source->next; |
||
1078 | |||
1079 | if (source->next) |
||
1080 | source->next->prev = source->prev; |
||
1081 | else |
||
1082 | source_list->tail = source->prev; |
||
1083 | |||
1084 | source->prev = NULL; |
||
1085 | source->next = NULL; |
||
1086 | |||
1087 | if (source_list->head == NULL) |
||
1088 | { |
||
1089 | context->source_lists = g_list_remove (context->source_lists, source_list); |
||
1090 | g_slice_free (GSourceList, source_list); |
||
1091 | } |
||
1092 | } |
||
1093 | |||
1094 | static guint |
||
1095 | g_source_attach_unlocked (GSource *source, |
||
1096 | GMainContext *context, |
||
1097 | gboolean do_wakeup) |
||
1098 | { |
||
1099 | GSList *tmp_list; |
||
1100 | guint id; |
||
1101 | |||
1102 | /* The counter may have wrapped, so we must ensure that we do not |
||
1103 | * reuse the source id of an existing source. |
||
1104 | */ |
||
1105 | do |
||
1106 | id = context->next_id++; |
||
1107 | while (id == 0 || g_hash_table_contains (context->sources, GUINT_TO_POINTER (id))); |
||
1108 | |||
1109 | source->context = context; |
||
1110 | source->source_id = id; |
||
1111 | source->ref_count++; |
||
1112 | |||
1113 | g_hash_table_insert (context->sources, GUINT_TO_POINTER (id), source); |
||
1114 | |||
1115 | source_add_to_context (source, context); |
||
1116 | |||
1117 | if (!SOURCE_BLOCKED (source)) |
||
1118 | { |
||
1119 | tmp_list = source->poll_fds; |
||
1120 | while (tmp_list) |
||
1121 | { |
||
1122 | g_main_context_add_poll_unlocked (context, source->priority, tmp_list->data); |
||
1123 | tmp_list = tmp_list->next; |
||
1124 | } |
||
1125 | |||
1126 | for (tmp_list = source->priv->fds; tmp_list; tmp_list = tmp_list->next) |
||
1127 | g_main_context_add_poll_unlocked (context, source->priority, tmp_list->data); |
||
1128 | } |
||
1129 | |||
1130 | tmp_list = source->priv->child_sources; |
||
1131 | while (tmp_list) |
||
1132 | { |
||
1133 | g_source_attach_unlocked (tmp_list->data, context, FALSE); |
||
1134 | tmp_list = tmp_list->next; |
||
1135 | } |
||
1136 | |||
1137 | /* If another thread has acquired the context, wake it up since it |
||
1138 | * might be in poll() right now. |
||
1139 | */ |
||
1140 | if (do_wakeup && context->owner && context->owner != G_THREAD_SELF) |
||
1141 | g_wakeup_signal (context->wakeup); |
||
1142 | |||
1143 | return source->source_id; |
||
1144 | } |
||
1145 | |||
1146 | /** |
||
1147 | * g_source_attach: |
||
1148 | * @source: a #GSource |
||
1149 | * @context: (allow-none): a #GMainContext (if %NULL, the default context will be used) |
||
1150 | * |
||
1151 | * Adds a #GSource to a @context so that it will be executed within |
||
1152 | * that context. Remove it by calling g_source_destroy(). |
||
1153 | * |
||
1154 | * Returns: the ID (greater than 0) for the source within the |
||
1155 | * #GMainContext. |
||
1156 | **/ |
||
1157 | guint |
||
1158 | g_source_attach (GSource *source, |
||
1159 | GMainContext *context) |
||
1160 | { |
||
1161 | guint result = 0; |
||
1162 | |||
1163 | g_return_val_if_fail (source->context == NULL, 0); |
||
1164 | g_return_val_if_fail (!SOURCE_DESTROYED (source), 0); |
||
1165 | |||
1166 | TRACE (GLIB_MAIN_SOURCE_ATTACH (g_source_get_name (source))); |
||
1167 | |||
1168 | if (!context) |
||
1169 | context = g_main_context_default (); |
||
1170 | |||
1171 | LOCK_CONTEXT (context); |
||
1172 | |||
1173 | result = g_source_attach_unlocked (source, context, TRUE); |
||
1174 | |||
1175 | UNLOCK_CONTEXT (context); |
||
1176 | |||
1177 | return result; |
||
1178 | } |
||
1179 | |||
1180 | static void |
||
1181 | g_source_destroy_internal (GSource *source, |
||
1182 | GMainContext *context, |
||
1183 | gboolean have_lock) |
||
1184 | { |
||
1185 | TRACE (GLIB_MAIN_SOURCE_DESTROY (g_source_get_name (source))); |
||
1186 | |||
1187 | if (!have_lock) |
||
1188 | LOCK_CONTEXT (context); |
||
1189 | |||
1190 | if (!SOURCE_DESTROYED (source)) |
||
1191 | { |
||
1192 | GSList *tmp_list; |
||
1193 | gpointer old_cb_data; |
||
1194 | GSourceCallbackFuncs *old_cb_funcs; |
||
1195 | |||
1196 | source->flags &= ~G_HOOK_FLAG_ACTIVE; |
||
1197 | |||
1198 | old_cb_data = source->callback_data; |
||
1199 | old_cb_funcs = source->callback_funcs; |
||
1200 | |||
1201 | source->callback_data = NULL; |
||
1202 | source->callback_funcs = NULL; |
||
1203 | |||
1204 | if (old_cb_funcs) |
||
1205 | { |
||
1206 | UNLOCK_CONTEXT (context); |
||
1207 | old_cb_funcs->unref (old_cb_data); |
||
1208 | LOCK_CONTEXT (context); |
||
1209 | } |
||
1210 | |||
1211 | if (!SOURCE_BLOCKED (source)) |
||
1212 | { |
||
1213 | tmp_list = source->poll_fds; |
||
1214 | while (tmp_list) |
||
1215 | { |
||
1216 | g_main_context_remove_poll_unlocked (context, tmp_list->data); |
||
1217 | tmp_list = tmp_list->next; |
||
1218 | } |
||
1219 | |||
1220 | for (tmp_list = source->priv->fds; tmp_list; tmp_list = tmp_list->next) |
||
1221 | g_main_context_remove_poll_unlocked (context, tmp_list->data); |
||
1222 | } |
||
1223 | |||
1224 | while (source->priv->child_sources) |
||
1225 | g_child_source_remove_internal (source->priv->child_sources->data, context); |
||
1226 | |||
1227 | if (source->priv->parent_source) |
||
1228 | g_child_source_remove_internal (source, context); |
||
1229 | |||
1230 | g_source_unref_internal (source, context, TRUE); |
||
1231 | } |
||
1232 | |||
1233 | if (!have_lock) |
||
1234 | UNLOCK_CONTEXT (context); |
||
1235 | } |
||
1236 | |||
1237 | /** |
||
1238 | * g_source_destroy: |
||
1239 | * @source: a #GSource |
||
1240 | * |
||
1241 | * Removes a source from its #GMainContext, if any, and mark it as |
||
1242 | * destroyed. The source cannot be subsequently added to another |
||
1243 | * context. It is safe to call this on sources which have already been |
||
1244 | * removed from their context. |
||
1245 | **/ |
||
1246 | void |
||
1247 | g_source_destroy (GSource *source) |
||
1248 | { |
||
1249 | GMainContext *context; |
||
1250 | |||
1251 | g_return_if_fail (source != NULL); |
||
1252 | |||
1253 | context = source->context; |
||
1254 | |||
1255 | if (context) |
||
1256 | g_source_destroy_internal (source, context, FALSE); |
||
1257 | else |
||
1258 | source->flags &= ~G_HOOK_FLAG_ACTIVE; |
||
1259 | } |
||
1260 | |||
1261 | /** |
||
1262 | * g_source_get_id: |
||
1263 | * @source: a #GSource |
||
1264 | * |
||
1265 | * Returns the numeric ID for a particular source. The ID of a source |
||
1266 | * is a positive integer which is unique within a particular main loop |
||
1267 | * context. The reverse |
||
1268 | * mapping from ID to source is done by g_main_context_find_source_by_id(). |
||
1269 | * |
||
1270 | * Returns: the ID (greater than 0) for the source |
||
1271 | **/ |
||
1272 | guint |
||
1273 | g_source_get_id (GSource *source) |
||
1274 | { |
||
1275 | guint result; |
||
1276 | |||
1277 | g_return_val_if_fail (source != NULL, 0); |
||
1278 | g_return_val_if_fail (source->context != NULL, 0); |
||
1279 | |||
1280 | LOCK_CONTEXT (source->context); |
||
1281 | result = source->source_id; |
||
1282 | UNLOCK_CONTEXT (source->context); |
||
1283 | |||
1284 | return result; |
||
1285 | } |
||
1286 | |||
1287 | /** |
||
1288 | * g_source_get_context: |
||
1289 | * @source: a #GSource |
||
1290 | * |
||
1291 | * Gets the #GMainContext with which the source is associated. |
||
1292 | * |
||
1293 | * You can call this on a source that has been destroyed, provided |
||
1294 | * that the #GMainContext it was attached to still exists (in which |
||
1295 | * case it will return that #GMainContext). In particular, you can |
||
1296 | * always call this function on the source returned from |
||
1297 | * g_main_current_source(). But calling this function on a source |
||
1298 | * whose #GMainContext has been destroyed is an error. |
||
1299 | * |
||
1300 | * Returns: (transfer none) (allow-none): the #GMainContext with which the |
||
1301 | * source is associated, or %NULL if the context has not |
||
1302 | * yet been added to a source. |
||
1303 | **/ |
||
1304 | GMainContext * |
||
1305 | g_source_get_context (GSource *source) |
||
1306 | { |
||
1307 | g_return_val_if_fail (source->context != NULL || !SOURCE_DESTROYED (source), NULL); |
||
1308 | |||
1309 | return source->context; |
||
1310 | } |
||
1311 | |||
1312 | /** |
||
1313 | * g_source_add_poll: |
||
1314 | * @source:a #GSource |
||
1315 | * @fd: a #GPollFD structure holding information about a file |
||
1316 | * descriptor to watch. |
||
1317 | * |
||
1318 | * Adds a file descriptor to the set of file descriptors polled for |
||
1319 | * this source. This is usually combined with g_source_new() to add an |
||
1320 | * event source. The event source's check function will typically test |
||
1321 | * the @revents field in the #GPollFD struct and return %TRUE if events need |
||
1322 | * to be processed. |
||
1323 | * |
||
1324 | * This API is only intended to be used by implementations of #GSource. |
||
1325 | * Do not call this API on a #GSource that you did not create. |
||
1326 | * |
||
1327 | * Using this API forces the linear scanning of event sources on each |
||
1328 | * main loop iteration. Newly-written event sources should try to use |
||
1329 | * g_source_add_unix_fd() instead of this API. |
||
1330 | **/ |
||
1331 | void |
||
1332 | g_source_add_poll (GSource *source, |
||
1333 | GPollFD *fd) |
||
1334 | { |
||
1335 | GMainContext *context; |
||
1336 | |||
1337 | g_return_if_fail (source != NULL); |
||
1338 | g_return_if_fail (fd != NULL); |
||
1339 | g_return_if_fail (!SOURCE_DESTROYED (source)); |
||
1340 | |||
1341 | context = source->context; |
||
1342 | |||
1343 | if (context) |
||
1344 | LOCK_CONTEXT (context); |
||
1345 | |||
1346 | source->poll_fds = g_slist_prepend (source->poll_fds, fd); |
||
1347 | |||
1348 | if (context) |
||
1349 | { |
||
1350 | if (!SOURCE_BLOCKED (source)) |
||
1351 | g_main_context_add_poll_unlocked (context, source->priority, fd); |
||
1352 | UNLOCK_CONTEXT (context); |
||
1353 | } |
||
1354 | } |
||
1355 | |||
1356 | /** |
||
1357 | * g_source_remove_poll: |
||
1358 | * @source:a #GSource |
||
1359 | * @fd: a #GPollFD structure previously passed to g_source_add_poll(). |
||
1360 | * |
||
1361 | * Removes a file descriptor from the set of file descriptors polled for |
||
1362 | * this source. |
||
1363 | * |
||
1364 | * This API is only intended to be used by implementations of #GSource. |
||
1365 | * Do not call this API on a #GSource that you did not create. |
||
1366 | **/ |
||
1367 | void |
||
1368 | g_source_remove_poll (GSource *source, |
||
1369 | GPollFD *fd) |
||
1370 | { |
||
1371 | GMainContext *context; |
||
1372 | |||
1373 | g_return_if_fail (source != NULL); |
||
1374 | g_return_if_fail (fd != NULL); |
||
1375 | g_return_if_fail (!SOURCE_DESTROYED (source)); |
||
1376 | |||
1377 | context = source->context; |
||
1378 | |||
1379 | if (context) |
||
1380 | LOCK_CONTEXT (context); |
||
1381 | |||
1382 | source->poll_fds = g_slist_remove (source->poll_fds, fd); |
||
1383 | |||
1384 | if (context) |
||
1385 | { |
||
1386 | if (!SOURCE_BLOCKED (source)) |
||
1387 | g_main_context_remove_poll_unlocked (context, fd); |
||
1388 | UNLOCK_CONTEXT (context); |
||
1389 | } |
||
1390 | } |
||
1391 | |||
1392 | /** |
||
1393 | * g_source_add_child_source: |
||
1394 | * @source:a #GSource |
||
1395 | * @child_source: a second #GSource that @source should "poll" |
||
1396 | * |
||
1397 | * Adds @child_source to @source as a "polled" source; when @source is |
||
1398 | * added to a #GMainContext, @child_source will be automatically added |
||
1399 | * with the same priority, when @child_source is triggered, it will |
||
1400 | * cause @source to dispatch (in addition to calling its own |
||
1401 | * callback), and when @source is destroyed, it will destroy |
||
1402 | * @child_source as well. (@source will also still be dispatched if |
||
1403 | * its own prepare/check functions indicate that it is ready.) |
||
1404 | * |
||
1405 | * If you don't need @child_source to do anything on its own when it |
||
1406 | * triggers, you can call g_source_set_dummy_callback() on it to set a |
||
1407 | * callback that does nothing (except return %TRUE if appropriate). |
||
1408 | * |
||
1409 | * @source will hold a reference on @child_source while @child_source |
||
1410 | * is attached to it. |
||
1411 | * |
||
1412 | * This API is only intended to be used by implementations of #GSource. |
||
1413 | * Do not call this API on a #GSource that you did not create. |
||
1414 | * |
||
1415 | * Since: 2.28 |
||
1416 | **/ |
||
1417 | void |
||
1418 | g_source_add_child_source (GSource *source, |
||
1419 | GSource *child_source) |
||
1420 | { |
||
1421 | GMainContext *context; |
||
1422 | |||
1423 | g_return_if_fail (source != NULL); |
||
1424 | g_return_if_fail (child_source != NULL); |
||
1425 | g_return_if_fail (!SOURCE_DESTROYED (source)); |
||
1426 | g_return_if_fail (!SOURCE_DESTROYED (child_source)); |
||
1427 | g_return_if_fail (child_source->context == NULL); |
||
1428 | g_return_if_fail (child_source->priv->parent_source == NULL); |
||
1429 | |||
1430 | context = source->context; |
||
1431 | |||
1432 | if (context) |
||
1433 | LOCK_CONTEXT (context); |
||
1434 | |||
1435 | source->priv->child_sources = g_slist_prepend (source->priv->child_sources, |
||
1436 | g_source_ref (child_source)); |
||
1437 | child_source->priv->parent_source = source; |
||
1438 | g_source_set_priority_unlocked (child_source, NULL, source->priority); |
||
1439 | if (SOURCE_BLOCKED (source)) |
||
1440 | block_source (child_source); |
||
1441 | |||
1442 | if (context) |
||
1443 | { |
||
1444 | g_source_attach_unlocked (child_source, context, TRUE); |
||
1445 | UNLOCK_CONTEXT (context); |
||
1446 | } |
||
1447 | } |
||
1448 | |||
1449 | static void |
||
1450 | g_child_source_remove_internal (GSource *child_source, |
||
1451 | GMainContext *context) |
||
1452 | { |
||
1453 | GSource *parent_source = child_source->priv->parent_source; |
||
1454 | |||
1455 | parent_source->priv->child_sources = |
||
1456 | g_slist_remove (parent_source->priv->child_sources, child_source); |
||
1457 | child_source->priv->parent_source = NULL; |
||
1458 | |||
1459 | g_source_destroy_internal (child_source, context, TRUE); |
||
1460 | g_source_unref_internal (child_source, context, TRUE); |
||
1461 | } |
||
1462 | |||
1463 | /** |
||
1464 | * g_source_remove_child_source: |
||
1465 | * @source:a #GSource |
||
1466 | * @child_source: a #GSource previously passed to |
||
1467 | * g_source_add_child_source(). |
||
1468 | * |
||
1469 | * Detaches @child_source from @source and destroys it. |
||
1470 | * |
||
1471 | * This API is only intended to be used by implementations of #GSource. |
||
1472 | * Do not call this API on a #GSource that you did not create. |
||
1473 | * |
||
1474 | * Since: 2.28 |
||
1475 | **/ |
||
1476 | void |
||
1477 | g_source_remove_child_source (GSource *source, |
||
1478 | GSource *child_source) |
||
1479 | { |
||
1480 | GMainContext *context; |
||
1481 | |||
1482 | g_return_if_fail (source != NULL); |
||
1483 | g_return_if_fail (child_source != NULL); |
||
1484 | g_return_if_fail (child_source->priv->parent_source == source); |
||
1485 | g_return_if_fail (!SOURCE_DESTROYED (source)); |
||
1486 | g_return_if_fail (!SOURCE_DESTROYED (child_source)); |
||
1487 | |||
1488 | context = source->context; |
||
1489 | |||
1490 | if (context) |
||
1491 | LOCK_CONTEXT (context); |
||
1492 | |||
1493 | g_child_source_remove_internal (child_source, context); |
||
1494 | |||
1495 | if (context) |
||
1496 | UNLOCK_CONTEXT (context); |
||
1497 | } |
||
1498 | |||
1499 | /** |
||
1500 | * g_source_set_callback_indirect: |
||
1501 | * @source: the source |
||
1502 | * @callback_data: pointer to callback data "object" |
||
1503 | * @callback_funcs: functions for reference counting @callback_data |
||
1504 | * and getting the callback and data |
||
1505 | * |
||
1506 | * Sets the callback function storing the data as a refcounted callback |
||
1507 | * "object". This is used internally. Note that calling |
||
1508 | * g_source_set_callback_indirect() assumes |
||
1509 | * an initial reference count on @callback_data, and thus |
||
1510 | * @callback_funcs->unref will eventually be called once more |
||
1511 | * than @callback_funcs->ref. |
||
1512 | **/ |
||
1513 | void |
||
1514 | g_source_set_callback_indirect (GSource *source, |
||
1515 | gpointer callback_data, |
||
1516 | GSourceCallbackFuncs *callback_funcs) |
||
1517 | { |
||
1518 | GMainContext *context; |
||
1519 | gpointer old_cb_data; |
||
1520 | GSourceCallbackFuncs *old_cb_funcs; |
||
1521 | |||
1522 | g_return_if_fail (source != NULL); |
||
1523 | g_return_if_fail (callback_funcs != NULL || callback_data == NULL); |
||
1524 | |||
1525 | context = source->context; |
||
1526 | |||
1527 | if (context) |
||
1528 | LOCK_CONTEXT (context); |
||
1529 | |||
1530 | old_cb_data = source->callback_data; |
||
1531 | old_cb_funcs = source->callback_funcs; |
||
1532 | |||
1533 | source->callback_data = callback_data; |
||
1534 | source->callback_funcs = callback_funcs; |
||
1535 | |||
1536 | if (context) |
||
1537 | UNLOCK_CONTEXT (context); |
||
1538 | |||
1539 | if (old_cb_funcs) |
||
1540 | old_cb_funcs->unref (old_cb_data); |
||
1541 | } |
||
1542 | |||
1543 | static void |
||
1544 | g_source_callback_ref (gpointer cb_data) |
||
1545 | { |
||
1546 | GSourceCallback *callback = cb_data; |
||
1547 | |||
1548 | callback->ref_count++; |
||
1549 | } |
||
1550 | |||
1551 | |||
1552 | static void |
||
1553 | g_source_callback_unref (gpointer cb_data) |
||
1554 | { |
||
1555 | GSourceCallback *callback = cb_data; |
||
1556 | |||
1557 | callback->ref_count--; |
||
1558 | if (callback->ref_count == 0) |
||
1559 | { |
||
1560 | if (callback->notify) |
||
1561 | callback->notify (callback->data); |
||
1562 | g_free (callback); |
||
1563 | } |
||
1564 | } |
||
1565 | |||
1566 | static void |
||
1567 | g_source_callback_get (gpointer cb_data, |
||
1568 | GSource *source, |
||
1569 | GSourceFunc *func, |
||
1570 | gpointer *data) |
||
1571 | { |
||
1572 | GSourceCallback *callback = cb_data; |
||
1573 | |||
1574 | *func = callback->func; |
||
1575 | *data = callback->data; |
||
1576 | } |
||
1577 | |||
1578 | static GSourceCallbackFuncs g_source_callback_funcs = { |
||
1579 | g_source_callback_ref, |
||
1580 | g_source_callback_unref, |
||
1581 | g_source_callback_get, |
||
1582 | }; |
||
1583 | |||
1584 | /** |
||
1585 | * g_source_set_callback: |
||
1586 | * @source: the source |
||
1587 | * @func: a callback function |
||
1588 | * @data: the data to pass to callback function |
||
1589 | * @notify: (allow-none): a function to call when @data is no longer in use, or %NULL. |
||
1590 | * |
||
1591 | * Sets the callback function for a source. The callback for a source is |
||
1592 | * called from the source's dispatch function. |
||
1593 | * |
||
1594 | * The exact type of @func depends on the type of source; ie. you |
||
1595 | * should not count on @func being called with @data as its first |
||
1596 | * parameter. |
||
1597 | * |
||
1598 | * See [memory management of sources][mainloop-memory-management] for details |
||
1599 | * on how to handle memory management of @data. |
||
1600 | * |
||
1601 | * Typically, you won't use this function. Instead use functions specific |
||
1602 | * to the type of source you are using. |
||
1603 | **/ |
||
1604 | void |
||
1605 | g_source_set_callback (GSource *source, |
||
1606 | GSourceFunc func, |
||
1607 | gpointer data, |
||
1608 | GDestroyNotify notify) |
||
1609 | { |
||
1610 | GSourceCallback *new_callback; |
||
1611 | |||
1612 | g_return_if_fail (source != NULL); |
||
1613 | |||
1614 | new_callback = g_new (GSourceCallback, 1); |
||
1615 | |||
1616 | new_callback->ref_count = 1; |
||
1617 | new_callback->func = func; |
||
1618 | new_callback->data = data; |
||
1619 | new_callback->notify = notify; |
||
1620 | |||
1621 | g_source_set_callback_indirect (source, new_callback, &g_source_callback_funcs); |
||
1622 | } |
||
1623 | |||
1624 | |||
1625 | /** |
||
1626 | * g_source_set_funcs: |
||
1627 | * @source: a #GSource |
||
1628 | * @funcs: the new #GSourceFuncs |
||
1629 | * |
||
1630 | * Sets the source functions (can be used to override |
||
1631 | * default implementations) of an unattached source. |
||
1632 | * |
||
1633 | * Since: 2.12 |
||
1634 | */ |
||
1635 | void |
||
1636 | g_source_set_funcs (GSource *source, |
||
1637 | GSourceFuncs *funcs) |
||
1638 | { |
||
1639 | g_return_if_fail (source != NULL); |
||
1640 | g_return_if_fail (source->context == NULL); |
||
1641 | g_return_if_fail (source->ref_count > 0); |
||
1642 | g_return_if_fail (funcs != NULL); |
||
1643 | |||
1644 | source->source_funcs = funcs; |
||
1645 | } |
||
1646 | |||
1647 | static void |
||
1648 | g_source_set_priority_unlocked (GSource *source, |
||
1649 | GMainContext *context, |
||
1650 | gint priority) |
||
1651 | { |
||
1652 | GSList *tmp_list; |
||
1653 | |||
1654 | g_return_if_fail (source->priv->parent_source == NULL || |
||
1655 | source->priv->parent_source->priority == priority); |
||
1656 | |||
1657 | if (context) |
||
1658 | { |
||
1659 | /* Remove the source from the context's source and then |
||
1660 | * add it back after so it is sorted in the correct place |
||
1661 | */ |
||
1662 | source_remove_from_context (source, source->context); |
||
1663 | } |
||
1664 | |||
1665 | source->priority = priority; |
||
1666 | |||
1667 | if (context) |
||
1668 | { |
||
1669 | source_add_to_context (source, source->context); |
||
1670 | |||
1671 | if (!SOURCE_BLOCKED (source)) |
||
1672 | { |
||
1673 | tmp_list = source->poll_fds; |
||
1674 | while (tmp_list) |
||
1675 | { |
||
1676 | g_main_context_remove_poll_unlocked (context, tmp_list->data); |
||
1677 | g_main_context_add_poll_unlocked (context, priority, tmp_list->data); |
||
1678 | |||
1679 | tmp_list = tmp_list->next; |
||
1680 | } |
||
1681 | |||
1682 | for (tmp_list = source->priv->fds; tmp_list; tmp_list = tmp_list->next) |
||
1683 | { |
||
1684 | g_main_context_remove_poll_unlocked (context, tmp_list->data); |
||
1685 | g_main_context_add_poll_unlocked (context, priority, tmp_list->data); |
||
1686 | } |
||
1687 | } |
||
1688 | } |
||
1689 | |||
1690 | if (source->priv->child_sources) |
||
1691 | { |
||
1692 | tmp_list = source->priv->child_sources; |
||
1693 | while (tmp_list) |
||
1694 | { |
||
1695 | g_source_set_priority_unlocked (tmp_list->data, context, priority); |
||
1696 | tmp_list = tmp_list->next; |
||
1697 | } |
||
1698 | } |
||
1699 | } |
||
1700 | |||
1701 | /** |
||
1702 | * g_source_set_priority: |
||
1703 | * @source: a #GSource |
||
1704 | * @priority: the new priority. |
||
1705 | * |
||
1706 | * Sets the priority of a source. While the main loop is being run, a |
||
1707 | * source will be dispatched if it is ready to be dispatched and no |
||
1708 | * sources at a higher (numerically smaller) priority are ready to be |
||
1709 | * dispatched. |
||
1710 | * |
||
1711 | * A child source always has the same priority as its parent. It is not |
||
1712 | * permitted to change the priority of a source once it has been added |
||
1713 | * as a child of another source. |
||
1714 | **/ |
||
1715 | void |
||
1716 | g_source_set_priority (GSource *source, |
||
1717 | gint priority) |
||
1718 | { |
||
1719 | GMainContext *context; |
||
1720 | |||
1721 | g_return_if_fail (source != NULL); |
||
1722 | g_return_if_fail (source->priv->parent_source == NULL); |
||
1723 | |||
1724 | context = source->context; |
||
1725 | |||
1726 | if (context) |
||
1727 | LOCK_CONTEXT (context); |
||
1728 | g_source_set_priority_unlocked (source, context, priority); |
||
1729 | if (context) |
||
1730 | UNLOCK_CONTEXT (source->context); |
||
1731 | } |
||
1732 | |||
1733 | /** |
||
1734 | * g_source_get_priority: |
||
1735 | * @source: a #GSource |
||
1736 | * |
||
1737 | * Gets the priority of a source. |
||
1738 | * |
||
1739 | * Returns: the priority of the source |
||
1740 | **/ |
||
1741 | gint |
||
1742 | g_source_get_priority (GSource *source) |
||
1743 | { |
||
1744 | g_return_val_if_fail (source != NULL, 0); |
||
1745 | |||
1746 | return source->priority; |
||
1747 | } |
||
1748 | |||
1749 | /** |
||
1750 | * g_source_set_ready_time: |
||
1751 | * @source: a #GSource |
||
1752 | * @ready_time: the monotonic time at which the source will be ready, |
||
1753 | * 0 for "immediately", -1 for "never" |
||
1754 | * |
||
1755 | * Sets a #GSource to be dispatched when the given monotonic time is |
||
1756 | * reached (or passed). If the monotonic time is in the past (as it |
||
1757 | * always will be if @ready_time is 0) then the source will be |
||
1758 | * dispatched immediately. |
||
1759 | * |
||
1760 | * If @ready_time is -1 then the source is never woken up on the basis |
||
1761 | * of the passage of time. |
||
1762 | * |
||
1763 | * Dispatching the source does not reset the ready time. You should do |
||
1764 | * so yourself, from the source dispatch function. |
||
1765 | * |
||
1766 | * Note that if you have a pair of sources where the ready time of one |
||
1767 | * suggests that it will be delivered first but the priority for the |
||
1768 | * other suggests that it would be delivered first, and the ready time |
||
1769 | * for both sources is reached during the same main context iteration |
||
1770 | * then the order of dispatch is undefined. |
||
1771 | * |
||
1772 | * This API is only intended to be used by implementations of #GSource. |
||
1773 | * Do not call this API on a #GSource that you did not create. |
||
1774 | * |
||
1775 | * Since: 2.36 |
||
1776 | **/ |
||
1777 | void |
||
1778 | g_source_set_ready_time (GSource *source, |
||
1779 | gint64 ready_time) |
||
1780 | { |
||
1781 | GMainContext *context; |
||
1782 | |||
1783 | g_return_if_fail (source != NULL); |
||
1784 | g_return_if_fail (source->ref_count > 0); |
||
1785 | |||
1786 | if (source->priv->ready_time == ready_time) |
||
1787 | return; |
||
1788 | |||
1789 | context = source->context; |
||
1790 | |||
1791 | if (context) |
||
1792 | LOCK_CONTEXT (context); |
||
1793 | |||
1794 | source->priv->ready_time = ready_time; |
||
1795 | |||
1796 | if (context) |
||
1797 | { |
||
1798 | /* Quite likely that we need to change the timeout on the poll */ |
||
1799 | if (!SOURCE_BLOCKED (source)) |
||
1800 | g_wakeup_signal (context->wakeup); |
||
1801 | UNLOCK_CONTEXT (context); |
||
1802 | } |
||
1803 | } |
||
1804 | |||
1805 | /** |
||
1806 | * g_source_get_ready_time: |
||
1807 | * @source: a #GSource |
||
1808 | * |
||
1809 | * Gets the "ready time" of @source, as set by |
||
1810 | * g_source_set_ready_time(). |
||
1811 | * |
||
1812 | * Any time before the current monotonic time (including 0) is an |
||
1813 | * indication that the source will fire immediately. |
||
1814 | * |
||
1815 | * Returns: the monotonic ready time, -1 for "never" |
||
1816 | **/ |
||
1817 | gint64 |
||
1818 | g_source_get_ready_time (GSource *source) |
||
1819 | { |
||
1820 | g_return_val_if_fail (source != NULL, -1); |
||
1821 | |||
1822 | return source->priv->ready_time; |
||
1823 | } |
||
1824 | |||
1825 | /** |
||
1826 | * g_source_set_can_recurse: |
||
1827 | * @source: a #GSource |
||
1828 | * @can_recurse: whether recursion is allowed for this source |
||
1829 | * |
||
1830 | * Sets whether a source can be called recursively. If @can_recurse is |
||
1831 | * %TRUE, then while the source is being dispatched then this source |
||
1832 | * will be processed normally. Otherwise, all processing of this |
||
1833 | * source is blocked until the dispatch function returns. |
||
1834 | **/ |
||
1835 | void |
||
1836 | g_source_set_can_recurse (GSource *source, |
||
1837 | gboolean can_recurse) |
||
1838 | { |
||
1839 | GMainContext *context; |
||
1840 | |||
1841 | g_return_if_fail (source != NULL); |
||
1842 | |||
1843 | context = source->context; |
||
1844 | |||
1845 | if (context) |
||
1846 | LOCK_CONTEXT (context); |
||
1847 | |||
1848 | if (can_recurse) |
||
1849 | source->flags |= G_SOURCE_CAN_RECURSE; |
||
1850 | else |
||
1851 | source->flags &= ~G_SOURCE_CAN_RECURSE; |
||
1852 | |||
1853 | if (context) |
||
1854 | UNLOCK_CONTEXT (context); |
||
1855 | } |
||
1856 | |||
1857 | /** |
||
1858 | * g_source_get_can_recurse: |
||
1859 | * @source: a #GSource |
||
1860 | * |
||
1861 | * Checks whether a source is allowed to be called recursively. |
||
1862 | * see g_source_set_can_recurse(). |
||
1863 | * |
||
1864 | * Returns: whether recursion is allowed. |
||
1865 | **/ |
||
1866 | gboolean |
||
1867 | g_source_get_can_recurse (GSource *source) |
||
1868 | { |
||
1869 | g_return_val_if_fail (source != NULL, FALSE); |
||
1870 | |||
1871 | return (source->flags & G_SOURCE_CAN_RECURSE) != 0; |
||
1872 | } |
||
1873 | |||
1874 | |||
1875 | /** |
||
1876 | * g_source_set_name: |
||
1877 | * @source: a #GSource |
||
1878 | * @name: debug name for the source |
||
1879 | * |
||
1880 | * Sets a name for the source, used in debugging and profiling. |
||
1881 | * The name defaults to #NULL. |
||
1882 | * |
||
1883 | * The source name should describe in a human-readable way |
||
1884 | * what the source does. For example, "X11 event queue" |
||
1885 | * or "GTK+ repaint idle handler" or whatever it is. |
||
1886 | * |
||
1887 | * It is permitted to call this function multiple times, but is not |
||
1888 | * recommended due to the potential performance impact. For example, |
||
1889 | * one could change the name in the "check" function of a #GSourceFuncs |
||
1890 | * to include details like the event type in the source name. |
||
1891 | * |
||
1892 | * Use caution if changing the name while another thread may be |
||
1893 | * accessing it with g_source_get_name(); that function does not copy |
||
1894 | * the value, and changing the value will free it while the other thread |
||
1895 | * may be attempting to use it. |
||
1896 | * |
||
1897 | * Since: 2.26 |
||
1898 | **/ |
||
1899 | void |
||
1900 | g_source_set_name (GSource *source, |
||
1901 | const char *name) |
||
1902 | { |
||
1903 | GMainContext *context; |
||
1904 | |||
1905 | g_return_if_fail (source != NULL); |
||
1906 | |||
1907 | context = source->context; |
||
1908 | |||
1909 | if (context) |
||
1910 | LOCK_CONTEXT (context); |
||
1911 | |||
1912 | /* setting back to NULL is allowed, just because it's |
||
1913 | * weird if get_name can return NULL but you can't |
||
1914 | * set that. |
||
1915 | */ |
||
1916 | |||
1917 | g_free (source->name); |
||
1918 | source->name = g_strdup (name); |
||
1919 | |||
1920 | if (context) |
||
1921 | UNLOCK_CONTEXT (context); |
||
1922 | } |
||
1923 | |||
1924 | /** |
||
1925 | * g_source_get_name: |
||
1926 | * @source: a #GSource |
||
1927 | * |
||
1928 | * Gets a name for the source, used in debugging and profiling. The |
||
1929 | * name may be #NULL if it has never been set with g_source_set_name(). |
||
1930 | * |
||
1931 | * Returns: the name of the source |
||
1932 | * |
||
1933 | * Since: 2.26 |
||
1934 | **/ |
||
1935 | const char * |
||
1936 | g_source_get_name (GSource *source) |
||
1937 | { |
||
1938 | g_return_val_if_fail (source != NULL, NULL); |
||
1939 | |||
1940 | return source->name; |
||
1941 | } |
||
1942 | |||
1943 | /** |
||
1944 | * g_source_set_name_by_id: |
||
1945 | * @tag: a #GSource ID |
||
1946 | * @name: debug name for the source |
||
1947 | * |
||
1948 | * Sets the name of a source using its ID. |
||
1949 | * |
||
1950 | * This is a convenience utility to set source names from the return |
||
1951 | * value of g_idle_add(), g_timeout_add(), etc. |
||
1952 | * |
||
1953 | * It is a programmer error to attempt to set the name of a non-existent |
||
1954 | * source. |
||
1955 | * |
||
1956 | * More specifically: source IDs can be reissued after a source has been |
||
1957 | * destroyed and therefore it is never valid to use this function with a |
||
1958 | * source ID which may have already been removed. An example is when |
||
1959 | * scheduling an idle to run in another thread with g_idle_add(): the |
||
1960 | * idle may already have run and been removed by the time this function |
||
1961 | * is called on its (now invalid) source ID. This source ID may have |
||
1962 | * been reissued, leading to the operation being performed against the |
||
1963 | * wrong source. |
||
1964 | * |
||
1965 | * Since: 2.26 |
||
1966 | **/ |
||
1967 | void |
||
1968 | g_source_set_name_by_id (guint tag, |
||
1969 | const char *name) |
||
1970 | { |
||
1971 | GSource *source; |
||
1972 | |||
1973 | g_return_if_fail (tag > 0); |
||
1974 | |||
1975 | source = g_main_context_find_source_by_id (NULL, tag); |
||
1976 | if (source == NULL) |
||
1977 | return; |
||
1978 | |||
1979 | g_source_set_name (source, name); |
||
1980 | } |
||
1981 | |||
1982 | |||
1983 | /** |
||
1984 | * g_source_ref: |
||
1985 | * @source: a #GSource |
||
1986 | * |
||
1987 | * Increases the reference count on a source by one. |
||
1988 | * |
||
1989 | * Returns: @source |
||
1990 | **/ |
||
1991 | GSource * |
||
1992 | g_source_ref (GSource *source) |
||
1993 | { |
||
1994 | GMainContext *context; |
||
1995 | |||
1996 | g_return_val_if_fail (source != NULL, NULL); |
||
1997 | |||
1998 | context = source->context; |
||
1999 | |||
2000 | if (context) |
||
2001 | LOCK_CONTEXT (context); |
||
2002 | |||
2003 | source->ref_count++; |
||
2004 | |||
2005 | if (context) |
||
2006 | UNLOCK_CONTEXT (context); |
||
2007 | |||
2008 | return source; |
||
2009 | } |
||
2010 | |||
2011 | /* g_source_unref() but possible to call within context lock |
||
2012 | */ |
||
2013 | static void |
||
2014 | g_source_unref_internal (GSource *source, |
||
2015 | GMainContext *context, |
||
2016 | gboolean have_lock) |
||
2017 | { |
||
2018 | gpointer old_cb_data = NULL; |
||
2019 | GSourceCallbackFuncs *old_cb_funcs = NULL; |
||
2020 | |||
2021 | g_return_if_fail (source != NULL); |
||
2022 | |||
2023 | if (!have_lock && context) |
||
2024 | LOCK_CONTEXT (context); |
||
2025 | |||
2026 | source->ref_count--; |
||
2027 | if (source->ref_count == 0) |
||
2028 | { |
||
2029 | old_cb_data = source->callback_data; |
||
2030 | old_cb_funcs = source->callback_funcs; |
||
2031 | |||
2032 | source->callback_data = NULL; |
||
2033 | source->callback_funcs = NULL; |
||
2034 | |||
2035 | if (context) |
||
2036 | { |
||
2037 | if (!SOURCE_DESTROYED (source)) |
||
2038 | g_warning (G_STRLOC ": ref_count == 0, but source was still attached to a context!"); |
||
2039 | source_remove_from_context (source, context); |
||
2040 | |||
2041 | g_hash_table_remove (context->sources, GUINT_TO_POINTER (source->source_id)); |
||
2042 | } |
||
2043 | |||
2044 | if (source->source_funcs->finalize) |
||
2045 | { |
||
2046 | if (context) |
||
2047 | UNLOCK_CONTEXT (context); |
||
2048 | source->source_funcs->finalize (source); |
||
2049 | if (context) |
||
2050 | LOCK_CONTEXT (context); |
||
2051 | } |
||
2052 | |||
2053 | g_free (source->name); |
||
2054 | source->name = NULL; |
||
2055 | |||
2056 | g_slist_free (source->poll_fds); |
||
2057 | source->poll_fds = NULL; |
||
2058 | |||
2059 | g_slist_free_full (source->priv->fds, g_free); |
||
2060 | |||
2061 | while (source->priv->child_sources) |
||
2062 | { |
||
2063 | GSource *child_source = source->priv->child_sources->data; |
||
2064 | |||
2065 | source->priv->child_sources = |
||
2066 | g_slist_remove (source->priv->child_sources, child_source); |
||
2067 | child_source->priv->parent_source = NULL; |
||
2068 | |||
2069 | g_source_unref_internal (child_source, context, have_lock); |
||
2070 | } |
||
2071 | |||
2072 | g_slice_free (GSourcePrivate, source->priv); |
||
2073 | source->priv = NULL; |
||
2074 | |||
2075 | g_free (source); |
||
2076 | } |
||
2077 | |||
2078 | if (!have_lock && context) |
||
2079 | UNLOCK_CONTEXT (context); |
||
2080 | |||
2081 | if (old_cb_funcs) |
||
2082 | { |
||
2083 | if (have_lock) |
||
2084 | UNLOCK_CONTEXT (context); |
||
2085 | |||
2086 | old_cb_funcs->unref (old_cb_data); |
||
2087 | |||
2088 | if (have_lock) |
||
2089 | LOCK_CONTEXT (context); |
||
2090 | } |
||
2091 | } |
||
2092 | |||
2093 | /** |
||
2094 | * g_source_unref: |
||
2095 | * @source: a #GSource |
||
2096 | * |
||
2097 | * Decreases the reference count of a source by one. If the |
||
2098 | * resulting reference count is zero the source and associated |
||
2099 | * memory will be destroyed. |
||
2100 | **/ |
||
2101 | void |
||
2102 | g_source_unref (GSource *source) |
||
2103 | { |
||
2104 | g_return_if_fail (source != NULL); |
||
2105 | |||
2106 | g_source_unref_internal (source, source->context, FALSE); |
||
2107 | } |
||
2108 | |||
2109 | /** |
||
2110 | * g_main_context_find_source_by_id: |
||
2111 | * @context: (allow-none): a #GMainContext (if %NULL, the default context will be used) |
||
2112 | * @source_id: the source ID, as returned by g_source_get_id(). |
||
2113 | * |
||
2114 | * Finds a #GSource given a pair of context and ID. |
||
2115 | * |
||
2116 | * It is a programmer error to attempt to lookup a non-existent source. |
||
2117 | * |
||
2118 | * More specifically: source IDs can be reissued after a source has been |
||
2119 | * destroyed and therefore it is never valid to use this function with a |
||
2120 | * source ID which may have already been removed. An example is when |
||
2121 | * scheduling an idle to run in another thread with g_idle_add(): the |
||
2122 | * idle may already have run and been removed by the time this function |
||
2123 | * is called on its (now invalid) source ID. This source ID may have |
||
2124 | * been reissued, leading to the operation being performed against the |
||
2125 | * wrong source. |
||
2126 | * |
||
2127 | * Returns: (transfer none): the #GSource |
||
2128 | **/ |
||
2129 | GSource * |
||
2130 | g_main_context_find_source_by_id (GMainContext *context, |
||
2131 | guint source_id) |
||
2132 | { |
||
2133 | GSource *source; |
||
2134 | |||
2135 | g_return_val_if_fail (source_id > 0, NULL); |
||
2136 | |||
2137 | if (context == NULL) |
||
2138 | context = g_main_context_default (); |
||
2139 | |||
2140 | LOCK_CONTEXT (context); |
||
2141 | source = g_hash_table_lookup (context->sources, GUINT_TO_POINTER (source_id)); |
||
2142 | UNLOCK_CONTEXT (context); |
||
2143 | |||
2144 | if (source && SOURCE_DESTROYED (source)) |
||
2145 | source = NULL; |
||
2146 | |||
2147 | return source; |
||
2148 | } |
||
2149 | |||
2150 | /** |
||
2151 | * g_main_context_find_source_by_funcs_user_data: |
||
2152 | * @context: (allow-none): a #GMainContext (if %NULL, the default context will be used). |
||
2153 | * @funcs: the @source_funcs passed to g_source_new(). |
||
2154 | * @user_data: the user data from the callback. |
||
2155 | * |
||
2156 | * Finds a source with the given source functions and user data. If |
||
2157 | * multiple sources exist with the same source function and user data, |
||
2158 | * the first one found will be returned. |
||
2159 | * |
||
2160 | * Returns: (transfer none): the source, if one was found, otherwise %NULL |
||
2161 | **/ |
||
2162 | GSource * |
||
2163 | g_main_context_find_source_by_funcs_user_data (GMainContext *context, |
||
2164 | GSourceFuncs *funcs, |
||
2165 | gpointer user_data) |
||
2166 | { |
||
2167 | GSourceIter iter; |
||
2168 | GSource *source; |
||
2169 | |||
2170 | g_return_val_if_fail (funcs != NULL, NULL); |
||
2171 | |||
2172 | if (context == NULL) |
||
2173 | context = g_main_context_default (); |
||
2174 | |||
2175 | LOCK_CONTEXT (context); |
||
2176 | |||
2177 | g_source_iter_init (&iter, context, FALSE); |
||
2178 | while (g_source_iter_next (&iter, &source)) |
||
2179 | { |
||
2180 | if (!SOURCE_DESTROYED (source) && |
||
2181 | source->source_funcs == funcs && |
||
2182 | source->callback_funcs) |
||
2183 | { |
||
2184 | GSourceFunc callback; |
||
2185 | gpointer callback_data; |
||
2186 | |||
2187 | source->callback_funcs->get (source->callback_data, source, &callback, &callback_data); |
||
2188 | |||
2189 | if (callback_data == user_data) |
||
2190 | break; |
||
2191 | } |
||
2192 | } |
||
2193 | g_source_iter_clear (&iter); |
||
2194 | |||
2195 | UNLOCK_CONTEXT (context); |
||
2196 | |||
2197 | return source; |
||
2198 | } |
||
2199 | |||
2200 | /** |
||
2201 | * g_main_context_find_source_by_user_data: |
||
2202 | * @context: a #GMainContext |
||
2203 | * @user_data: the user_data for the callback. |
||
2204 | * |
||
2205 | * Finds a source with the given user data for the callback. If |
||
2206 | * multiple sources exist with the same user data, the first |
||
2207 | * one found will be returned. |
||
2208 | * |
||
2209 | * Returns: (transfer none): the source, if one was found, otherwise %NULL |
||
2210 | **/ |
||
2211 | GSource * |
||
2212 | g_main_context_find_source_by_user_data (GMainContext *context, |
||
2213 | gpointer user_data) |
||
2214 | { |
||
2215 | GSourceIter iter; |
||
2216 | GSource *source; |
||
2217 | |||
2218 | if (context == NULL) |
||
2219 | context = g_main_context_default (); |
||
2220 | |||
2221 | LOCK_CONTEXT (context); |
||
2222 | |||
2223 | g_source_iter_init (&iter, context, FALSE); |
||
2224 | while (g_source_iter_next (&iter, &source)) |
||
2225 | { |
||
2226 | if (!SOURCE_DESTROYED (source) && |
||
2227 | source->callback_funcs) |
||
2228 | { |
||
2229 | GSourceFunc callback; |
||
2230 | gpointer callback_data = NULL; |
||
2231 | |||
2232 | source->callback_funcs->get (source->callback_data, source, &callback, &callback_data); |
||
2233 | |||
2234 | if (callback_data == user_data) |
||
2235 | break; |
||
2236 | } |
||
2237 | } |
||
2238 | g_source_iter_clear (&iter); |
||
2239 | |||
2240 | UNLOCK_CONTEXT (context); |
||
2241 | |||
2242 | return source; |
||
2243 | } |
||
2244 | |||
2245 | /** |
||
2246 | * g_source_remove: |
||
2247 | * @tag: the ID of the source to remove. |
||
2248 | * |
||
2249 | * Removes the source with the given id from the default main context. |
||
2250 | * |
||
2251 | * The id of a #GSource is given by g_source_get_id(), or will be |
||
2252 | * returned by the functions g_source_attach(), g_idle_add(), |
||
2253 | * g_idle_add_full(), g_timeout_add(), g_timeout_add_full(), |
||
2254 | * g_child_watch_add(), g_child_watch_add_full(), g_io_add_watch(), and |
||
2255 | * g_io_add_watch_full(). |
||
2256 | * |
||
2257 | * See also g_source_destroy(). You must use g_source_destroy() for sources |
||
2258 | * added to a non-default main context. |
||
2259 | * |
||
2260 | * It is a programmer error to attempt to remove a non-existent source. |
||
2261 | * |
||
2262 | * More specifically: source IDs can be reissued after a source has been |
||
2263 | * destroyed and therefore it is never valid to use this function with a |
||
2264 | * source ID which may have already been removed. An example is when |
||
2265 | * scheduling an idle to run in another thread with g_idle_add(): the |
||
2266 | * idle may already have run and been removed by the time this function |
||
2267 | * is called on its (now invalid) source ID. This source ID may have |
||
2268 | * been reissued, leading to the operation being performed against the |
||
2269 | * wrong source. |
||
2270 | * |
||
2271 | * Returns: For historical reasons, this function always returns %TRUE |
||
2272 | **/ |
||
2273 | gboolean |
||
2274 | g_source_remove (guint tag) |
||
2275 | { |
||
2276 | GSource *source; |
||
2277 | |||
2278 | g_return_val_if_fail (tag > 0, FALSE); |
||
2279 | |||
2280 | source = g_main_context_find_source_by_id (NULL, tag); |
||
2281 | if (source) |
||
2282 | g_source_destroy (source); |
||
2283 | else |
||
2284 | g_critical ("Source ID %u was not found when attempting to remove it", tag); |
||
2285 | |||
2286 | return source != NULL; |
||
2287 | } |
||
2288 | |||
2289 | /** |
||
2290 | * g_source_remove_by_user_data: |
||
2291 | * @user_data: the user_data for the callback. |
||
2292 | * |
||
2293 | * Removes a source from the default main loop context given the user |
||
2294 | * data for the callback. If multiple sources exist with the same user |
||
2295 | * data, only one will be destroyed. |
||
2296 | * |
||
2297 | * Returns: %TRUE if a source was found and removed. |
||
2298 | **/ |
||
2299 | gboolean |
||
2300 | g_source_remove_by_user_data (gpointer user_data) |
||
2301 | { |
||
2302 | GSource *source; |
||
2303 | |||
2304 | source = g_main_context_find_source_by_user_data (NULL, user_data); |
||
2305 | if (source) |
||
2306 | { |
||
2307 | g_source_destroy (source); |
||
2308 | return TRUE; |
||
2309 | } |
||
2310 | else |
||
2311 | return FALSE; |
||
2312 | } |
||
2313 | |||
2314 | /** |
||
2315 | * g_source_remove_by_funcs_user_data: |
||
2316 | * @funcs: The @source_funcs passed to g_source_new() |
||
2317 | * @user_data: the user data for the callback |
||
2318 | * |
||
2319 | * Removes a source from the default main loop context given the |
||
2320 | * source functions and user data. If multiple sources exist with the |
||
2321 | * same source functions and user data, only one will be destroyed. |
||
2322 | * |
||
2323 | * Returns: %TRUE if a source was found and removed. |
||
2324 | **/ |
||
2325 | gboolean |
||
2326 | g_source_remove_by_funcs_user_data (GSourceFuncs *funcs, |
||
2327 | gpointer user_data) |
||
2328 | { |
||
2329 | GSource *source; |
||
2330 | |||
2331 | g_return_val_if_fail (funcs != NULL, FALSE); |
||
2332 | |||
2333 | source = g_main_context_find_source_by_funcs_user_data (NULL, funcs, user_data); |
||
2334 | if (source) |
||
2335 | { |
||
2336 | g_source_destroy (source); |
||
2337 | return TRUE; |
||
2338 | } |
||
2339 | else |
||
2340 | return FALSE; |
||
2341 | } |
||
2342 | |||
2343 | #ifdef G_OS_UNIX |
||
2344 | /** |
||
2345 | * g_source_add_unix_fd: |
||
2346 | * @source: a #GSource |
||
2347 | * @fd: the fd to monitor |
||
2348 | * @events: an event mask |
||
2349 | * |
||
2350 | * Monitors @fd for the IO events in @events. |
||
2351 | * |
||
2352 | * The tag returned by this function can be used to remove or modify the |
||
2353 | * monitoring of the fd using g_source_remove_unix_fd() or |
||
2354 | * g_source_modify_unix_fd(). |
||
2355 | * |
||
2356 | * It is not necessary to remove the fd before destroying the source; it |
||
2357 | * will be cleaned up automatically. |
||
2358 | * |
||
2359 | * This API is only intended to be used by implementations of #GSource. |
||
2360 | * Do not call this API on a #GSource that you did not create. |
||
2361 | * |
||
2362 | * As the name suggests, this function is not available on Windows. |
||
2363 | * |
||
2364 | * Returns: (not nullable): an opaque tag |
||
2365 | * |
||
2366 | * Since: 2.36 |
||
2367 | **/ |
||
2368 | gpointer |
||
2369 | g_source_add_unix_fd (GSource *source, |
||
2370 | gint fd, |
||
2371 | GIOCondition events) |
||
2372 | { |
||
2373 | GMainContext *context; |
||
2374 | GPollFD *poll_fd; |
||
2375 | |||
2376 | g_return_val_if_fail (source != NULL, NULL); |
||
2377 | g_return_val_if_fail (!SOURCE_DESTROYED (source), NULL); |
||
2378 | |||
2379 | poll_fd = g_new (GPollFD, 1); |
||
2380 | poll_fd->fd = fd; |
||
2381 | poll_fd->events = events; |
||
2382 | poll_fd->revents = 0; |
||
2383 | |||
2384 | context = source->context; |
||
2385 | |||
2386 | if (context) |
||
2387 | LOCK_CONTEXT (context); |
||
2388 | |||
2389 | source->priv->fds = g_slist_prepend (source->priv->fds, poll_fd); |
||
2390 | |||
2391 | if (context) |
||
2392 | { |
||
2393 | if (!SOURCE_BLOCKED (source)) |
||
2394 | g_main_context_add_poll_unlocked (context, source->priority, poll_fd); |
||
2395 | UNLOCK_CONTEXT (context); |
||
2396 | } |
||
2397 | |||
2398 | return poll_fd; |
||
2399 | } |
||
2400 | |||
2401 | /** |
||
2402 | * g_source_modify_unix_fd: |
||
2403 | * @source: a #GSource |
||
2404 | * @tag: (not nullable): the tag from g_source_add_unix_fd() |
||
2405 | * @new_events: the new event mask to watch |
||
2406 | * |
||
2407 | * Updates the event mask to watch for the fd identified by @tag. |
||
2408 | * |
||
2409 | * @tag is the tag returned from g_source_add_unix_fd(). |
||
2410 | * |
||
2411 | * If you want to remove a fd, don't set its event mask to zero. |
||
2412 | * Instead, call g_source_remove_unix_fd(). |
||
2413 | * |
||
2414 | * This API is only intended to be used by implementations of #GSource. |
||
2415 | * Do not call this API on a #GSource that you did not create. |
||
2416 | * |
||
2417 | * As the name suggests, this function is not available on Windows. |
||
2418 | * |
||
2419 | * Since: 2.36 |
||
2420 | **/ |
||
2421 | void |
||
2422 | g_source_modify_unix_fd (GSource *source, |
||
2423 | gpointer tag, |
||
2424 | GIOCondition new_events) |
||
2425 | { |
||
2426 | GMainContext *context; |
||
2427 | GPollFD *poll_fd; |
||
2428 | |||
2429 | g_return_if_fail (source != NULL); |
||
2430 | g_return_if_fail (g_slist_find (source->priv->fds, tag)); |
||
2431 | |||
2432 | context = source->context; |
||
2433 | poll_fd = tag; |
||
2434 | |||
2435 | poll_fd->events = new_events; |
||
2436 | |||
2437 | if (context) |
||
2438 | g_main_context_wakeup (context); |
||
2439 | } |
||
2440 | |||
2441 | /** |
||
2442 | * g_source_remove_unix_fd: |
||
2443 | * @source: a #GSource |
||
2444 | * @tag: (not nullable): the tag from g_source_add_unix_fd() |
||
2445 | * |
||
2446 | * Reverses the effect of a previous call to g_source_add_unix_fd(). |
||
2447 | * |
||
2448 | * You only need to call this if you want to remove an fd from being |
||
2449 | * watched while keeping the same source around. In the normal case you |
||
2450 | * will just want to destroy the source. |
||
2451 | * |
||
2452 | * This API is only intended to be used by implementations of #GSource. |
||
2453 | * Do not call this API on a #GSource that you did not create. |
||
2454 | * |
||
2455 | * As the name suggests, this function is not available on Windows. |
||
2456 | * |
||
2457 | * Since: 2.36 |
||
2458 | **/ |
||
2459 | void |
||
2460 | g_source_remove_unix_fd (GSource *source, |
||
2461 | gpointer tag) |
||
2462 | { |
||
2463 | GMainContext *context; |
||
2464 | GPollFD *poll_fd; |
||
2465 | |||
2466 | g_return_if_fail (source != NULL); |
||
2467 | g_return_if_fail (g_slist_find (source->priv->fds, tag)); |
||
2468 | |||
2469 | context = source->context; |
||
2470 | poll_fd = tag; |
||
2471 | |||
2472 | if (context) |
||
2473 | LOCK_CONTEXT (context); |
||
2474 | |||
2475 | source->priv->fds = g_slist_remove (source->priv->fds, poll_fd); |
||
2476 | |||
2477 | if (context) |
||
2478 | { |
||
2479 | if (!SOURCE_BLOCKED (source)) |
||
2480 | g_main_context_remove_poll_unlocked (context, poll_fd); |
||
2481 | |||
2482 | UNLOCK_CONTEXT (context); |
||
2483 | } |
||
2484 | |||
2485 | g_free (poll_fd); |
||
2486 | } |
||
2487 | |||
2488 | /** |
||
2489 | * g_source_query_unix_fd: |
||
2490 | * @source: a #GSource |
||
2491 | * @tag: (not nullable): the tag from g_source_add_unix_fd() |
||
2492 | * |
||
2493 | * Queries the events reported for the fd corresponding to @tag on |
||
2494 | * @source during the last poll. |
||
2495 | * |
||
2496 | * The return value of this function is only defined when the function |
||
2497 | * is called from the check or dispatch functions for @source. |
||
2498 | * |
||
2499 | * This API is only intended to be used by implementations of #GSource. |
||
2500 | * Do not call this API on a #GSource that you did not create. |
||
2501 | * |
||
2502 | * As the name suggests, this function is not available on Windows. |
||
2503 | * |
||
2504 | * Returns: the conditions reported on the fd |
||
2505 | * |
||
2506 | * Since: 2.36 |
||
2507 | **/ |
||
2508 | GIOCondition |
||
2509 | g_source_query_unix_fd (GSource *source, |
||
2510 | gpointer tag) |
||
2511 | { |
||
2512 | GPollFD *poll_fd; |
||
2513 | |||
2514 | g_return_val_if_fail (source != NULL, 0); |
||
2515 | g_return_val_if_fail (g_slist_find (source->priv->fds, tag), 0); |
||
2516 | |||
2517 | poll_fd = tag; |
||
2518 | |||
2519 | return poll_fd->revents; |
||
2520 | } |
||
2521 | #endif /* G_OS_UNIX */ |
||
2522 | |||
2523 | /** |
||
2524 | * g_get_current_time: |
||
2525 | * @result: #GTimeVal structure in which to store current time. |
||
2526 | * |
||
2527 | * Equivalent to the UNIX gettimeofday() function, but portable. |
||
2528 | * |
||
2529 | * You may find g_get_real_time() to be more convenient. |
||
2530 | **/ |
||
2531 | void |
||
2532 | g_get_current_time (GTimeVal *result) |
||
2533 | { |
||
2534 | #ifndef G_OS_WIN32 |
||
2535 | struct timeval r; |
||
2536 | |||
2537 | g_return_if_fail (result != NULL); |
||
2538 | |||
2539 | /*this is required on alpha, there the timeval structs are int's |
||
2540 | not longs and a cast only would fail horribly*/ |
||
2541 | gettimeofday (&r, NULL); |
||
2542 | result->tv_sec = r.tv_sec; |
||
2543 | result->tv_usec = r.tv_usec; |
||
2544 | #else |
||
2545 | FILETIME ft; |
||
2546 | guint64 time64; |
||
2547 | |||
2548 | g_return_if_fail (result != NULL); |
||
2549 | |||
2550 | GetSystemTimeAsFileTime (&ft); |
||
2551 | memmove (&time64, &ft, sizeof (FILETIME)); |
||
2552 | |||
2553 | /* Convert from 100s of nanoseconds since 1601-01-01 |
||
2554 | * to Unix epoch. Yes, this is Y2038 unsafe. |
||
2555 | */ |
||
2556 | time64 -= G_GINT64_CONSTANT (116444736000000000); |
||
2557 | time64 /= 10; |
||
2558 | |||
2559 | result->tv_sec = time64 / 1000000; |
||
2560 | result->tv_usec = time64 % 1000000; |
||
2561 | #endif |
||
2562 | } |
||
2563 | |||
2564 | /** |
||
2565 | * g_get_real_time: |
||
2566 | * |
||
2567 | * Queries the system wall-clock time. |
||
2568 | * |
||
2569 | * This call is functionally equivalent to g_get_current_time() except |
||
2570 | * that the return value is often more convenient than dealing with a |
||
2571 | * #GTimeVal. |
||
2572 | * |
||
2573 | * You should only use this call if you are actually interested in the real |
||
2574 | * wall-clock time. g_get_monotonic_time() is probably more useful for |
||
2575 | * measuring intervals. |
||
2576 | * |
||
2577 | * Returns: the number of microseconds since January 1, 1970 UTC. |
||
2578 | * |
||
2579 | * Since: 2.28 |
||
2580 | **/ |
||
2581 | gint64 |
||
2582 | g_get_real_time (void) |
||
2583 | { |
||
2584 | GTimeVal tv; |
||
2585 | |||
2586 | g_get_current_time (&tv); |
||
2587 | |||
2588 | return (((gint64) tv.tv_sec) * 1000000) + tv.tv_usec; |
||
2589 | } |
||
2590 | |||
2591 | /** |
||
2592 | * g_get_monotonic_time: |
||
2593 | * |
||
2594 | * Queries the system monotonic time. |
||
2595 | * |
||
2596 | * The monotonic clock will always increase and doesn't suffer |
||
2597 | * discontinuities when the user (or NTP) changes the system time. It |
||
2598 | * may or may not continue to tick during times where the machine is |
||
2599 | * suspended. |
||
2600 | * |
||
2601 | * We try to use the clock that corresponds as closely as possible to |
||
2602 | * the passage of time as measured by system calls such as poll() but it |
||
2603 | * may not always be possible to do this. |
||
2604 | * |
||
2605 | * Returns: the monotonic time, in microseconds |
||
2606 | * |
||
2607 | * Since: 2.28 |
||
2608 | **/ |
||
2609 | #if defined (G_OS_WIN32) |
||
2610 | static ULONGLONG (*g_GetTickCount64) (void) = NULL; |
||
2611 | static guint32 g_win32_tick_epoch = 0; |
||
2612 | |||
2613 | void |
||
2614 | g_clock_win32_init (void) |
||
2615 | { |
||
2616 | HMODULE kernel32; |
||
2617 | |||
2618 | g_GetTickCount64 = NULL; |
||
2619 | kernel32 = GetModuleHandle ("KERNEL32.DLL"); |
||
2620 | if (kernel32 != NULL) |
||
2621 | g_GetTickCount64 = (void *) GetProcAddress (kernel32, "GetTickCount64"); |
||
2622 | g_win32_tick_epoch = ((guint32)GetTickCount()) >> 31; |
||
2623 | } |
||
2624 | |||
2625 | gint64 |
||
2626 | g_get_monotonic_time (void) |
||
2627 | { |
||
2628 | guint64 ticks; |
||
2629 | guint32 ticks32; |
||
2630 | |||
2631 | /* There are four sources for the monotonic time on Windows: |
||
2632 | * |
||
2633 | * Three are based on a (1 msec accuracy, but only read periodically) clock chip: |
||
2634 | * - GetTickCount (GTC) |
||
2635 | * 32bit msec counter, updated each ~15msec, wraps in ~50 days |
||
2636 | * - GetTickCount64 (GTC64) |
||
2637 | * Same as GetTickCount, but extended to 64bit, so no wrap |
||
2638 | * Only available in Vista or later |
||
2639 | * - timeGetTime (TGT) |
||
2640 | * similar to GetTickCount by default: 15msec, 50 day wrap. |
||
2641 | * available in winmm.dll (thus known as the multimedia timers) |
||
2642 | * However apps can raise the system timer clock frequency using timeBeginPeriod() |
||
2643 | * increasing the accuracy up to 1 msec, at a cost in general system performance |
||
2644 | * and battery use. |
||
2645 | * |
||
2646 | * One is based on high precision clocks: |
||
2647 | * - QueryPrecisionCounter (QPC) |
||
2648 | * This has much higher accuracy, but is not guaranteed monotonic, and |
||
2649 | * has lots of complications like clock jumps and different times on different |
||
2650 | * CPUs. It also has lower long term accuracy (i.e. it will drift compared to |
||
2651 | * the low precision clocks. |
||
2652 | * |
||
2653 | * Additionally, the precision available in the timer-based wakeup such as |
||
2654 | * MsgWaitForMultipleObjectsEx (which is what the mainloop is based on) is based |
||
2655 | * on the TGT resolution, so by default it is ~15msec, but can be increased by apps. |
||
2656 | * |
||
2657 | * The QPC timer has too many issues to be used as is. The only way it could be used |
||
2658 | * is to use it to interpolate the lower precision clocks. Firefox does something like |
||
2659 | * this: |
||
2660 | * https://bugzilla.mozilla.org/show_bug.cgi?id=363258 |
||
2661 | * |
||
2662 | * However this seems quite complicated, so we're not doing this right now. |
||
2663 | * |
||
2664 | * The approach we take instead is to use the TGT timer, extending it to 64bit |
||
2665 | * either by using the GTC64 value, or if that is not available, a process local |
||
2666 | * time epoch that we increment when we detect a timer wrap (assumes that we read |
||
2667 | * the time at least once every 50 days). |
||
2668 | * |
||
2669 | * This means that: |
||
2670 | * - We have a globally consistent monotonic clock on Vista and later |
||
2671 | * - We have a locally monotonic clock on XP |
||
2672 | * - Apps that need higher precision in timeouts and clock reads can call |
||
2673 | * timeBeginPeriod() to increase it as much as they want |
||
2674 | */ |
||
2675 | |||
2676 | if (g_GetTickCount64 != NULL) |
||
2677 | { |
||
2678 | guint32 ticks_as_32bit; |
||
2679 | |||
2680 | ticks = g_GetTickCount64 (); |
||
2681 | ticks32 = timeGetTime(); |
||
2682 | |||
2683 | /* GTC64 and TGT are sampled at different times, however they |
||
2684 | * have the same base and source (msecs since system boot). |
||
2685 | * They can differ by as much as -16 to +16 msecs. |
||
2686 | * We can't just inject the low bits into the 64bit counter |
||
2687 | * as one of the counters can have wrapped in 32bit space and |
||
2688 | * the other not. Instead we calculate the signed difference |
||
2689 | * in 32bit space and apply that difference to the 64bit counter. |
||
2690 | */ |
||
2691 | ticks_as_32bit = (guint32)ticks; |
||
2692 | |||
2693 | /* We could do some 2's complement hack, but we play it safe */ |
||
2694 | if (ticks32 - ticks_as_32bit <= G_MAXINT32) |
||
2695 | ticks += ticks32 - ticks_as_32bit; |
||
2696 | else |
||
2697 | ticks -= ticks_as_32bit - ticks32; |
||
2698 | } |
||
2699 | else |
||
2700 | { |
||
2701 | guint32 epoch; |
||
2702 | |||
2703 | epoch = g_atomic_int_get (&g_win32_tick_epoch); |
||
2704 | |||
2705 | /* Must read ticks after the epoch. Then we're guaranteed |
||
2706 | * that the ticks value we read is higher or equal to any |
||
2707 | * previous ones that lead to the writing of the epoch. |
||
2708 | */ |
||
2709 | ticks32 = timeGetTime(); |
||
2710 | |||
2711 | /* We store the MSB of the current time as the LSB |
||
2712 | * of the epoch. Comparing these bits lets us detect when |
||
2713 | * the 32bit counter has wrapped so we can increase the |
||
2714 | * epoch. |
||
2715 | * |
||
2716 | * This will work as long as this function is called at |
||
2717 | * least once every ~24 days, which is half the wrap time |
||
2718 | * of a 32bit msec counter. I think this is pretty likely. |
||
2719 | * |
||
2720 | * Note that g_win32_tick_epoch is a process local state, |
||
2721 | * so the monotonic clock will not be the same between |
||
2722 | * processes. |
||
2723 | */ |
||
2724 | if ((ticks32 >> 31) != (epoch & 1)) |
||
2725 | { |
||
2726 | epoch++; |
||
2727 | g_atomic_int_set (&g_win32_tick_epoch, epoch); |
||
2728 | } |
||
2729 | |||
2730 | |||
2731 | ticks = (guint64)ticks32 | ((guint64)epoch) << 31; |
||
2732 | } |
||
2733 | |||
2734 | return ticks * 1000; |
||
2735 | } |
||
2736 | #elif defined(HAVE_MACH_MACH_TIME_H) /* Mac OS */ |
||
2737 | gint64 |
||
2738 | g_get_monotonic_time (void) |
||
2739 | { |
||
2740 | static mach_timebase_info_data_t timebase_info; |
||
2741 | |||
2742 | if (timebase_info.denom == 0) |
||
2743 | { |
||
2744 | /* This is a fraction that we must use to scale |
||
2745 | * mach_absolute_time() by in order to reach nanoseconds. |
||
2746 | * |
||
2747 | * We've only ever observed this to be 1/1, but maybe it could be |
||
2748 | * 1000/1 if mach time is microseconds already, or 1/1000 if |
||
2749 | * picoseconds. Try to deal nicely with that. |
||
2750 | */ |
||
2751 | mach_timebase_info (&timebase_info); |
||
2752 | |||
2753 | /* We actually want microseconds... */ |
||
2754 | if (timebase_info.numer % 1000 == 0) |
||
2755 | timebase_info.numer /= 1000; |
||
2756 | else |
||
2757 | timebase_info.denom *= 1000; |
||
2758 | |||
2759 | /* We want to make the numer 1 to avoid having to multiply... */ |
||
2760 | if (timebase_info.denom % timebase_info.numer == 0) |
||
2761 | { |
||
2762 | timebase_info.denom /= timebase_info.numer; |
||
2763 | timebase_info.numer = 1; |
||
2764 | } |
||
2765 | else |
||
2766 | { |
||
2767 | /* We could just multiply by timebase_info.numer below, but why |
||
2768 | * bother for a case that may never actually exist... |
||
2769 | * |
||
2770 | * Plus -- performing the multiplication would risk integer |
||
2771 | * overflow. If we ever actually end up in this situation, we |
||
2772 | * should more carefully evaluate the correct course of action. |
||
2773 | */ |
||
2774 | mach_timebase_info (&timebase_info); /* Get a fresh copy for a better message */ |
||
2775 | g_error ("Got weird mach timebase info of %d/%d. Please file a bug against GLib.", |
||
2776 | timebase_info.numer, timebase_info.denom); |
||
2777 | } |
||
2778 | } |
||
2779 | |||
2780 | return mach_absolute_time () / timebase_info.denom; |
||
2781 | } |
||
2782 | #else |
||
2783 | gint64 |
||
2784 | g_get_monotonic_time (void) |
||
2785 | { |
||
2786 | struct timespec ts; |
||
2787 | gint result; |
||
2788 | |||
2789 | result = clock_gettime (CLOCK_MONOTONIC, &ts); |
||
2790 | |||
2791 | if G_UNLIKELY (result != 0) |
||
2792 | g_error ("GLib requires working CLOCK_MONOTONIC"); |
||
2793 | |||
2794 | return (((gint64) ts.tv_sec) * 1000000) + (ts.tv_nsec / 1000); |
||
2795 | } |
||
2796 | #endif |
||
2797 | |||
2798 | static void |
||
2799 | g_main_dispatch_free (gpointer dispatch) |
||
2800 | { |
||
2801 | g_slice_free (GMainDispatch, dispatch); |
||
2802 | } |
||
2803 | |||
2804 | /* Running the main loop */ |
||
2805 | |||
2806 | static GMainDispatch * |
||
2807 | get_dispatch (void) |
||
2808 | { |
||
2809 | static GPrivate depth_private = G_PRIVATE_INIT (g_main_dispatch_free); |
||
2810 | GMainDispatch *dispatch; |
||
2811 | |||
2812 | dispatch = g_private_get (&depth_private); |
||
2813 | |||
2814 | if (!dispatch) |
||
2815 | { |
||
2816 | dispatch = g_slice_new0 (GMainDispatch); |
||
2817 | g_private_set (&depth_private, dispatch); |
||
2818 | } |
||
2819 | |||
2820 | return dispatch; |
||
2821 | } |
||
2822 | |||
2823 | /** |
||
2824 | * g_main_depth: |
||
2825 | * |
||
2826 | * Returns the depth of the stack of calls to |
||
2827 | * g_main_context_dispatch() on any #GMainContext in the current thread. |
||
2828 | * That is, when called from the toplevel, it gives 0. When |
||
2829 | * called from within a callback from g_main_context_iteration() |
||
2830 | * (or g_main_loop_run(), etc.) it returns 1. When called from within |
||
2831 | * a callback to a recursive call to g_main_context_iteration(), |
||
2832 | * it returns 2. And so forth. |
||
2833 | * |
||
2834 | * This function is useful in a situation like the following: |
||
2835 | * Imagine an extremely simple "garbage collected" system. |
||
2836 | * |
||
2837 | * |[<!-- language="C" --> |
||
2838 | * static GList *free_list; |
||
2839 | * |
||
2840 | * gpointer |
||
2841 | * allocate_memory (gsize size) |
||
2842 | * { |
||
2843 | * gpointer result = g_malloc (size); |
||
2844 | * free_list = g_list_prepend (free_list, result); |
||
2845 | * return result; |
||
2846 | * } |
||
2847 | * |
||
2848 | * void |
||
2849 | * free_allocated_memory (void) |
||
2850 | * { |
||
2851 | * GList *l; |
||
2852 | * for (l = free_list; l; l = l->next); |
||
2853 | * g_free (l->data); |
||
2854 | * g_list_free (free_list); |
||
2855 | * free_list = NULL; |
||
2856 | * } |
||
2857 | * |
||
2858 | * [...] |
||
2859 | * |
||
2860 | * while (TRUE); |
||
2861 | * { |
||
2862 | * g_main_context_iteration (NULL, TRUE); |
||
2863 | * free_allocated_memory(); |
||
2864 | * } |
||
2865 | * ]| |
||
2866 | * |
||
2867 | * This works from an application, however, if you want to do the same |
||
2868 | * thing from a library, it gets more difficult, since you no longer |
||
2869 | * control the main loop. You might think you can simply use an idle |
||
2870 | * function to make the call to free_allocated_memory(), but that |
||
2871 | * doesn't work, since the idle function could be called from a |
||
2872 | * recursive callback. This can be fixed by using g_main_depth() |
||
2873 | * |
||
2874 | * |[<!-- language="C" --> |
||
2875 | * gpointer |
||
2876 | * allocate_memory (gsize size) |
||
2877 | * { |
||
2878 | * FreeListBlock *block = g_new (FreeListBlock, 1); |
||
2879 | * block->mem = g_malloc (size); |
||
2880 | * block->depth = g_main_depth (); |
||
2881 | * free_list = g_list_prepend (free_list, block); |
||
2882 | * return block->mem; |
||
2883 | * } |
||
2884 | * |
||
2885 | * void |
||
2886 | * free_allocated_memory (void) |
||
2887 | * { |
||
2888 | * GList *l; |
||
2889 | * |
||
2890 | * int depth = g_main_depth (); |
||
2891 | * for (l = free_list; l; ); |
||
2892 | * { |
||
2893 | * GList *next = l->next; |
||
2894 | * FreeListBlock *block = l->data; |
||
2895 | * if (block->depth > depth) |
||
2896 | * { |
||
2897 | * g_free (block->mem); |
||
2898 | * g_free (block); |
||
2899 | * free_list = g_list_delete_link (free_list, l); |
||
2900 | * } |
||
2901 | * |
||
2902 | * l = next; |
||
2903 | * } |
||
2904 | * } |
||
2905 | * ]| |
||
2906 | * |
||
2907 | * There is a temptation to use g_main_depth() to solve |
||
2908 | * problems with reentrancy. For instance, while waiting for data |
||
2909 | * to be received from the network in response to a menu item, |
||
2910 | * the menu item might be selected again. It might seem that |
||
2911 | * one could make the menu item's callback return immediately |
||
2912 | * and do nothing if g_main_depth() returns a value greater than 1. |
||
2913 | * However, this should be avoided since the user then sees selecting |
||
2914 | * the menu item do nothing. Furthermore, you'll find yourself adding |
||
2915 | * these checks all over your code, since there are doubtless many, |
||
2916 | * many things that the user could do. Instead, you can use the |
||
2917 | * following techniques: |
||
2918 | * |
||
2919 | * 1. Use gtk_widget_set_sensitive() or modal dialogs to prevent |
||
2920 | * the user from interacting with elements while the main |
||
2921 | * loop is recursing. |
||
2922 | * |
||
2923 | * 2. Avoid main loop recursion in situations where you can't handle |
||
2924 | * arbitrary callbacks. Instead, structure your code so that you |
||
2925 | * simply return to the main loop and then get called again when |
||
2926 | * there is more work to do. |
||
2927 | * |
||
2928 | * Returns: The main loop recursion level in the current thread |
||
2929 | */ |
||
2930 | int |
||
2931 | g_main_depth (void) |
||
2932 | { |
||
2933 | GMainDispatch *dispatch = get_dispatch (); |
||
2934 | return dispatch->depth; |
||
2935 | } |
||
2936 | |||
2937 | /** |
||
2938 | * g_main_current_source: |
||
2939 | * |
||
2940 | * Returns the currently firing source for this thread. |
||
2941 | * |
||
2942 | * Returns: (transfer none): The currently firing source or %NULL. |
||
2943 | * |
||
2944 | * Since: 2.12 |
||
2945 | */ |
||
2946 | GSource * |
||
2947 | g_main_current_source (void) |
||
2948 | { |
||
2949 | GMainDispatch *dispatch = get_dispatch (); |
||
2950 | return dispatch->source; |
||
2951 | } |
||
2952 | |||
2953 | /** |
||
2954 | * g_source_is_destroyed: |
||
2955 | * @source: a #GSource |
||
2956 | * |
||
2957 | * Returns whether @source has been destroyed. |
||
2958 | * |
||
2959 | * This is important when you operate upon your objects |
||
2960 | * from within idle handlers, but may have freed the object |
||
2961 | * before the dispatch of your idle handler. |
||
2962 | * |
||
2963 | * |[<!-- language="C" --> |
||
2964 | * static gboolean |
||
2965 | * idle_callback (gpointer data) |
||
2966 | * { |
||
2967 | * SomeWidget *self = data; |
||
2968 | * |
||
2969 | * GDK_THREADS_ENTER (); |
||
2970 | * // do stuff with self |
||
2971 | * self->idle_id = 0; |
||
2972 | * GDK_THREADS_LEAVE (); |
||
2973 | * |
||
2974 | * return G_SOURCE_REMOVE; |
||
2975 | * } |
||
2976 | * |
||
2977 | * static void |
||
2978 | * some_widget_do_stuff_later (SomeWidget *self) |
||
2979 | * { |
||
2980 | * self->idle_id = g_idle_add (idle_callback, self); |
||
2981 | * } |
||
2982 | * |
||
2983 | * static void |
||
2984 | * some_widget_finalize (GObject *object) |
||
2985 | * { |
||
2986 | * SomeWidget *self = SOME_WIDGET (object); |
||
2987 | * |
||
2988 | * if (self->idle_id) |
||
2989 | * g_source_remove (self->idle_id); |
||
2990 | * |
||
2991 | * G_OBJECT_CLASS (parent_class)->finalize (object); |
||
2992 | * } |
||
2993 | * ]| |
||
2994 | * |
||
2995 | * This will fail in a multi-threaded application if the |
||
2996 | * widget is destroyed before the idle handler fires due |
||
2997 | * to the use after free in the callback. A solution, to |
||
2998 | * this particular problem, is to check to if the source |
||
2999 | * has already been destroy within the callback. |
||
3000 | * |
||
3001 | * |[<!-- language="C" --> |
||
3002 | * static gboolean |
||
3003 | * idle_callback (gpointer data) |
||
3004 | * { |
||
3005 | * SomeWidget *self = data; |
||
3006 | * |
||
3007 | * GDK_THREADS_ENTER (); |
||
3008 | * if (!g_source_is_destroyed (g_main_current_source ())) |
||
3009 | * { |
||
3010 | * // do stuff with self |
||
3011 | * } |
||
3012 | * GDK_THREADS_LEAVE (); |
||
3013 | * |
||
3014 | * return FALSE; |
||
3015 | * } |
||
3016 | * ]| |
||
3017 | * |
||
3018 | * Returns: %TRUE if the source has been destroyed |
||
3019 | * |
||
3020 | * Since: 2.12 |
||
3021 | */ |
||
3022 | gboolean |
||
3023 | g_source_is_destroyed (GSource *source) |
||
3024 | { |
||
3025 | return SOURCE_DESTROYED (source); |
||
3026 | } |
||
3027 | |||
3028 | /* Temporarily remove all this source's file descriptors from the |
||
3029 | * poll(), so that if data comes available for one of the file descriptors |
||
3030 | * we don't continually spin in the poll() |
||
3031 | */ |
||
3032 | /* HOLDS: source->context's lock */ |
||
3033 | static void |
||
3034 | block_source (GSource *source) |
||
3035 | { |
||
3036 | GSList *tmp_list; |
||
3037 | |||
3038 | g_return_if_fail (!SOURCE_BLOCKED (source)); |
||
3039 | |||
3040 | source->flags |= G_SOURCE_BLOCKED; |
||
3041 | |||
3042 | if (source->context) |
||
3043 | { |
||
3044 | tmp_list = source->poll_fds; |
||
3045 | while (tmp_list) |
||
3046 | { |
||
3047 | g_main_context_remove_poll_unlocked (source->context, tmp_list->data); |
||
3048 | tmp_list = tmp_list->next; |
||
3049 | } |
||
3050 | |||
3051 | for (tmp_list = source->priv->fds; tmp_list; tmp_list = tmp_list->next) |
||
3052 | g_main_context_remove_poll_unlocked (source->context, tmp_list->data); |
||
3053 | } |
||
3054 | |||
3055 | if (source->priv && source->priv->child_sources) |
||
3056 | { |
||
3057 | tmp_list = source->priv->child_sources; |
||
3058 | while (tmp_list) |
||
3059 | { |
||
3060 | block_source (tmp_list->data); |
||
3061 | tmp_list = tmp_list->next; |
||
3062 | } |
||
3063 | } |
||
3064 | } |
||
3065 | |||
3066 | /* HOLDS: source->context's lock */ |
||
3067 | static void |
||
3068 | unblock_source (GSource *source) |
||
3069 | { |
||
3070 | GSList *tmp_list; |
||
3071 | |||
3072 | g_return_if_fail (SOURCE_BLOCKED (source)); /* Source already unblocked */ |
||
3073 | g_return_if_fail (!SOURCE_DESTROYED (source)); |
||
3074 | |||
3075 | source->flags &= ~G_SOURCE_BLOCKED; |
||
3076 | |||
3077 | tmp_list = source->poll_fds; |
||
3078 | while (tmp_list) |
||
3079 | { |
||
3080 | g_main_context_add_poll_unlocked (source->context, source->priority, tmp_list->data); |
||
3081 | tmp_list = tmp_list->next; |
||
3082 | } |
||
3083 | |||
3084 | for (tmp_list = source->priv->fds; tmp_list; tmp_list = tmp_list->next) |
||
3085 | g_main_context_add_poll_unlocked (source->context, source->priority, tmp_list->data); |
||
3086 | |||
3087 | if (source->priv && source->priv->child_sources) |
||
3088 | { |
||
3089 | tmp_list = source->priv->child_sources; |
||
3090 | while (tmp_list) |
||
3091 | { |
||
3092 | unblock_source (tmp_list->data); |
||
3093 | tmp_list = tmp_list->next; |
||
3094 | } |
||
3095 | } |
||
3096 | } |
||
3097 | |||
3098 | /* HOLDS: context's lock */ |
||
3099 | static void |
||
3100 | g_main_dispatch (GMainContext *context) |
||
3101 | { |
||
3102 | GMainDispatch *current = get_dispatch (); |
||
3103 | guint i; |
||
3104 | |||
3105 | for (i = 0; i < context->pending_dispatches->len; i++) |
||
3106 | { |
||
3107 | GSource *source = context->pending_dispatches->pdata[i]; |
||
3108 | |||
3109 | context->pending_dispatches->pdata[i] = NULL; |
||
3110 | g_assert (source); |
||
3111 | |||
3112 | source->flags &= ~G_SOURCE_READY; |
||
3113 | |||
3114 | if (!SOURCE_DESTROYED (source)) |
||
3115 | { |
||
3116 | gboolean was_in_call; |
||
3117 | gpointer user_data = NULL; |
||
3118 | GSourceFunc callback = NULL; |
||
3119 | GSourceCallbackFuncs *cb_funcs; |
||
3120 | gpointer cb_data; |
||
3121 | gboolean need_destroy; |
||
3122 | |||
3123 | gboolean (*dispatch) (GSource *, |
||
3124 | GSourceFunc, |
||
3125 | gpointer); |
||
3126 | GSource *prev_source; |
||
3127 | |||
3128 | dispatch = source->source_funcs->dispatch; |
||
3129 | cb_funcs = source->callback_funcs; |
||
3130 | cb_data = source->callback_data; |
||
3131 | |||
3132 | if (cb_funcs) |
||
3133 | cb_funcs->ref (cb_data); |
||
3134 | |||
3135 | if ((source->flags & G_SOURCE_CAN_RECURSE) == 0) |
||
3136 | block_source (source); |
||
3137 | |||
3138 | was_in_call = source->flags & G_HOOK_FLAG_IN_CALL; |
||
3139 | source->flags |= G_HOOK_FLAG_IN_CALL; |
||
3140 | |||
3141 | if (cb_funcs) |
||
3142 | cb_funcs->get (cb_data, source, &callback, &user_data); |
||
3143 | |||
3144 | UNLOCK_CONTEXT (context); |
||
3145 | |||
3146 | /* These operations are safe because 'current' is thread-local |
||
3147 | * and not modified from anywhere but this function. |
||
3148 | */ |
||
3149 | prev_source = current->source; |
||
3150 | current->source = source; |
||
3151 | current->depth++; |
||
3152 | |||
3153 | TRACE( GLIB_MAIN_BEFORE_DISPATCH (g_source_get_name (source))); |
||
3154 | need_destroy = !(* dispatch) (source, callback, user_data); |
||
3155 | TRACE( GLIB_MAIN_AFTER_DISPATCH (g_source_get_name (source))); |
||
3156 | |||
3157 | current->source = prev_source; |
||
3158 | current->depth--; |
||
3159 | |||
3160 | if (cb_funcs) |
||
3161 | cb_funcs->unref (cb_data); |
||
3162 | |||
3163 | LOCK_CONTEXT (context); |
||
3164 | |||
3165 | if (!was_in_call) |
||
3166 | source->flags &= ~G_HOOK_FLAG_IN_CALL; |
||
3167 | |||
3168 | if (SOURCE_BLOCKED (source) && !SOURCE_DESTROYED (source)) |
||
3169 | unblock_source (source); |
||
3170 | |||
3171 | /* Note: this depends on the fact that we can't switch |
||
3172 | * sources from one main context to another |
||
3173 | */ |
||
3174 | if (need_destroy && !SOURCE_DESTROYED (source)) |
||
3175 | { |
||
3176 | g_assert (source->context == context); |
||
3177 | g_source_destroy_internal (source, context, TRUE); |
||
3178 | } |
||
3179 | } |
||
3180 | |||
3181 | SOURCE_UNREF (source, context); |
||
3182 | } |
||
3183 | |||
3184 | g_ptr_array_set_size (context->pending_dispatches, 0); |
||
3185 | } |
||
3186 | |||
3187 | /** |
||
3188 | * g_main_context_acquire: |
||
3189 | * @context: a #GMainContext |
||
3190 | * |
||
3191 | * Tries to become the owner of the specified context. |
||
3192 | * If some other thread is the owner of the context, |
||
3193 | * returns %FALSE immediately. Ownership is properly |
||
3194 | * recursive: the owner can require ownership again |
||
3195 | * and will release ownership when g_main_context_release() |
||
3196 | * is called as many times as g_main_context_acquire(). |
||
3197 | * |
||
3198 | * You must be the owner of a context before you |
||
3199 | * can call g_main_context_prepare(), g_main_context_query(), |
||
3200 | * g_main_context_check(), g_main_context_dispatch(). |
||
3201 | * |
||
3202 | * Returns: %TRUE if the operation succeeded, and |
||
3203 | * this thread is now the owner of @context. |
||
3204 | **/ |
||
3205 | gboolean |
||
3206 | g_main_context_acquire (GMainContext *context) |
||
3207 | { |
||
3208 | gboolean result = FALSE; |
||
3209 | GThread *self = G_THREAD_SELF; |
||
3210 | |||
3211 | if (context == NULL) |
||
3212 | context = g_main_context_default (); |
||
3213 | |||
3214 | LOCK_CONTEXT (context); |
||
3215 | |||
3216 | if (!context->owner) |
||
3217 | { |
||
3218 | context->owner = self; |
||
3219 | g_assert (context->owner_count == 0); |
||
3220 | } |
||
3221 | |||
3222 | if (context->owner == self) |
||
3223 | { |
||
3224 | context->owner_count++; |
||
3225 | result = TRUE; |
||
3226 | } |
||
3227 | |||
3228 | UNLOCK_CONTEXT (context); |
||
3229 | |||
3230 | return result; |
||
3231 | } |
||
3232 | |||
3233 | /** |
||
3234 | * g_main_context_release: |
||
3235 | * @context: a #GMainContext |
||
3236 | * |
||
3237 | * Releases ownership of a context previously acquired by this thread |
||
3238 | * with g_main_context_acquire(). If the context was acquired multiple |
||
3239 | * times, the ownership will be released only when g_main_context_release() |
||
3240 | * is called as many times as it was acquired. |
||
3241 | **/ |
||
3242 | void |
||
3243 | g_main_context_release (GMainContext *context) |
||
3244 | { |
||
3245 | if (context == NULL) |
||
3246 | context = g_main_context_default (); |
||
3247 | |||
3248 | LOCK_CONTEXT (context); |
||
3249 | |||
3250 | context->owner_count--; |
||
3251 | if (context->owner_count == 0) |
||
3252 | { |
||
3253 | context->owner = NULL; |
||
3254 | |||
3255 | if (context->waiters) |
||
3256 | { |
||
3257 | GMainWaiter *waiter = context->waiters->data; |
||
3258 | gboolean loop_internal_waiter = (waiter->mutex == &context->mutex); |
||
3259 | context->waiters = g_slist_delete_link (context->waiters, |
||
3260 | context->waiters); |
||
3261 | if (!loop_internal_waiter) |
||
3262 | g_mutex_lock (waiter->mutex); |
||
3263 | |||
3264 | g_cond_signal (waiter->cond); |
||
3265 | |||
3266 | if (!loop_internal_waiter) |
||
3267 | g_mutex_unlock (waiter->mutex); |
||
3268 | } |
||
3269 | } |
||
3270 | |||
3271 | UNLOCK_CONTEXT (context); |
||
3272 | } |
||
3273 | |||
3274 | /** |
||
3275 | * g_main_context_wait: |
||
3276 | * @context: a #GMainContext |
||
3277 | * @cond: a condition variable |
||
3278 | * @mutex: a mutex, currently held |
||
3279 | * |
||
3280 | * Tries to become the owner of the specified context, |
||
3281 | * as with g_main_context_acquire(). But if another thread |
||
3282 | * is the owner, atomically drop @mutex and wait on @cond until |
||
3283 | * that owner releases ownership or until @cond is signaled, then |
||
3284 | * try again (once) to become the owner. |
||
3285 | * |
||
3286 | * Returns: %TRUE if the operation succeeded, and |
||
3287 | * this thread is now the owner of @context. |
||
3288 | **/ |
||
3289 | gboolean |
||
3290 | g_main_context_wait (GMainContext *context, |
||
3291 | GCond *cond, |
||
3292 | GMutex *mutex) |
||
3293 | { |
||
3294 | gboolean result = FALSE; |
||
3295 | GThread *self = G_THREAD_SELF; |
||
3296 | gboolean loop_internal_waiter; |
||
3297 | |||
3298 | if (context == NULL) |
||
3299 | context = g_main_context_default (); |
||
3300 | |||
3301 | if G_UNLIKELY (cond != &context->cond || mutex != &context->mutex) |
||
3302 | { |
||
3303 | static gboolean warned; |
||
3304 | |||
3305 | if (!warned) |
||
3306 | { |
||
3307 | g_critical ("WARNING!! g_main_context_wait() will be removed in a future release. " |
||
3308 | "If you see this message, please file a bug immediately."); |
||
3309 | warned = TRUE; |
||
3310 | } |
||
3311 | } |
||
3312 | |||
3313 | loop_internal_waiter = (mutex == &context->mutex); |
||
3314 | |||
3315 | if (!loop_internal_waiter) |
||
3316 | LOCK_CONTEXT (context); |
||
3317 | |||
3318 | if (context->owner && context->owner != self) |
||
3319 | { |
||
3320 | GMainWaiter waiter; |
||
3321 | |||
3322 | waiter.cond = cond; |
||
3323 | waiter.mutex = mutex; |
||
3324 | |||
3325 | context->waiters = g_slist_append (context->waiters, &waiter); |
||
3326 | |||
3327 | if (!loop_internal_waiter) |
||
3328 | UNLOCK_CONTEXT (context); |
||
3329 | g_cond_wait (cond, mutex); |
||
3330 | if (!loop_internal_waiter) |
||
3331 | LOCK_CONTEXT (context); |
||
3332 | |||
3333 | context->waiters = g_slist_remove (context->waiters, &waiter); |
||
3334 | } |
||
3335 | |||
3336 | if (!context->owner) |
||
3337 | { |
||
3338 | context->owner = self; |
||
3339 | g_assert (context->owner_count == 0); |
||
3340 | } |
||
3341 | |||
3342 | if (context->owner == self) |
||
3343 | { |
||
3344 | context->owner_count++; |
||
3345 | result = TRUE; |
||
3346 | } |
||
3347 | |||
3348 | if (!loop_internal_waiter) |
||
3349 | UNLOCK_CONTEXT (context); |
||
3350 | |||
3351 | return result; |
||
3352 | } |
||
3353 | |||
3354 | /** |
||
3355 | * g_main_context_prepare: |
||
3356 | * @context: a #GMainContext |
||
3357 | * @priority: location to store priority of highest priority |
||
3358 | * source already ready. |
||
3359 | * |
||
3360 | * Prepares to poll sources within a main loop. The resulting information |
||
3361 | * for polling is determined by calling g_main_context_query (). |
||
3362 | * |
||
3363 | * You must have successfully acquired the context with |
||
3364 | * g_main_context_acquire() before you may call this function. |
||
3365 | * |
||
3366 | * Returns: %TRUE if some source is ready to be dispatched |
||
3367 | * prior to polling. |
||
3368 | **/ |
||
3369 | gboolean |
||
3370 | g_main_context_prepare (GMainContext *context, |
||
3371 | gint *priority) |
||
3372 | { |
||
3373 | guint i; |
||
3374 | gint n_ready = 0; |
||
3375 | gint current_priority = G_MAXINT; |
||
3376 | GSource *source; |
||
3377 | GSourceIter iter; |
||
3378 | |||
3379 | if (context == NULL) |
||
3380 | context = g_main_context_default (); |
||
3381 | |||
3382 | LOCK_CONTEXT (context); |
||
3383 | |||
3384 | context->time_is_fresh = FALSE; |
||
3385 | |||
3386 | if (context->in_check_or_prepare) |
||
3387 | { |
||
3388 | g_warning ("g_main_context_prepare() called recursively from within a source's check() or " |
||
3389 | "prepare() member."); |
||
3390 | UNLOCK_CONTEXT (context); |
||
3391 | return FALSE; |
||
3392 | } |
||
3393 | |||
3394 | #if 0 |
||
3395 | /* If recursing, finish up current dispatch, before starting over */ |
||
3396 | if (context->pending_dispatches) |
||
3397 | { |
||
3398 | if (dispatch) |
||
3399 | g_main_dispatch (context, ¤t_time); |
||
3400 | |||
3401 | UNLOCK_CONTEXT (context); |
||
3402 | return TRUE; |
||
3403 | } |
||
3404 | #endif |
||
3405 | |||
3406 | /* If recursing, clear list of pending dispatches */ |
||
3407 | |||
3408 | for (i = 0; i < context->pending_dispatches->len; i++) |
||
3409 | { |
||
3410 | if (context->pending_dispatches->pdata[i]) |
||
3411 | SOURCE_UNREF ((GSource *)context->pending_dispatches->pdata[i], context); |
||
3412 | } |
||
3413 | g_ptr_array_set_size (context->pending_dispatches, 0); |
||
3414 | |||
3415 | /* Prepare all sources */ |
||
3416 | |||
3417 | context->timeout = -1; |
||
3418 | |||
3419 | g_source_iter_init (&iter, context, TRUE); |
||
3420 | while (g_source_iter_next (&iter, &source)) |
||
3421 | { |
||
3422 | gint source_timeout = -1; |
||
3423 | |||
3424 | if (SOURCE_DESTROYED (source) || SOURCE_BLOCKED (source)) |
||
3425 | continue; |
||
3426 | if ((n_ready > 0) && (source->priority > current_priority)) |
||
3427 | break; |
||
3428 | |||
3429 | if (!(source->flags & G_SOURCE_READY)) |
||
3430 | { |
||
3431 | gboolean result; |
||
3432 | gboolean (* prepare) (GSource *source, |
||
3433 | gint *timeout); |
||
3434 | |||
3435 | prepare = source->source_funcs->prepare; |
||
3436 | |||
3437 | if (prepare) |
||
3438 | { |
||
3439 | context->in_check_or_prepare++; |
||
3440 | UNLOCK_CONTEXT (context); |
||
3441 | |||
3442 | result = (* prepare) (source, &source_timeout); |
||
3443 | |||
3444 | LOCK_CONTEXT (context); |
||
3445 | context->in_check_or_prepare--; |
||
3446 | } |
||
3447 | else |
||
3448 | { |
||
3449 | source_timeout = -1; |
||
3450 | result = FALSE; |
||
3451 | } |
||
3452 | |||
3453 | if (result == FALSE && source->priv->ready_time != -1) |
||
3454 | { |
||
3455 | if (!context->time_is_fresh) |
||
3456 | { |
||
3457 | context->time = g_get_monotonic_time (); |
||
3458 | context->time_is_fresh = TRUE; |
||
3459 | } |
||
3460 | |||
3461 | if (source->priv->ready_time <= context->time) |
||
3462 | { |
||
3463 | source_timeout = 0; |
||
3464 | result = TRUE; |
||
3465 | } |
||
3466 | else |
||
3467 | { |
||
3468 | gint timeout; |
||
3469 | |||
3470 | /* rounding down will lead to spinning, so always round up */ |
||
3471 | timeout = (source->priv->ready_time - context->time + 999) / 1000; |
||
3472 | |||
3473 | if (source_timeout < 0 || timeout < source_timeout) |
||
3474 | source_timeout = timeout; |
||
3475 | } |
||
3476 | } |
||
3477 | |||
3478 | if (result) |
||
3479 | { |
||
3480 | GSource *ready_source = source; |
||
3481 | |||
3482 | while (ready_source) |
||
3483 | { |
||
3484 | ready_source->flags |= G_SOURCE_READY; |
||
3485 | ready_source = ready_source->priv->parent_source; |
||
3486 | } |
||
3487 | } |
||
3488 | } |
||
3489 | |||
3490 | if (source->flags & G_SOURCE_READY) |
||
3491 | { |
||
3492 | n_ready++; |
||
3493 | current_priority = source->priority; |
||
3494 | context->timeout = 0; |
||
3495 | } |
||
3496 | |||
3497 | if (source_timeout >= 0) |
||
3498 | { |
||
3499 | if (context->timeout < 0) |
||
3500 | context->timeout = source_timeout; |
||
3501 | else |
||
3502 | context->timeout = MIN (context->timeout, source_timeout); |
||
3503 | } |
||
3504 | } |
||
3505 | g_source_iter_clear (&iter); |
||
3506 | |||
3507 | UNLOCK_CONTEXT (context); |
||
3508 | |||
3509 | if (priority) |
||
3510 | *priority = current_priority; |
||
3511 | |||
3512 | return (n_ready > 0); |
||
3513 | } |
||
3514 | |||
3515 | /** |
||
3516 | * g_main_context_query: |
||
3517 | * @context: a #GMainContext |
||
3518 | * @max_priority: maximum priority source to check |
||
3519 | * @timeout_: (out): location to store timeout to be used in polling |
||
3520 | * @fds: (out caller-allocates) (array length=n_fds): location to |
||
3521 | * store #GPollFD records that need to be polled. |
||
3522 | * @n_fds: (in): length of @fds. |
||
3523 | * |
||
3524 | * Determines information necessary to poll this main loop. |
||
3525 | * |
||
3526 | * You must have successfully acquired the context with |
||
3527 | * g_main_context_acquire() before you may call this function. |
||
3528 | * |
||
3529 | * Returns: the number of records actually stored in @fds, |
||
3530 | * or, if more than @n_fds records need to be stored, the number |
||
3531 | * of records that need to be stored. |
||
3532 | **/ |
||
3533 | gint |
||
3534 | g_main_context_query (GMainContext *context, |
||
3535 | gint max_priority, |
||
3536 | gint *timeout, |
||
3537 | GPollFD *fds, |
||
3538 | gint n_fds) |
||
3539 | { |
||
3540 | gint n_poll; |
||
3541 | GPollRec *pollrec, *lastpollrec; |
||
3542 | gushort events; |
||
3543 | |||
3544 | LOCK_CONTEXT (context); |
||
3545 | |||
3546 | n_poll = 0; |
||
3547 | lastpollrec = NULL; |
||
3548 | for (pollrec = context->poll_records; pollrec; pollrec = pollrec->next) |
||
3549 | { |
||
3550 | if (pollrec->priority > max_priority) |
||
3551 | continue; |
||
3552 | |||
3553 | /* In direct contradiction to the Unix98 spec, IRIX runs into |
||
3554 | * difficulty if you pass in POLLERR, POLLHUP or POLLNVAL |
||
3555 | * flags in the events field of the pollfd while it should |
||
3556 | * just ignoring them. So we mask them out here. |
||
3557 | */ |
||
3558 | events = pollrec->fd->events & ~(G_IO_ERR|G_IO_HUP|G_IO_NVAL); |
||
3559 | |||
3560 | if (lastpollrec && pollrec->fd->fd == lastpollrec->fd->fd) |
||
3561 | { |
||
3562 | if (n_poll - 1 < n_fds) |
||
3563 | fds[n_poll - 1].events |= events; |
||
3564 | } |
||
3565 | else |
||
3566 | { |
||
3567 | if (n_poll < n_fds) |
||
3568 | { |
||
3569 | fds[n_poll].fd = pollrec->fd->fd; |
||
3570 | fds[n_poll].events = events; |
||
3571 | fds[n_poll].revents = 0; |
||
3572 | } |
||
3573 | |||
3574 | n_poll++; |
||
3575 | } |
||
3576 | |||
3577 | lastpollrec = pollrec; |
||
3578 | } |
||
3579 | |||
3580 | context->poll_changed = FALSE; |
||
3581 | |||
3582 | if (timeout) |
||
3583 | { |
||
3584 | *timeout = context->timeout; |
||
3585 | if (*timeout != 0) |
||
3586 | context->time_is_fresh = FALSE; |
||
3587 | } |
||
3588 | |||
3589 | UNLOCK_CONTEXT (context); |
||
3590 | |||
3591 | return n_poll; |
||
3592 | } |
||
3593 | |||
3594 | /** |
||
3595 | * g_main_context_check: |
||
3596 | * @context: a #GMainContext |
||
3597 | * @max_priority: the maximum numerical priority of sources to check |
||
3598 | * @fds: (array length=n_fds): array of #GPollFD's that was passed to |
||
3599 | * the last call to g_main_context_query() |
||
3600 | * @n_fds: return value of g_main_context_query() |
||
3601 | * |
||
3602 | * Passes the results of polling back to the main loop. |
||
3603 | * |
||
3604 | * You must have successfully acquired the context with |
||
3605 | * g_main_context_acquire() before you may call this function. |
||
3606 | * |
||
3607 | * Returns: %TRUE if some sources are ready to be dispatched. |
||
3608 | **/ |
||
3609 | gboolean |
||
3610 | g_main_context_check (GMainContext *context, |
||
3611 | gint max_priority, |
||
3612 | GPollFD *fds, |
||
3613 | gint n_fds) |
||
3614 | { |
||
3615 | GSource *source; |
||
3616 | GSourceIter iter; |
||
3617 | GPollRec *pollrec; |
||
3618 | gint n_ready = 0; |
||
3619 | gint i; |
||
3620 | |||
3621 | LOCK_CONTEXT (context); |
||
3622 | |||
3623 | if (context->in_check_or_prepare) |
||
3624 | { |
||
3625 | g_warning ("g_main_context_check() called recursively from within a source's check() or " |
||
3626 | "prepare() member."); |
||
3627 | UNLOCK_CONTEXT (context); |
||
3628 | return FALSE; |
||
3629 | } |
||
3630 | |||
3631 | if (context->wake_up_rec.revents) |
||
3632 | g_wakeup_acknowledge (context->wakeup); |
||
3633 | |||
3634 | /* If the set of poll file descriptors changed, bail out |
||
3635 | * and let the main loop rerun |
||
3636 | */ |
||
3637 | if (context->poll_changed) |
||
3638 | { |
||
3639 | UNLOCK_CONTEXT (context); |
||
3640 | return FALSE; |
||
3641 | } |
||
3642 | |||
3643 | pollrec = context->poll_records; |
||
3644 | i = 0; |
||
3645 | while (pollrec && i < n_fds) |
||
3646 | { |
||
3647 | while (pollrec && pollrec->fd->fd == fds[i].fd) |
||
3648 | { |
||
3649 | if (pollrec->priority <= max_priority) |
||
3650 | { |
||
3651 | pollrec->fd->revents = |
||
3652 | fds[i].revents & (pollrec->fd->events | G_IO_ERR | G_IO_HUP | G_IO_NVAL); |
||
3653 | } |
||
3654 | pollrec = pollrec->next; |
||
3655 | } |
||
3656 | |||
3657 | i++; |
||
3658 | } |
||
3659 | |||
3660 | g_source_iter_init (&iter, context, TRUE); |
||
3661 | while (g_source_iter_next (&iter, &source)) |
||
3662 | { |
||
3663 | if (SOURCE_DESTROYED (source) || SOURCE_BLOCKED (source)) |
||
3664 | continue; |
||
3665 | if ((n_ready > 0) && (source->priority > max_priority)) |
||
3666 | break; |
||
3667 | |||
3668 | if (!(source->flags & G_SOURCE_READY)) |
||
3669 | { |
||
3670 | gboolean result; |
||
3671 | gboolean (* check) (GSource *source); |
||
3672 | |||
3673 | check = source->source_funcs->check; |
||
3674 | |||
3675 | if (check) |
||
3676 | { |
||
3677 | /* If the check function is set, call it. */ |
||
3678 | context->in_check_or_prepare++; |
||
3679 | UNLOCK_CONTEXT (context); |
||
3680 | |||
3681 | result = (* check) (source); |
||
3682 | |||
3683 | LOCK_CONTEXT (context); |
||
3684 | context->in_check_or_prepare--; |
||
3685 | } |
||
3686 | else |
||
3687 | result = FALSE; |
||
3688 | |||
3689 | if (result == FALSE) |
||
3690 | { |
||
3691 | GSList *tmp_list; |
||
3692 | |||
3693 | /* If not already explicitly flagged ready by ->check() |
||
3694 | * (or if we have no check) then we can still be ready if |
||
3695 | * any of our fds poll as ready. |
||
3696 | */ |
||
3697 | for (tmp_list = source->priv->fds; tmp_list; tmp_list = tmp_list->next) |
||
3698 | { |
||
3699 | GPollFD *pollfd = tmp_list->data; |
||
3700 | |||
3701 | if (pollfd->revents) |
||
3702 | { |
||
3703 | result = TRUE; |
||
3704 | break; |
||
3705 | } |
||
3706 | } |
||
3707 | } |
||
3708 | |||
3709 | if (result == FALSE && source->priv->ready_time != -1) |
||
3710 | { |
||
3711 | if (!context->time_is_fresh) |
||
3712 | { |
||
3713 | context->time = g_get_monotonic_time (); |
||
3714 | context->time_is_fresh = TRUE; |
||
3715 | } |
||
3716 | |||
3717 | if (source->priv->ready_time <= context->time) |
||
3718 | result = TRUE; |
||
3719 | } |
||
3720 | |||
3721 | if (result) |
||
3722 | { |
||
3723 | GSource *ready_source = source; |
||
3724 | |||
3725 | while (ready_source) |
||
3726 | { |
||
3727 | ready_source->flags |= G_SOURCE_READY; |
||
3728 | ready_source = ready_source->priv->parent_source; |
||
3729 | } |
||
3730 | } |
||
3731 | } |
||
3732 | |||
3733 | if (source->flags & G_SOURCE_READY) |
||
3734 | { |
||
3735 | source->ref_count++; |
||
3736 | g_ptr_array_add (context->pending_dispatches, source); |
||
3737 | |||
3738 | n_ready++; |
||
3739 | |||
3740 | /* never dispatch sources with less priority than the first |
||
3741 | * one we choose to dispatch |
||
3742 | */ |
||
3743 | max_priority = source->priority; |
||
3744 | } |
||
3745 | } |
||
3746 | g_source_iter_clear (&iter); |
||
3747 | |||
3748 | UNLOCK_CONTEXT (context); |
||
3749 | |||
3750 | return n_ready > 0; |
||
3751 | } |
||
3752 | |||
3753 | /** |
||
3754 | * g_main_context_dispatch: |
||
3755 | * @context: a #GMainContext |
||
3756 | * |
||
3757 | * Dispatches all pending sources. |
||
3758 | * |
||
3759 | * You must have successfully acquired the context with |
||
3760 | * g_main_context_acquire() before you may call this function. |
||
3761 | **/ |
||
3762 | void |
||
3763 | g_main_context_dispatch (GMainContext *context) |
||
3764 | { |
||
3765 | LOCK_CONTEXT (context); |
||
3766 | |||
3767 | if (context->pending_dispatches->len > 0) |
||
3768 | { |
||
3769 | g_main_dispatch (context); |
||
3770 | } |
||
3771 | |||
3772 | UNLOCK_CONTEXT (context); |
||
3773 | } |
||
3774 | |||
3775 | /* HOLDS context lock */ |
||
3776 | static gboolean |
||
3777 | g_main_context_iterate (GMainContext *context, |
||
3778 | gboolean block, |
||
3779 | gboolean dispatch, |
||
3780 | GThread *self) |
||
3781 | { |
||
3782 | gint max_priority; |
||
3783 | gint timeout; |
||
3784 | gboolean some_ready; |
||
3785 | gint nfds, allocated_nfds; |
||
3786 | GPollFD *fds = NULL; |
||
3787 | |||
3788 | UNLOCK_CONTEXT (context); |
||
3789 | |||
3790 | if (!g_main_context_acquire (context)) |
||
3791 | { |
||
3792 | gboolean got_ownership; |
||
3793 | |||
3794 | LOCK_CONTEXT (context); |
||
3795 | |||
3796 | if (!block) |
||
3797 | return FALSE; |
||
3798 | |||
3799 | got_ownership = g_main_context_wait (context, |
||
3800 | &context->cond, |
||
3801 | &context->mutex); |
||
3802 | |||
3803 | if (!got_ownership) |
||
3804 | return FALSE; |
||
3805 | } |
||
3806 | else |
||
3807 | LOCK_CONTEXT (context); |
||
3808 | |||
3809 | if (!context->cached_poll_array) |
||
3810 | { |
||
3811 | context->cached_poll_array_size = context->n_poll_records; |
||
3812 | context->cached_poll_array = g_new (GPollFD, context->n_poll_records); |
||
3813 | } |
||
3814 | |||
3815 | allocated_nfds = context->cached_poll_array_size; |
||
3816 | fds = context->cached_poll_array; |
||
3817 | |||
3818 | UNLOCK_CONTEXT (context); |
||
3819 | |||
3820 | g_main_context_prepare (context, &max_priority); |
||
3821 | |||
3822 | while ((nfds = g_main_context_query (context, max_priority, &timeout, fds, |
||
3823 | allocated_nfds)) > allocated_nfds) |
||
3824 | { |
||
3825 | LOCK_CONTEXT (context); |
||
3826 | g_free (fds); |
||
3827 | context->cached_poll_array_size = allocated_nfds = nfds; |
||
3828 | context->cached_poll_array = fds = g_new (GPollFD, nfds); |
||
3829 | UNLOCK_CONTEXT (context); |
||
3830 | } |
||
3831 | |||
3832 | if (!block) |
||
3833 | timeout = 0; |
||
3834 | |||
3835 | g_main_context_poll (context, timeout, max_priority, fds, nfds); |
||
3836 | |||
3837 | some_ready = g_main_context_check (context, max_priority, fds, nfds); |
||
3838 | |||
3839 | if (dispatch) |
||
3840 | g_main_context_dispatch (context); |
||
3841 | |||
3842 | g_main_context_release (context); |
||
3843 | |||
3844 | LOCK_CONTEXT (context); |
||
3845 | |||
3846 | return some_ready; |
||
3847 | } |
||
3848 | |||
3849 | /** |
||
3850 | * g_main_context_pending: |
||
3851 | * @context: (allow-none): a #GMainContext (if %NULL, the default context will be used) |
||
3852 | * |
||
3853 | * Checks if any sources have pending events for the given context. |
||
3854 | * |
||
3855 | * Returns: %TRUE if events are pending. |
||
3856 | **/ |
||
3857 | gboolean |
||
3858 | g_main_context_pending (GMainContext *context) |
||
3859 | { |
||
3860 | gboolean retval; |
||
3861 | |||
3862 | if (!context) |
||
3863 | context = g_main_context_default(); |
||
3864 | |||
3865 | LOCK_CONTEXT (context); |
||
3866 | retval = g_main_context_iterate (context, FALSE, FALSE, G_THREAD_SELF); |
||
3867 | UNLOCK_CONTEXT (context); |
||
3868 | |||
3869 | return retval; |
||
3870 | } |
||
3871 | |||
3872 | /** |
||
3873 | * g_main_context_iteration: |
||
3874 | * @context: (allow-none): a #GMainContext (if %NULL, the default context will be used) |
||
3875 | * @may_block: whether the call may block. |
||
3876 | * |
||
3877 | * Runs a single iteration for the given main loop. This involves |
||
3878 | * checking to see if any event sources are ready to be processed, |
||
3879 | * then if no events sources are ready and @may_block is %TRUE, waiting |
||
3880 | * for a source to become ready, then dispatching the highest priority |
||
3881 | * events sources that are ready. Otherwise, if @may_block is %FALSE |
||
3882 | * sources are not waited to become ready, only those highest priority |
||
3883 | * events sources will be dispatched (if any), that are ready at this |
||
3884 | * given moment without further waiting. |
||
3885 | * |
||
3886 | * Note that even when @may_block is %TRUE, it is still possible for |
||
3887 | * g_main_context_iteration() to return %FALSE, since the wait may |
||
3888 | * be interrupted for other reasons than an event source becoming ready. |
||
3889 | * |
||
3890 | * Returns: %TRUE if events were dispatched. |
||
3891 | **/ |
||
3892 | gboolean |
||
3893 | g_main_context_iteration (GMainContext *context, gboolean may_block) |
||
3894 | { |
||
3895 | gboolean retval; |
||
3896 | |||
3897 | if (!context) |
||
3898 | context = g_main_context_default(); |
||
3899 | |||
3900 | LOCK_CONTEXT (context); |
||
3901 | retval = g_main_context_iterate (context, may_block, TRUE, G_THREAD_SELF); |
||
3902 | UNLOCK_CONTEXT (context); |
||
3903 | |||
3904 | return retval; |
||
3905 | } |
||
3906 | |||
3907 | /** |
||
3908 | * g_main_loop_new: |
||
3909 | * @context: (allow-none): a #GMainContext (if %NULL, the default context will be used). |
||
3910 | * @is_running: set to %TRUE to indicate that the loop is running. This |
||
3911 | * is not very important since calling g_main_loop_run() will set this to |
||
3912 | * %TRUE anyway. |
||
3913 | * |
||
3914 | * Creates a new #GMainLoop structure. |
||
3915 | * |
||
3916 | * Returns: a new #GMainLoop. |
||
3917 | **/ |
||
3918 | GMainLoop * |
||
3919 | g_main_loop_new (GMainContext *context, |
||
3920 | gboolean is_running) |
||
3921 | { |
||
3922 | GMainLoop *loop; |
||
3923 | |||
3924 | if (!context) |
||
3925 | context = g_main_context_default(); |
||
3926 | |||
3927 | g_main_context_ref (context); |
||
3928 | |||
3929 | loop = g_new0 (GMainLoop, 1); |
||
3930 | loop->context = context; |
||
3931 | loop->is_running = is_running != FALSE; |
||
3932 | loop->ref_count = 1; |
||
3933 | |||
3934 | return loop; |
||
3935 | } |
||
3936 | |||
3937 | /** |
||
3938 | * g_main_loop_ref: |
||
3939 | * @loop: a #GMainLoop |
||
3940 | * |
||
3941 | * Increases the reference count on a #GMainLoop object by one. |
||
3942 | * |
||
3943 | * Returns: @loop |
||
3944 | **/ |
||
3945 | GMainLoop * |
||
3946 | g_main_loop_ref (GMainLoop *loop) |
||
3947 | { |
||
3948 | g_return_val_if_fail (loop != NULL, NULL); |
||
3949 | g_return_val_if_fail (g_atomic_int_get (&loop->ref_count) > 0, NULL); |
||
3950 | |||
3951 | g_atomic_int_inc (&loop->ref_count); |
||
3952 | |||
3953 | return loop; |
||
3954 | } |
||
3955 | |||
3956 | /** |
||
3957 | * g_main_loop_unref: |
||
3958 | * @loop: a #GMainLoop |
||
3959 | * |
||
3960 | * Decreases the reference count on a #GMainLoop object by one. If |
||
3961 | * the result is zero, free the loop and free all associated memory. |
||
3962 | **/ |
||
3963 | void |
||
3964 | g_main_loop_unref (GMainLoop *loop) |
||
3965 | { |
||
3966 | g_return_if_fail (loop != NULL); |
||
3967 | g_return_if_fail (g_atomic_int_get (&loop->ref_count) > 0); |
||
3968 | |||
3969 | if (!g_atomic_int_dec_and_test (&loop->ref_count)) |
||
3970 | return; |
||
3971 | |||
3972 | g_main_context_unref (loop->context); |
||
3973 | g_free (loop); |
||
3974 | } |
||
3975 | |||
3976 | /** |
||
3977 | * g_main_loop_run: |
||
3978 | * @loop: a #GMainLoop |
||
3979 | * |
||
3980 | * Runs a main loop until g_main_loop_quit() is called on the loop. |
||
3981 | * If this is called for the thread of the loop's #GMainContext, |
||
3982 | * it will process events from the loop, otherwise it will |
||
3983 | * simply wait. |
||
3984 | **/ |
||
3985 | void |
||
3986 | g_main_loop_run (GMainLoop *loop) |
||
3987 | { |
||
3988 | GThread *self = G_THREAD_SELF; |
||
3989 | |||
3990 | g_return_if_fail (loop != NULL); |
||
3991 | g_return_if_fail (g_atomic_int_get (&loop->ref_count) > 0); |
||
3992 | |||
3993 | if (!g_main_context_acquire (loop->context)) |
||
3994 | { |
||
3995 | gboolean got_ownership = FALSE; |
||
3996 | |||
3997 | /* Another thread owns this context */ |
||
3998 | LOCK_CONTEXT (loop->context); |
||
3999 | |||
4000 | g_atomic_int_inc (&loop->ref_count); |
||
4001 | |||
4002 | if (!loop->is_running) |
||
4003 | loop->is_running = TRUE; |
||
4004 | |||
4005 | while (loop->is_running && !got_ownership) |
||
4006 | got_ownership = g_main_context_wait (loop->context, |
||
4007 | &loop->context->cond, |
||
4008 | &loop->context->mutex); |
||
4009 | |||
4010 | if (!loop->is_running) |
||
4011 | { |
||
4012 | UNLOCK_CONTEXT (loop->context); |
||
4013 | if (got_ownership) |
||
4014 | g_main_context_release (loop->context); |
||
4015 | g_main_loop_unref (loop); |
||
4016 | return; |
||
4017 | } |
||
4018 | |||
4019 | g_assert (got_ownership); |
||
4020 | } |
||
4021 | else |
||
4022 | LOCK_CONTEXT (loop->context); |
||
4023 | |||
4024 | if (loop->context->in_check_or_prepare) |
||
4025 | { |
||
4026 | g_warning ("g_main_loop_run(): called recursively from within a source's " |
||
4027 | "check() or prepare() member, iteration not possible."); |
||
4028 | return; |
||
4029 | } |
||
4030 | |||
4031 | g_atomic_int_inc (&loop->ref_count); |
||
4032 | loop->is_running = TRUE; |
||
4033 | while (loop->is_running) |
||
4034 | g_main_context_iterate (loop->context, TRUE, TRUE, self); |
||
4035 | |||
4036 | UNLOCK_CONTEXT (loop->context); |
||
4037 | |||
4038 | g_main_context_release (loop->context); |
||
4039 | |||
4040 | g_main_loop_unref (loop); |
||
4041 | } |
||
4042 | |||
4043 | /** |
||
4044 | * g_main_loop_quit: |
||
4045 | * @loop: a #GMainLoop |
||
4046 | * |
||
4047 | * Stops a #GMainLoop from running. Any calls to g_main_loop_run() |
||
4048 | * for the loop will return. |
||
4049 | * |
||
4050 | * Note that sources that have already been dispatched when |
||
4051 | * g_main_loop_quit() is called will still be executed. |
||
4052 | **/ |
||
4053 | void |
||
4054 | g_main_loop_quit (GMainLoop *loop) |
||
4055 | { |
||
4056 | g_return_if_fail (loop != NULL); |
||
4057 | g_return_if_fail (g_atomic_int_get (&loop->ref_count) > 0); |
||
4058 | |||
4059 | LOCK_CONTEXT (loop->context); |
||
4060 | loop->is_running = FALSE; |
||
4061 | g_wakeup_signal (loop->context->wakeup); |
||
4062 | |||
4063 | g_cond_broadcast (&loop->context->cond); |
||
4064 | |||
4065 | UNLOCK_CONTEXT (loop->context); |
||
4066 | } |
||
4067 | |||
4068 | /** |
||
4069 | * g_main_loop_is_running: |
||
4070 | * @loop: a #GMainLoop. |
||
4071 | * |
||
4072 | * Checks to see if the main loop is currently being run via g_main_loop_run(). |
||
4073 | * |
||
4074 | * Returns: %TRUE if the mainloop is currently being run. |
||
4075 | **/ |
||
4076 | gboolean |
||
4077 | g_main_loop_is_running (GMainLoop *loop) |
||
4078 | { |
||
4079 | g_return_val_if_fail (loop != NULL, FALSE); |
||
4080 | g_return_val_if_fail (g_atomic_int_get (&loop->ref_count) > 0, FALSE); |
||
4081 | |||
4082 | return loop->is_running; |
||
4083 | } |
||
4084 | |||
4085 | /** |
||
4086 | * g_main_loop_get_context: |
||
4087 | * @loop: a #GMainLoop. |
||
4088 | * |
||
4089 | * Returns the #GMainContext of @loop. |
||
4090 | * |
||
4091 | * Returns: (transfer none): the #GMainContext of @loop |
||
4092 | **/ |
||
4093 | GMainContext * |
||
4094 | g_main_loop_get_context (GMainLoop *loop) |
||
4095 | { |
||
4096 | g_return_val_if_fail (loop != NULL, NULL); |
||
4097 | g_return_val_if_fail (g_atomic_int_get (&loop->ref_count) > 0, NULL); |
||
4098 | |||
4099 | return loop->context; |
||
4100 | } |
||
4101 | |||
4102 | /* HOLDS: context's lock */ |
||
4103 | static void |
||
4104 | g_main_context_poll (GMainContext *context, |
||
4105 | gint timeout, |
||
4106 | gint priority, |
||
4107 | GPollFD *fds, |
||
4108 | gint n_fds) |
||
4109 | { |
||
4110 | #ifdef G_MAIN_POLL_DEBUG |
||
4111 | GTimer *poll_timer; |
||
4112 | GPollRec *pollrec; |
||
4113 | gint i; |
||
4114 | #endif |
||
4115 | |||
4116 | GPollFunc poll_func; |
||
4117 | |||
4118 | if (n_fds || timeout != 0) |
||
4119 | { |
||
4120 | #ifdef G_MAIN_POLL_DEBUG |
||
4121 | poll_timer = NULL; |
||
4122 | if (_g_main_poll_debug) |
||
4123 | { |
||
4124 | g_print ("polling context=%p n=%d timeout=%d\n", |
||
4125 | context, n_fds, timeout); |
||
4126 | poll_timer = g_timer_new (); |
||
4127 | } |
||
4128 | #endif |
||
4129 | |||
4130 | LOCK_CONTEXT (context); |
||
4131 | |||
4132 | poll_func = context->poll_func; |
||
4133 | |||
4134 | UNLOCK_CONTEXT (context); |
||
4135 | if ((*poll_func) (fds, n_fds, timeout) < 0 && errno != EINTR) |
||
4136 | { |
||
4137 | #ifndef G_OS_WIN32 |
||
4138 | g_warning ("poll(2) failed due to: %s.", |
||
4139 | g_strerror (errno)); |
||
4140 | #else |
||
4141 | /* If g_poll () returns -1, it has already called g_warning() */ |
||
4142 | #endif |
||
4143 | } |
||
4144 | |||
4145 | #ifdef G_MAIN_POLL_DEBUG |
||
4146 | if (_g_main_poll_debug) |
||
4147 | { |
||
4148 | LOCK_CONTEXT (context); |
||
4149 | |||
4150 | g_print ("g_main_poll(%d) timeout: %d - elapsed %12.10f seconds", |
||
4151 | n_fds, |
||
4152 | timeout, |
||
4153 | g_timer_elapsed (poll_timer, NULL)); |
||
4154 | g_timer_destroy (poll_timer); |
||
4155 | pollrec = context->poll_records; |
||
4156 | |||
4157 | while (pollrec != NULL) |
||
4158 | { |
||
4159 | i = 0; |
||
4160 | while (i < n_fds) |
||
4161 | { |
||
4162 | if (fds[i].fd == pollrec->fd->fd && |
||
4163 | pollrec->fd->events && |
||
4164 | fds[i].revents) |
||
4165 | { |
||
4166 | g_print (" [" G_POLLFD_FORMAT " :", fds[i].fd); |
||
4167 | if (fds[i].revents & G_IO_IN) |
||
4168 | g_print ("i"); |
||
4169 | if (fds[i].revents & G_IO_OUT) |
||
4170 | g_print ("o"); |
||
4171 | if (fds[i].revents & G_IO_PRI) |
||
4172 | g_print ("p"); |
||
4173 | if (fds[i].revents & G_IO_ERR) |
||
4174 | g_print ("e"); |
||
4175 | if (fds[i].revents & G_IO_HUP) |
||
4176 | g_print ("h"); |
||
4177 | if (fds[i].revents & G_IO_NVAL) |
||
4178 | g_print ("n"); |
||
4179 | g_print ("]"); |
||
4180 | } |
||
4181 | i++; |
||
4182 | } |
||
4183 | pollrec = pollrec->next; |
||
4184 | } |
||
4185 | g_print ("\n"); |
||
4186 | |||
4187 | UNLOCK_CONTEXT (context); |
||
4188 | } |
||
4189 | #endif |
||
4190 | } /* if (n_fds || timeout != 0) */ |
||
4191 | } |
||
4192 | |||
4193 | /** |
||
4194 | * g_main_context_add_poll: |
||
4195 | * @context: (allow-none): a #GMainContext (or %NULL for the default context) |
||
4196 | * @fd: a #GPollFD structure holding information about a file |
||
4197 | * descriptor to watch. |
||
4198 | * @priority: the priority for this file descriptor which should be |
||
4199 | * the same as the priority used for g_source_attach() to ensure that the |
||
4200 | * file descriptor is polled whenever the results may be needed. |
||
4201 | * |
||
4202 | * Adds a file descriptor to the set of file descriptors polled for |
||
4203 | * this context. This will very seldom be used directly. Instead |
||
4204 | * a typical event source will use g_source_add_unix_fd() instead. |
||
4205 | **/ |
||
4206 | void |
||
4207 | g_main_context_add_poll (GMainContext *context, |
||
4208 | GPollFD *fd, |
||
4209 | gint priority) |
||
4210 | { |
||
4211 | if (!context) |
||
4212 | context = g_main_context_default (); |
||
4213 | |||
4214 | g_return_if_fail (g_atomic_int_get (&context->ref_count) > 0); |
||
4215 | g_return_if_fail (fd); |
||
4216 | |||
4217 | LOCK_CONTEXT (context); |
||
4218 | g_main_context_add_poll_unlocked (context, priority, fd); |
||
4219 | UNLOCK_CONTEXT (context); |
||
4220 | } |
||
4221 | |||
4222 | /* HOLDS: main_loop_lock */ |
||
4223 | static void |
||
4224 | g_main_context_add_poll_unlocked (GMainContext *context, |
||
4225 | gint priority, |
||
4226 | GPollFD *fd) |
||
4227 | { |
||
4228 | GPollRec *prevrec, *nextrec; |
||
4229 | GPollRec *newrec = g_slice_new (GPollRec); |
||
4230 | |||
4231 | /* This file descriptor may be checked before we ever poll */ |
||
4232 | fd->revents = 0; |
||
4233 | newrec->fd = fd; |
||
4234 | newrec->priority = priority; |
||
4235 | |||
4236 | prevrec = NULL; |
||
4237 | nextrec = context->poll_records; |
||
4238 | while (nextrec) |
||
4239 | { |
||
4240 | if (nextrec->fd->fd > fd->fd) |
||
4241 | break; |
||
4242 | prevrec = nextrec; |
||
4243 | nextrec = nextrec->next; |
||
4244 | } |
||
4245 | |||
4246 | if (prevrec) |
||
4247 | prevrec->next = newrec; |
||
4248 | else |
||
4249 | context->poll_records = newrec; |
||
4250 | |||
4251 | newrec->prev = prevrec; |
||
4252 | newrec->next = nextrec; |
||
4253 | |||
4254 | if (nextrec) |
||
4255 | nextrec->prev = newrec; |
||
4256 | |||
4257 | context->n_poll_records++; |
||
4258 | |||
4259 | context->poll_changed = TRUE; |
||
4260 | |||
4261 | /* Now wake up the main loop if it is waiting in the poll() */ |
||
4262 | g_wakeup_signal (context->wakeup); |
||
4263 | } |
||
4264 | |||
4265 | /** |
||
4266 | * g_main_context_remove_poll: |
||
4267 | * @context:a #GMainContext |
||
4268 | * @fd: a #GPollFD descriptor previously added with g_main_context_add_poll() |
||
4269 | * |
||
4270 | * Removes file descriptor from the set of file descriptors to be |
||
4271 | * polled for a particular context. |
||
4272 | **/ |
||
4273 | void |
||
4274 | g_main_context_remove_poll (GMainContext *context, |
||
4275 | GPollFD *fd) |
||
4276 | { |
||
4277 | if (!context) |
||
4278 | context = g_main_context_default (); |
||
4279 | |||
4280 | g_return_if_fail (g_atomic_int_get (&context->ref_count) > 0); |
||
4281 | g_return_if_fail (fd); |
||
4282 | |||
4283 | LOCK_CONTEXT (context); |
||
4284 | g_main_context_remove_poll_unlocked (context, fd); |
||
4285 | UNLOCK_CONTEXT (context); |
||
4286 | } |
||
4287 | |||
4288 | static void |
||
4289 | g_main_context_remove_poll_unlocked (GMainContext *context, |
||
4290 | GPollFD *fd) |
||
4291 | { |
||
4292 | GPollRec *pollrec, *prevrec, *nextrec; |
||
4293 | |||
4294 | prevrec = NULL; |
||
4295 | pollrec = context->poll_records; |
||
4296 | |||
4297 | while (pollrec) |
||
4298 | { |
||
4299 | nextrec = pollrec->next; |
||
4300 | if (pollrec->fd == fd) |
||
4301 | { |
||
4302 | if (prevrec != NULL) |
||
4303 | prevrec->next = nextrec; |
||
4304 | else |
||
4305 | context->poll_records = nextrec; |
||
4306 | |||
4307 | if (nextrec != NULL) |
||
4308 | nextrec->prev = prevrec; |
||
4309 | |||
4310 | g_slice_free (GPollRec, pollrec); |
||
4311 | |||
4312 | context->n_poll_records--; |
||
4313 | break; |
||
4314 | } |
||
4315 | prevrec = pollrec; |
||
4316 | pollrec = nextrec; |
||
4317 | } |
||
4318 | |||
4319 | context->poll_changed = TRUE; |
||
4320 | |||
4321 | /* Now wake up the main loop if it is waiting in the poll() */ |
||
4322 | g_wakeup_signal (context->wakeup); |
||
4323 | } |
||
4324 | |||
4325 | /** |
||
4326 | * g_source_get_current_time: |
||
4327 | * @source: a #GSource |
||
4328 | * @timeval: #GTimeVal structure in which to store current time. |
||
4329 | * |
||
4330 | * This function ignores @source and is otherwise the same as |
||
4331 | * g_get_current_time(). |
||
4332 | * |
||
4333 | * Deprecated: 2.28: use g_source_get_time() instead |
||
4334 | **/ |
||
4335 | void |
||
4336 | g_source_get_current_time (GSource *source, |
||
4337 | GTimeVal *timeval) |
||
4338 | { |
||
4339 | g_get_current_time (timeval); |
||
4340 | } |
||
4341 | |||
4342 | /** |
||
4343 | * g_source_get_time: |
||
4344 | * @source: a #GSource |
||
4345 | * |
||
4346 | * Gets the time to be used when checking this source. The advantage of |
||
4347 | * calling this function over calling g_get_monotonic_time() directly is |
||
4348 | * that when checking multiple sources, GLib can cache a single value |
||
4349 | * instead of having to repeatedly get the system monotonic time. |
||
4350 | * |
||
4351 | * The time here is the system monotonic time, if available, or some |
||
4352 | * other reasonable alternative otherwise. See g_get_monotonic_time(). |
||
4353 | * |
||
4354 | * Returns: the monotonic time in microseconds |
||
4355 | * |
||
4356 | * Since: 2.28 |
||
4357 | **/ |
||
4358 | gint64 |
||
4359 | g_source_get_time (GSource *source) |
||
4360 | { |
||
4361 | GMainContext *context; |
||
4362 | gint64 result; |
||
4363 | |||
4364 | g_return_val_if_fail (source->context != NULL, 0); |
||
4365 | |||
4366 | context = source->context; |
||
4367 | |||
4368 | LOCK_CONTEXT (context); |
||
4369 | |||
4370 | if (!context->time_is_fresh) |
||
4371 | { |
||
4372 | context->time = g_get_monotonic_time (); |
||
4373 | context->time_is_fresh = TRUE; |
||
4374 | } |
||
4375 | |||
4376 | result = context->time; |
||
4377 | |||
4378 | UNLOCK_CONTEXT (context); |
||
4379 | |||
4380 | return result; |
||
4381 | } |
||
4382 | |||
4383 | /** |
||
4384 | * g_main_context_set_poll_func: |
||
4385 | * @context: a #GMainContext |
||
4386 | * @func: the function to call to poll all file descriptors |
||
4387 | * |
||
4388 | * Sets the function to use to handle polling of file descriptors. It |
||
4389 | * will be used instead of the poll() system call |
||
4390 | * (or GLib's replacement function, which is used where |
||
4391 | * poll() isn't available). |
||
4392 | * |
||
4393 | * This function could possibly be used to integrate the GLib event |
||
4394 | * loop with an external event loop. |
||
4395 | **/ |
||
4396 | void |
||
4397 | g_main_context_set_poll_func (GMainContext *context, |
||
4398 | GPollFunc func) |
||
4399 | { |
||
4400 | if (!context) |
||
4401 | context = g_main_context_default (); |
||
4402 | |||
4403 | g_return_if_fail (g_atomic_int_get (&context->ref_count) > 0); |
||
4404 | |||
4405 | LOCK_CONTEXT (context); |
||
4406 | |||
4407 | if (func) |
||
4408 | context->poll_func = func; |
||
4409 | else |
||
4410 | context->poll_func = g_poll; |
||
4411 | |||
4412 | UNLOCK_CONTEXT (context); |
||
4413 | } |
||
4414 | |||
4415 | /** |
||
4416 | * g_main_context_get_poll_func: |
||
4417 | * @context: a #GMainContext |
||
4418 | * |
||
4419 | * Gets the poll function set by g_main_context_set_poll_func(). |
||
4420 | * |
||
4421 | * Returns: the poll function |
||
4422 | **/ |
||
4423 | GPollFunc |
||
4424 | g_main_context_get_poll_func (GMainContext *context) |
||
4425 | { |
||
4426 | GPollFunc result; |
||
4427 | |||
4428 | if (!context) |
||
4429 | context = g_main_context_default (); |
||
4430 | |||
4431 | g_return_val_if_fail (g_atomic_int_get (&context->ref_count) > 0, NULL); |
||
4432 | |||
4433 | LOCK_CONTEXT (context); |
||
4434 | result = context->poll_func; |
||
4435 | UNLOCK_CONTEXT (context); |
||
4436 | |||
4437 | return result; |
||
4438 | } |
||
4439 | |||
4440 | /** |
||
4441 | * g_main_context_wakeup: |
||
4442 | * @context: a #GMainContext |
||
4443 | * |
||
4444 | * If @context is currently blocking in g_main_context_iteration() |
||
4445 | * waiting for a source to become ready, cause it to stop blocking |
||
4446 | * and return. Otherwise, cause the next invocation of |
||
4447 | * g_main_context_iteration() to return without blocking. |
||
4448 | * |
||
4449 | * This API is useful for low-level control over #GMainContext; for |
||
4450 | * example, integrating it with main loop implementations such as |
||
4451 | * #GMainLoop. |
||
4452 | * |
||
4453 | * Another related use for this function is when implementing a main |
||
4454 | * loop with a termination condition, computed from multiple threads: |
||
4455 | * |
||
4456 | * |[<!-- language="C" --> |
||
4457 | * #define NUM_TASKS 10 |
||
4458 | * static volatile gint tasks_remaining = NUM_TASKS; |
||
4459 | * ... |
||
4460 | * |
||
4461 | * while (g_atomic_int_get (&tasks_remaining) != 0) |
||
4462 | * g_main_context_iteration (NULL, TRUE); |
||
4463 | * ]| |
||
4464 | * |
||
4465 | * Then in a thread: |
||
4466 | * |[<!-- language="C" --> |
||
4467 | * perform_work(); |
||
4468 | * |
||
4469 | * if (g_atomic_int_dec_and_test (&tasks_remaining)) |
||
4470 | * g_main_context_wakeup (NULL); |
||
4471 | * ]| |
||
4472 | **/ |
||
4473 | void |
||
4474 | g_main_context_wakeup (GMainContext *context) |
||
4475 | { |
||
4476 | if (!context) |
||
4477 | context = g_main_context_default (); |
||
4478 | |||
4479 | g_return_if_fail (g_atomic_int_get (&context->ref_count) > 0); |
||
4480 | |||
4481 | g_wakeup_signal (context->wakeup); |
||
4482 | } |
||
4483 | |||
4484 | /** |
||
4485 | * g_main_context_is_owner: |
||
4486 | * @context: a #GMainContext |
||
4487 | * |
||
4488 | * Determines whether this thread holds the (recursive) |
||
4489 | * ownership of this #GMainContext. This is useful to |
||
4490 | * know before waiting on another thread that may be |
||
4491 | * blocking to get ownership of @context. |
||
4492 | * |
||
4493 | * Returns: %TRUE if current thread is owner of @context. |
||
4494 | * |
||
4495 | * Since: 2.10 |
||
4496 | **/ |
||
4497 | gboolean |
||
4498 | g_main_context_is_owner (GMainContext *context) |
||
4499 | { |
||
4500 | gboolean is_owner; |
||
4501 | |||
4502 | if (!context) |
||
4503 | context = g_main_context_default (); |
||
4504 | |||
4505 | LOCK_CONTEXT (context); |
||
4506 | is_owner = context->owner == G_THREAD_SELF; |
||
4507 | UNLOCK_CONTEXT (context); |
||
4508 | |||
4509 | return is_owner; |
||
4510 | } |
||
4511 | |||
4512 | /* Timeouts */ |
||
4513 | |||
4514 | static void |
||
4515 | g_timeout_set_expiration (GTimeoutSource *timeout_source, |
||
4516 | gint64 current_time) |
||
4517 | { |
||
4518 | gint64 expiration; |
||
4519 | |||
4520 | expiration = current_time + (guint64) timeout_source->interval * 1000; |
||
4521 | |||
4522 | if (timeout_source->seconds) |
||
4523 | { |
||
4524 | gint64 remainder; |
||
4525 | static gint timer_perturb = -1; |
||
4526 | |||
4527 | if (timer_perturb == -1) |
||
4528 | { |
||
4529 | /* |
||
4530 | * we want a per machine/session unique 'random' value; try the dbus |
||
4531 | * address first, that has a UUID in it. If there is no dbus, use the |
||
4532 | * hostname for hashing. |
||
4533 | */ |
||
4534 | const char *session_bus_address = g_getenv ("DBUS_SESSION_BUS_ADDRESS"); |
||
4535 | if (!session_bus_address) |
||
4536 | session_bus_address = g_getenv ("HOSTNAME"); |
||
4537 | if (session_bus_address) |
||
4538 | timer_perturb = ABS ((gint) g_str_hash (session_bus_address)) % 1000000; |
||
4539 | else |
||
4540 | timer_perturb = 0; |
||
4541 | } |
||
4542 | |||
4543 | /* We want the microseconds part of the timeout to land on the |
||
4544 | * 'timer_perturb' mark, but we need to make sure we don't try to |
||
4545 | * set the timeout in the past. We do this by ensuring that we |
||
4546 | * always only *increase* the expiration time by adding a full |
||
4547 | * second in the case that the microsecond portion decreases. |
||
4548 | */ |
||
4549 | expiration -= timer_perturb; |
||
4550 | |||
4551 | remainder = expiration % 1000000; |
||
4552 | if (remainder >= 1000000/4) |
||
4553 | expiration += 1000000; |
||
4554 | |||
4555 | expiration -= remainder; |
||
4556 | expiration += timer_perturb; |
||
4557 | } |
||
4558 | |||
4559 | g_source_set_ready_time ((GSource *) timeout_source, expiration); |
||
4560 | } |
||
4561 | |||
4562 | static gboolean |
||
4563 | g_timeout_dispatch (GSource *source, |
||
4564 | GSourceFunc callback, |
||
4565 | gpointer user_data) |
||
4566 | { |
||
4567 | GTimeoutSource *timeout_source = (GTimeoutSource *)source; |
||
4568 | gboolean again; |
||
4569 | |||
4570 | if (!callback) |
||
4571 | { |
||
4572 | g_warning ("Timeout source dispatched without callback\n" |
||
4573 | "You must call g_source_set_callback()."); |
||
4574 | return FALSE; |
||
4575 | } |
||
4576 | |||
4577 | again = callback (user_data); |
||
4578 | |||
4579 | if (again) |
||
4580 | g_timeout_set_expiration (timeout_source, g_source_get_time (source)); |
||
4581 | |||
4582 | return again; |
||
4583 | } |
||
4584 | |||
4585 | /** |
||
4586 | * g_timeout_source_new: |
||
4587 | * @interval: the timeout interval in milliseconds. |
||
4588 | * |
||
4589 | * Creates a new timeout source. |
||
4590 | * |
||
4591 | * The source will not initially be associated with any #GMainContext |
||
4592 | * and must be added to one with g_source_attach() before it will be |
||
4593 | * executed. |
||
4594 | * |
||
4595 | * The interval given is in terms of monotonic time, not wall clock |
||
4596 | * time. See g_get_monotonic_time(). |
||
4597 | * |
||
4598 | * Returns: the newly-created timeout source |
||
4599 | **/ |
||
4600 | GSource * |
||
4601 | g_timeout_source_new (guint interval) |
||
4602 | { |
||
4603 | GSource *source = g_source_new (&g_timeout_funcs, sizeof (GTimeoutSource)); |
||
4604 | GTimeoutSource *timeout_source = (GTimeoutSource *)source; |
||
4605 | |||
4606 | timeout_source->interval = interval; |
||
4607 | g_timeout_set_expiration (timeout_source, g_get_monotonic_time ()); |
||
4608 | |||
4609 | return source; |
||
4610 | } |
||
4611 | |||
4612 | /** |
||
4613 | * g_timeout_source_new_seconds: |
||
4614 | * @interval: the timeout interval in seconds |
||
4615 | * |
||
4616 | * Creates a new timeout source. |
||
4617 | * |
||
4618 | * The source will not initially be associated with any #GMainContext |
||
4619 | * and must be added to one with g_source_attach() before it will be |
||
4620 | * executed. |
||
4621 | * |
||
4622 | * The scheduling granularity/accuracy of this timeout source will be |
||
4623 | * in seconds. |
||
4624 | * |
||
4625 | * The interval given in terms of monotonic time, not wall clock time. |
||
4626 | * See g_get_monotonic_time(). |
||
4627 | * |
||
4628 | * Returns: the newly-created timeout source |
||
4629 | * |
||
4630 | * Since: 2.14 |
||
4631 | **/ |
||
4632 | GSource * |
||
4633 | g_timeout_source_new_seconds (guint interval) |
||
4634 | { |
||
4635 | GSource *source = g_source_new (&g_timeout_funcs, sizeof (GTimeoutSource)); |
||
4636 | GTimeoutSource *timeout_source = (GTimeoutSource *)source; |
||
4637 | |||
4638 | timeout_source->interval = 1000 * interval; |
||
4639 | timeout_source->seconds = TRUE; |
||
4640 | |||
4641 | g_timeout_set_expiration (timeout_source, g_get_monotonic_time ()); |
||
4642 | |||
4643 | return source; |
||
4644 | } |
||
4645 | |||
4646 | |||
4647 | /** |
||
4648 | * g_timeout_add_full: (rename-to g_timeout_add) |
||
4649 | * @priority: the priority of the timeout source. Typically this will be in |
||
4650 | * the range between #G_PRIORITY_DEFAULT and #G_PRIORITY_HIGH. |
||
4651 | * @interval: the time between calls to the function, in milliseconds |
||
4652 | * (1/1000ths of a second) |
||
4653 | * @function: function to call |
||
4654 | * @data: data to pass to @function |
||
4655 | * @notify: (allow-none): function to call when the timeout is removed, or %NULL |
||
4656 | * |
||
4657 | * Sets a function to be called at regular intervals, with the given |
||
4658 | * priority. The function is called repeatedly until it returns |
||
4659 | * %FALSE, at which point the timeout is automatically destroyed and |
||
4660 | * the function will not be called again. The @notify function is |
||
4661 | * called when the timeout is destroyed. The first call to the |
||
4662 | * function will be at the end of the first @interval. |
||
4663 | * |
||
4664 | * Note that timeout functions may be delayed, due to the processing of other |
||
4665 | * event sources. Thus they should not be relied on for precise timing. |
||
4666 | * After each call to the timeout function, the time of the next |
||
4667 | * timeout is recalculated based on the current time and the given interval |
||
4668 | * (it does not try to 'catch up' time lost in delays). |
||
4669 | * |
||
4670 | * See [memory management of sources][mainloop-memory-management] for details |
||
4671 | * on how to handle the return value and memory management of @data. |
||
4672 | * |
||
4673 | * This internally creates a main loop source using g_timeout_source_new() |
||
4674 | * and attaches it to the global #GMainContext using g_source_attach(), so |
||
4675 | * the callback will be invoked in whichever thread is running that main |
||
4676 | * context. You can do these steps manually if you need greater control or to |
||
4677 | * use a custom main context. |
||
4678 | * |
||
4679 | * The interval given in terms of monotonic time, not wall clock time. |
||
4680 | * See g_get_monotonic_time(). |
||
4681 | * |
||
4682 | * Returns: the ID (greater than 0) of the event source. |
||
4683 | **/ |
||
4684 | guint |
||
4685 | g_timeout_add_full (gint priority, |
||
4686 | guint interval, |
||
4687 | GSourceFunc function, |
||
4688 | gpointer data, |
||
4689 | GDestroyNotify notify) |
||
4690 | { |
||
4691 | GSource *source; |
||
4692 | guint id; |
||
4693 | |||
4694 | g_return_val_if_fail (function != NULL, 0); |
||
4695 | |||
4696 | source = g_timeout_source_new (interval); |
||
4697 | |||
4698 | if (priority != G_PRIORITY_DEFAULT) |
||
4699 | g_source_set_priority (source, priority); |
||
4700 | |||
4701 | g_source_set_callback (source, function, data, notify); |
||
4702 | id = g_source_attach (source, NULL); |
||
4703 | g_source_unref (source); |
||
4704 | |||
4705 | return id; |
||
4706 | } |
||
4707 | |||
4708 | /** |
||
4709 | * g_timeout_add: |
||
4710 | * @interval: the time between calls to the function, in milliseconds |
||
4711 | * (1/1000ths of a second) |
||
4712 | * @function: function to call |
||
4713 | * @data: data to pass to @function |
||
4714 | * |
||
4715 | * Sets a function to be called at regular intervals, with the default |
||
4716 | * priority, #G_PRIORITY_DEFAULT. The function is called repeatedly |
||
4717 | * until it returns %FALSE, at which point the timeout is automatically |
||
4718 | * destroyed and the function will not be called again. The first call |
||
4719 | * to the function will be at the end of the first @interval. |
||
4720 | * |
||
4721 | * Note that timeout functions may be delayed, due to the processing of other |
||
4722 | * event sources. Thus they should not be relied on for precise timing. |
||
4723 | * After each call to the timeout function, the time of the next |
||
4724 | * timeout is recalculated based on the current time and the given interval |
||
4725 | * (it does not try to 'catch up' time lost in delays). |
||
4726 | * |
||
4727 | * See [memory management of sources][mainloop-memory-management] for details |
||
4728 | * on how to handle the return value and memory management of @data. |
||
4729 | * |
||
4730 | * If you want to have a timer in the "seconds" range and do not care |
||
4731 | * about the exact time of the first call of the timer, use the |
||
4732 | * g_timeout_add_seconds() function; this function allows for more |
||
4733 | * optimizations and more efficient system power usage. |
||
4734 | * |
||
4735 | * This internally creates a main loop source using g_timeout_source_new() |
||
4736 | * and attaches it to the global #GMainContext using g_source_attach(), so |
||
4737 | * the callback will be invoked in whichever thread is running that main |
||
4738 | * context. You can do these steps manually if you need greater control or to |
||
4739 | * use a custom main context. |
||
4740 | * |
||
4741 | * The interval given is in terms of monotonic time, not wall clock |
||
4742 | * time. See g_get_monotonic_time(). |
||
4743 | * |
||
4744 | * Returns: the ID (greater than 0) of the event source. |
||
4745 | **/ |
||
4746 | guint |
||
4747 | g_timeout_add (guint32 interval, |
||
4748 | GSourceFunc function, |
||
4749 | gpointer data) |
||
4750 | { |
||
4751 | return g_timeout_add_full (G_PRIORITY_DEFAULT, |
||
4752 | interval, function, data, NULL); |
||
4753 | } |
||
4754 | |||
4755 | /** |
||
4756 | * g_timeout_add_seconds_full: (rename-to g_timeout_add_seconds) |
||
4757 | * @priority: the priority of the timeout source. Typically this will be in |
||
4758 | * the range between #G_PRIORITY_DEFAULT and #G_PRIORITY_HIGH. |
||
4759 | * @interval: the time between calls to the function, in seconds |
||
4760 | * @function: function to call |
||
4761 | * @data: data to pass to @function |
||
4762 | * @notify: (allow-none): function to call when the timeout is removed, or %NULL |
||
4763 | * |
||
4764 | * Sets a function to be called at regular intervals, with @priority. |
||
4765 | * The function is called repeatedly until it returns %FALSE, at which |
||
4766 | * point the timeout is automatically destroyed and the function will |
||
4767 | * not be called again. |
||
4768 | * |
||
4769 | * Unlike g_timeout_add(), this function operates at whole second granularity. |
||
4770 | * The initial starting point of the timer is determined by the implementation |
||
4771 | * and the implementation is expected to group multiple timers together so that |
||
4772 | * they fire all at the same time. |
||
4773 | * To allow this grouping, the @interval to the first timer is rounded |
||
4774 | * and can deviate up to one second from the specified interval. |
||
4775 | * Subsequent timer iterations will generally run at the specified interval. |
||
4776 | * |
||
4777 | * Note that timeout functions may be delayed, due to the processing of other |
||
4778 | * event sources. Thus they should not be relied on for precise timing. |
||
4779 | * After each call to the timeout function, the time of the next |
||
4780 | * timeout is recalculated based on the current time and the given @interval |
||
4781 | * |
||
4782 | * See [memory management of sources][mainloop-memory-management] for details |
||
4783 | * on how to handle the return value and memory management of @data. |
||
4784 | * |
||
4785 | * If you want timing more precise than whole seconds, use g_timeout_add() |
||
4786 | * instead. |
||
4787 | * |
||
4788 | * The grouping of timers to fire at the same time results in a more power |
||
4789 | * and CPU efficient behavior so if your timer is in multiples of seconds |
||
4790 | * and you don't require the first timer exactly one second from now, the |
||
4791 | * use of g_timeout_add_seconds() is preferred over g_timeout_add(). |
||
4792 | * |
||
4793 | * This internally creates a main loop source using |
||
4794 | * g_timeout_source_new_seconds() and attaches it to the main loop context |
||
4795 | * using g_source_attach(). You can do these steps manually if you need |
||
4796 | * greater control. |
||
4797 | * |
||
4798 | * The interval given is in terms of monotonic time, not wall clock |
||
4799 | * time. See g_get_monotonic_time(). |
||
4800 | * |
||
4801 | * Returns: the ID (greater than 0) of the event source. |
||
4802 | * |
||
4803 | * Since: 2.14 |
||
4804 | **/ |
||
4805 | guint |
||
4806 | g_timeout_add_seconds_full (gint priority, |
||
4807 | guint32 interval, |
||
4808 | GSourceFunc function, |
||
4809 | gpointer data, |
||
4810 | GDestroyNotify notify) |
||
4811 | { |
||
4812 | GSource *source; |
||
4813 | guint id; |
||
4814 | |||
4815 | g_return_val_if_fail (function != NULL, 0); |
||
4816 | |||
4817 | source = g_timeout_source_new_seconds (interval); |
||
4818 | |||
4819 | if (priority != G_PRIORITY_DEFAULT) |
||
4820 | g_source_set_priority (source, priority); |
||
4821 | |||
4822 | g_source_set_callback (source, function, data, notify); |
||
4823 | id = g_source_attach (source, NULL); |
||
4824 | g_source_unref (source); |
||
4825 | |||
4826 | return id; |
||
4827 | } |
||
4828 | |||
4829 | /** |
||
4830 | * g_timeout_add_seconds: |
||
4831 | * @interval: the time between calls to the function, in seconds |
||
4832 | * @function: function to call |
||
4833 | * @data: data to pass to @function |
||
4834 | * |
||
4835 | * Sets a function to be called at regular intervals with the default |
||
4836 | * priority, #G_PRIORITY_DEFAULT. The function is called repeatedly until |
||
4837 | * it returns %FALSE, at which point the timeout is automatically destroyed |
||
4838 | * and the function will not be called again. |
||
4839 | * |
||
4840 | * This internally creates a main loop source using |
||
4841 | * g_timeout_source_new_seconds() and attaches it to the main loop context |
||
4842 | * using g_source_attach(). You can do these steps manually if you need |
||
4843 | * greater control. Also see g_timeout_add_seconds_full(). |
||
4844 | * |
||
4845 | * Note that the first call of the timer may not be precise for timeouts |
||
4846 | * of one second. If you need finer precision and have such a timeout, |
||
4847 | * you may want to use g_timeout_add() instead. |
||
4848 | * |
||
4849 | * See [memory management of sources][mainloop-memory-management] for details |
||
4850 | * on how to handle the return value and memory management of @data. |
||
4851 | * |
||
4852 | * The interval given is in terms of monotonic time, not wall clock |
||
4853 | * time. See g_get_monotonic_time(). |
||
4854 | * |
||
4855 | * Returns: the ID (greater than 0) of the event source. |
||
4856 | * |
||
4857 | * Since: 2.14 |
||
4858 | **/ |
||
4859 | guint |
||
4860 | g_timeout_add_seconds (guint interval, |
||
4861 | GSourceFunc function, |
||
4862 | gpointer data) |
||
4863 | { |
||
4864 | g_return_val_if_fail (function != NULL, 0); |
||
4865 | |||
4866 | return g_timeout_add_seconds_full (G_PRIORITY_DEFAULT, interval, function, data, NULL); |
||
4867 | } |
||
4868 | |||
4869 | /* Child watch functions */ |
||
4870 | |||
4871 | #ifdef G_OS_WIN32 |
||
4872 | |||
4873 | static gboolean |
||
4874 | g_child_watch_prepare (GSource *source, |
||
4875 | gint *timeout) |
||
4876 | { |
||
4877 | *timeout = -1; |
||
4878 | return FALSE; |
||
4879 | } |
||
4880 | |||
4881 | static gboolean |
||
4882 | g_child_watch_check (GSource *source) |
||
4883 | { |
||
4884 | GChildWatchSource *child_watch_source; |
||
4885 | gboolean child_exited; |
||
4886 | |||
4887 | child_watch_source = (GChildWatchSource *) source; |
||
4888 | |||
4889 | child_exited = child_watch_source->poll.revents & G_IO_IN; |
||
4890 | |||
4891 | if (child_exited) |
||
4892 | { |
||
4893 | DWORD child_status; |
||
4894 | |||
4895 | /* |
||
4896 | * Note: We do _not_ check for the special value of STILL_ACTIVE |
||
4897 | * since we know that the process has exited and doing so runs into |
||
4898 | * problems if the child process "happens to return STILL_ACTIVE(259)" |
||
4899 | * as Microsoft's Platform SDK puts it. |
||
4900 | */ |
||
4901 | if (!GetExitCodeProcess (child_watch_source->pid, &child_status)) |
||
4902 | { |
||
4903 | gchar *emsg = g_win32_error_message (GetLastError ()); |
||
4904 | g_warning (G_STRLOC ": GetExitCodeProcess() failed: %s", emsg); |
||
4905 | g_free (emsg); |
||
4906 | |||
4907 | child_watch_source->child_status = -1; |
||
4908 | } |
||
4909 | else |
||
4910 | child_watch_source->child_status = child_status; |
||
4911 | } |
||
4912 | |||
4913 | return child_exited; |
||
4914 | } |
||
4915 | |||
4916 | static void |
||
4917 | g_child_watch_finalize (GSource *source) |
||
4918 | { |
||
4919 | } |
||
4920 | |||
4921 | #else /* G_OS_WIN32 */ |
||
4922 | |||
4923 | static void |
||
4924 | wake_source (GSource *source) |
||
4925 | { |
||
4926 | GMainContext *context; |
||
4927 | |||
4928 | /* This should be thread-safe: |
||
4929 | * |
||
4930 | * - if the source is currently being added to a context, that |
||
4931 | * context will be woken up anyway |
||
4932 | * |
||
4933 | * - if the source is currently being destroyed, we simply need not |
||
4934 | * to crash: |
||
4935 | * |
||
4936 | * - the memory for the source will remain valid until after the |
||
4937 | * source finalize function was called (which would remove the |
||
4938 | * source from the global list which we are currently holding the |
||
4939 | * lock for) |
||
4940 | * |
||
4941 | * - the GMainContext will either be NULL or point to a live |
||
4942 | * GMainContext |
||
4943 | * |
||
4944 | * - the GMainContext will remain valid since we hold the |
||
4945 | * main_context_list lock |
||
4946 | * |
||
4947 | * Since we are holding a lot of locks here, don't try to enter any |
||
4948 | * more GMainContext functions for fear of dealock -- just hit the |
||
4949 | * GWakeup and run. Even if that's safe now, it could easily become |
||
4950 | * unsafe with some very minor changes in the future, and signal |
||
4951 | * handling is not the most well-tested codepath. |
||
4952 | */ |
||
4953 | G_LOCK(main_context_list); |
||
4954 | context = source->context; |
||
4955 | if (context) |
||
4956 | g_wakeup_signal (context->wakeup); |
||
4957 | G_UNLOCK(main_context_list); |
||
4958 | } |
||
4959 | |||
4960 | static void |
||
4961 | dispatch_unix_signals_unlocked (void) |
||
4962 | { |
||
4963 | gboolean pending[NSIG]; |
||
4964 | GSList *node; |
||
4965 | gint i; |
||
4966 | |||
4967 | /* clear this first incase another one arrives while we're processing */ |
||
4968 | any_unix_signal_pending = FALSE; |
||
4969 | |||
4970 | /* We atomically test/clear the bit from the global array in case |
||
4971 | * other signals arrive while we are dispatching. |
||
4972 | * |
||
4973 | * We then can safely use our own array below without worrying about |
||
4974 | * races. |
||
4975 | */ |
||
4976 | for (i = 0; i < NSIG; i++) |
||
4977 | { |
||
4978 | /* Be very careful with (the volatile) unix_signal_pending. |
||
4979 | * |
||
4980 | * We must ensure that it's not possible that we clear it without |
||
4981 | * handling the signal. We therefore must ensure that our pending |
||
4982 | * array has a field set (ie: we will do something about the |
||
4983 | * signal) before we clear the item in unix_signal_pending. |
||
4984 | * |
||
4985 | * Note specifically: we must check _our_ array. |
||
4986 | */ |
||
4987 | pending[i] = unix_signal_pending[i]; |
||
4988 | if (pending[i]) |
||
4989 | unix_signal_pending[i] = FALSE; |
||
4990 | } |
||
4991 | |||
4992 | /* handle GChildWatchSource instances */ |
||
4993 | if (pending[SIGCHLD]) |
||
4994 | { |
||
4995 | /* The only way we can do this is to scan all of the children. |
||
4996 | * |
||
4997 | * The docs promise that we will not reap children that we are not |
||
4998 | * explicitly watching, so that ties our hands from calling |
||
4999 | * waitpid(-1). We also can't use siginfo's si_pid field since if |
||
5000 | * multiple SIGCHLD arrive at the same time, one of them can be |
||
5001 | * dropped (since a given UNIX signal can only be pending once). |
||
5002 | */ |
||
5003 | for (node = unix_child_watches; node; node = node->next) |
||
5004 | { |
||
5005 | GChildWatchSource *source = node->data; |
||
5006 | |||
5007 | if (!source->child_exited) |
||
5008 | { |
||
5009 | pid_t pid; |
||
5010 | do |
||
5011 | { |
||
5012 | g_assert (source->pid > 0); |
||
5013 | |||
5014 | pid = waitpid (source->pid, &source->child_status, WNOHANG); |
||
5015 | if (pid > 0) |
||
5016 | { |
||
5017 | source->child_exited = TRUE; |
||
5018 | wake_source ((GSource *) source); |
||
5019 | } |
||
5020 | else if (pid == -1 && errno == ECHILD) |
||
5021 | { |
||
5022 | g_warning ("GChildWatchSource: Exit status of a child process was requested but ECHILD was received by waitpid(). Most likely the process is ignoring SIGCHLD, or some other thread is invoking waitpid() with a nonpositive first argument; either behavior can break applications that use g_child_watch_add()/g_spawn_sync() either directly or indirectly."); |
||
5023 | source->child_exited = TRUE; |
||
5024 | source->child_status = 0; |
||
5025 | wake_source ((GSource *) source); |
||
5026 | } |
||
5027 | } |
||
5028 | while (pid == -1 && errno == EINTR); |
||
5029 | } |
||
5030 | } |
||
5031 | } |
||
5032 | |||
5033 | /* handle GUnixSignalWatchSource instances */ |
||
5034 | for (node = unix_signal_watches; node; node = node->next) |
||
5035 | { |
||
5036 | GUnixSignalWatchSource *source = node->data; |
||
5037 | |||
5038 | if (!source->pending) |
||
5039 | { |
||
5040 | if (pending[source->signum]) |
||
5041 | { |
||
5042 | source->pending = TRUE; |
||
5043 | |||
5044 | wake_source ((GSource *) source); |
||
5045 | } |
||
5046 | } |
||
5047 | } |
||
5048 | |||
5049 | } |
||
5050 | |||
5051 | static void |
||
5052 | dispatch_unix_signals (void) |
||
5053 | { |
||
5054 | G_LOCK(unix_signal_lock); |
||
5055 | dispatch_unix_signals_unlocked (); |
||
5056 | G_UNLOCK(unix_signal_lock); |
||
5057 | } |
||
5058 | |||
5059 | static gboolean |
||
5060 | g_child_watch_prepare (GSource *source, |
||
5061 | gint *timeout) |
||
5062 | { |
||
5063 | GChildWatchSource *child_watch_source; |
||
5064 | |||
5065 | child_watch_source = (GChildWatchSource *) source; |
||
5066 | |||
5067 | return child_watch_source->child_exited; |
||
5068 | } |
||
5069 | |||
5070 | static gboolean |
||
5071 | g_child_watch_check (GSource *source) |
||
5072 | { |
||
5073 | GChildWatchSource *child_watch_source; |
||
5074 | |||
5075 | child_watch_source = (GChildWatchSource *) source; |
||
5076 | |||
5077 | return child_watch_source->child_exited; |
||
5078 | } |
||
5079 | |||
5080 | static gboolean |
||
5081 | g_unix_signal_watch_prepare (GSource *source, |
||
5082 | gint *timeout) |
||
5083 | { |
||
5084 | GUnixSignalWatchSource *unix_signal_source; |
||
5085 | |||
5086 | unix_signal_source = (GUnixSignalWatchSource *) source; |
||
5087 | |||
5088 | return unix_signal_source->pending; |
||
5089 | } |
||
5090 | |||
5091 | static gboolean |
||
5092 | g_unix_signal_watch_check (GSource *source) |
||
5093 | { |
||
5094 | GUnixSignalWatchSource *unix_signal_source; |
||
5095 | |||
5096 | unix_signal_source = (GUnixSignalWatchSource *) source; |
||
5097 | |||
5098 | return unix_signal_source->pending; |
||
5099 | } |
||
5100 | |||
5101 | static gboolean |
||
5102 | g_unix_signal_watch_dispatch (GSource *source, |
||
5103 | GSourceFunc callback, |
||
5104 | gpointer user_data) |
||
5105 | { |
||
5106 | GUnixSignalWatchSource *unix_signal_source; |
||
5107 | gboolean again; |
||
5108 | |||
5109 | unix_signal_source = (GUnixSignalWatchSource *) source; |
||
5110 | |||
5111 | if (!callback) |
||
5112 | { |
||
5113 | g_warning ("Unix signal source dispatched without callback\n" |
||
5114 | "You must call g_source_set_callback()."); |
||
5115 | return FALSE; |
||
5116 | } |
||
5117 | |||
5118 | again = (callback) (user_data); |
||
5119 | |||
5120 | unix_signal_source->pending = FALSE; |
||
5121 | |||
5122 | return again; |
||
5123 | } |
||
5124 | |||
5125 | static void |
||
5126 | ref_unix_signal_handler_unlocked (int signum) |
||
5127 | { |
||
5128 | /* Ensure we have the worker context */ |
||
5129 | g_get_worker_context (); |
||
5130 | unix_signal_refcount[signum]++; |
||
5131 | if (unix_signal_refcount[signum] == 1) |
||
5132 | { |
||
5133 | struct sigaction action; |
||
5134 | action.sa_handler = g_unix_signal_handler; |
||
5135 | sigemptyset (&action.sa_mask); |
||
5136 | #ifdef SA_RESTART |
||
5137 | action.sa_flags = SA_RESTART | SA_NOCLDSTOP; |
||
5138 | #else |
||
5139 | action.sa_flags = SA_NOCLDSTOP; |
||
5140 | #endif |
||
5141 | sigaction (signum, &action, NULL); |
||
5142 | } |
||
5143 | } |
||
5144 | |||
5145 | static void |
||
5146 | unref_unix_signal_handler_unlocked (int signum) |
||
5147 | { |
||
5148 | unix_signal_refcount[signum]--; |
||
5149 | if (unix_signal_refcount[signum] == 0) |
||
5150 | { |
||
5151 | struct sigaction action; |
||
5152 | memset (&action, 0, sizeof (action)); |
||
5153 | action.sa_handler = SIG_DFL; |
||
5154 | sigemptyset (&action.sa_mask); |
||
5155 | sigaction (signum, &action, NULL); |
||
5156 | } |
||
5157 | } |
||
5158 | |||
5159 | GSource * |
||
5160 | _g_main_create_unix_signal_watch (int signum) |
||
5161 | { |
||
5162 | GSource *source; |
||
5163 | GUnixSignalWatchSource *unix_signal_source; |
||
5164 | |||
5165 | source = g_source_new (&g_unix_signal_funcs, sizeof (GUnixSignalWatchSource)); |
||
5166 | unix_signal_source = (GUnixSignalWatchSource *) source; |
||
5167 | |||
5168 | unix_signal_source->signum = signum; |
||
5169 | unix_signal_source->pending = FALSE; |
||
5170 | |||
5171 | G_LOCK (unix_signal_lock); |
||
5172 | ref_unix_signal_handler_unlocked (signum); |
||
5173 | unix_signal_watches = g_slist_prepend (unix_signal_watches, unix_signal_source); |
||
5174 | dispatch_unix_signals_unlocked (); |
||
5175 | G_UNLOCK (unix_signal_lock); |
||
5176 | |||
5177 | return source; |
||
5178 | } |
||
5179 | |||
5180 | static void |
||
5181 | g_unix_signal_watch_finalize (GSource *source) |
||
5182 | { |
||
5183 | GUnixSignalWatchSource *unix_signal_source; |
||
5184 | |||
5185 | unix_signal_source = (GUnixSignalWatchSource *) source; |
||
5186 | |||
5187 | G_LOCK (unix_signal_lock); |
||
5188 | unref_unix_signal_handler_unlocked (unix_signal_source->signum); |
||
5189 | unix_signal_watches = g_slist_remove (unix_signal_watches, source); |
||
5190 | G_UNLOCK (unix_signal_lock); |
||
5191 | } |
||
5192 | |||
5193 | static void |
||
5194 | g_child_watch_finalize (GSource *source) |
||
5195 | { |
||
5196 | G_LOCK (unix_signal_lock); |
||
5197 | unix_child_watches = g_slist_remove (unix_child_watches, source); |
||
5198 | unref_unix_signal_handler_unlocked (SIGCHLD); |
||
5199 | G_UNLOCK (unix_signal_lock); |
||
5200 | } |
||
5201 | |||
5202 | #endif /* G_OS_WIN32 */ |
||
5203 | |||
5204 | static gboolean |
||
5205 | g_child_watch_dispatch (GSource *source, |
||
5206 | GSourceFunc callback, |
||
5207 | gpointer user_data) |
||
5208 | { |
||
5209 | GChildWatchSource *child_watch_source; |
||
5210 | GChildWatchFunc child_watch_callback = (GChildWatchFunc) callback; |
||
5211 | |||
5212 | child_watch_source = (GChildWatchSource *) source; |
||
5213 | |||
5214 | if (!callback) |
||
5215 | { |
||
5216 | g_warning ("Child watch source dispatched without callback\n" |
||
5217 | "You must call g_source_set_callback()."); |
||
5218 | return FALSE; |
||
5219 | } |
||
5220 | |||
5221 | (child_watch_callback) (child_watch_source->pid, child_watch_source->child_status, user_data); |
||
5222 | |||
5223 | /* We never keep a child watch source around as the child is gone */ |
||
5224 | return FALSE; |
||
5225 | } |
||
5226 | |||
5227 | #ifndef G_OS_WIN32 |
||
5228 | |||
5229 | static void |
||
5230 | g_unix_signal_handler (int signum) |
||
5231 | { |
||
5232 | gint saved_errno = errno; |
||
5233 | |||
5234 | unix_signal_pending[signum] = TRUE; |
||
5235 | any_unix_signal_pending = TRUE; |
||
5236 | |||
5237 | g_wakeup_signal (glib_worker_context->wakeup); |
||
5238 | |||
5239 | errno = saved_errno; |
||
5240 | } |
||
5241 | |||
5242 | #endif /* !G_OS_WIN32 */ |
||
5243 | |||
5244 | /** |
||
5245 | * g_child_watch_source_new: |
||
5246 | * @pid: process to watch. On POSIX the positive pid of a child process. On |
||
5247 | * Windows a handle for a process (which doesn't have to be a child). |
||
5248 | * |
||
5249 | * Creates a new child_watch source. |
||
5250 | * |
||
5251 | * The source will not initially be associated with any #GMainContext |
||
5252 | * and must be added to one with g_source_attach() before it will be |
||
5253 | * executed. |
||
5254 | * |
||
5255 | * Note that child watch sources can only be used in conjunction with |
||
5256 | * `g_spawn...` when the %G_SPAWN_DO_NOT_REAP_CHILD flag is used. |
||
5257 | * |
||
5258 | * Note that on platforms where #GPid must be explicitly closed |
||
5259 | * (see g_spawn_close_pid()) @pid must not be closed while the |
||
5260 | * source is still active. Typically, you will want to call |
||
5261 | * g_spawn_close_pid() in the callback function for the source. |
||
5262 | * |
||
5263 | * Note further that using g_child_watch_source_new() is not |
||
5264 | * compatible with calling `waitpid` with a nonpositive first |
||
5265 | * argument in the application. Calling waitpid() for individual |
||
5266 | * pids will still work fine. |
||
5267 | * |
||
5268 | * Similarly, on POSIX platforms, the @pid passed to this function must |
||
5269 | * be greater than 0 (i.e. this function must wait for a specific child, |
||
5270 | * and cannot wait for one of many children by using a nonpositive argument). |
||
5271 | * |
||
5272 | * Returns: the newly-created child watch source |
||
5273 | * |
||
5274 | * Since: 2.4 |
||
5275 | **/ |
||
5276 | GSource * |
||
5277 | g_child_watch_source_new (GPid pid) |
||
5278 | { |
||
5279 | GSource *source; |
||
5280 | GChildWatchSource *child_watch_source; |
||
5281 | |||
5282 | #ifndef G_OS_WIN32 |
||
5283 | g_return_val_if_fail (pid > 0, NULL); |
||
5284 | #endif |
||
5285 | |||
5286 | source = g_source_new (&g_child_watch_funcs, sizeof (GChildWatchSource)); |
||
5287 | child_watch_source = (GChildWatchSource *)source; |
||
5288 | |||
5289 | child_watch_source->pid = pid; |
||
5290 | |||
5291 | #ifdef G_OS_WIN32 |
||
5292 | child_watch_source->poll.fd = (gintptr) pid; |
||
5293 | child_watch_source->poll.events = G_IO_IN; |
||
5294 | |||
5295 | g_source_add_poll (source, &child_watch_source->poll); |
||
5296 | #else /* G_OS_WIN32 */ |
||
5297 | G_LOCK (unix_signal_lock); |
||
5298 | ref_unix_signal_handler_unlocked (SIGCHLD); |
||
5299 | unix_child_watches = g_slist_prepend (unix_child_watches, child_watch_source); |
||
5300 | if (waitpid (pid, &child_watch_source->child_status, WNOHANG) > 0) |
||
5301 | child_watch_source->child_exited = TRUE; |
||
5302 | G_UNLOCK (unix_signal_lock); |
||
5303 | #endif /* G_OS_WIN32 */ |
||
5304 | |||
5305 | return source; |
||
5306 | } |
||
5307 | |||
5308 | /** |
||
5309 | * g_child_watch_add_full: (rename-to g_child_watch_add) |
||
5310 | * @priority: the priority of the idle source. Typically this will be in the |
||
5311 | * range between #G_PRIORITY_DEFAULT_IDLE and #G_PRIORITY_HIGH_IDLE. |
||
5312 | * @pid: process to watch. On POSIX the positive pid of a child process. On |
||
5313 | * Windows a handle for a process (which doesn't have to be a child). |
||
5314 | * @function: function to call |
||
5315 | * @data: data to pass to @function |
||
5316 | * @notify: (allow-none): function to call when the idle is removed, or %NULL |
||
5317 | * |
||
5318 | * Sets a function to be called when the child indicated by @pid |
||
5319 | * exits, at the priority @priority. |
||
5320 | * |
||
5321 | * If you obtain @pid from g_spawn_async() or g_spawn_async_with_pipes() |
||
5322 | * you will need to pass #G_SPAWN_DO_NOT_REAP_CHILD as flag to |
||
5323 | * the spawn function for the child watching to work. |
||
5324 | * |
||
5325 | * In many programs, you will want to call g_spawn_check_exit_status() |
||
5326 | * in the callback to determine whether or not the child exited |
||
5327 | * successfully. |
||
5328 | * |
||
5329 | * Also, note that on platforms where #GPid must be explicitly closed |
||
5330 | * (see g_spawn_close_pid()) @pid must not be closed while the source |
||
5331 | * is still active. Typically, you should invoke g_spawn_close_pid() |
||
5332 | * in the callback function for the source. |
||
5333 | * |
||
5334 | * GLib supports only a single callback per process id. |
||
5335 | * |
||
5336 | * This internally creates a main loop source using |
||
5337 | * g_child_watch_source_new() and attaches it to the main loop context |
||
5338 | * using g_source_attach(). You can do these steps manually if you |
||
5339 | * need greater control. |
||
5340 | * |
||
5341 | * Returns: the ID (greater than 0) of the event source. |
||
5342 | * |
||
5343 | * Since: 2.4 |
||
5344 | **/ |
||
5345 | guint |
||
5346 | g_child_watch_add_full (gint priority, |
||
5347 | GPid pid, |
||
5348 | GChildWatchFunc function, |
||
5349 | gpointer data, |
||
5350 | GDestroyNotify notify) |
||
5351 | { |
||
5352 | GSource *source; |
||
5353 | guint id; |
||
5354 | |||
5355 | g_return_val_if_fail (function != NULL, 0); |
||
5356 | #ifndef G_OS_WIN32 |
||
5357 | g_return_val_if_fail (pid > 0, 0); |
||
5358 | #endif |
||
5359 | |||
5360 | source = g_child_watch_source_new (pid); |
||
5361 | |||
5362 | if (priority != G_PRIORITY_DEFAULT) |
||
5363 | g_source_set_priority (source, priority); |
||
5364 | |||
5365 | g_source_set_callback (source, (GSourceFunc) function, data, notify); |
||
5366 | id = g_source_attach (source, NULL); |
||
5367 | g_source_unref (source); |
||
5368 | |||
5369 | return id; |
||
5370 | } |
||
5371 | |||
5372 | /** |
||
5373 | * g_child_watch_add: |
||
5374 | * @pid: process id to watch. On POSIX the positive pid of a child |
||
5375 | * process. On Windows a handle for a process (which doesn't have to be |
||
5376 | * a child). |
||
5377 | * @function: function to call |
||
5378 | * @data: data to pass to @function |
||
5379 | * |
||
5380 | * Sets a function to be called when the child indicated by @pid |
||
5381 | * exits, at a default priority, #G_PRIORITY_DEFAULT. |
||
5382 | * |
||
5383 | * If you obtain @pid from g_spawn_async() or g_spawn_async_with_pipes() |
||
5384 | * you will need to pass #G_SPAWN_DO_NOT_REAP_CHILD as flag to |
||
5385 | * the spawn function for the child watching to work. |
||
5386 | * |
||
5387 | * Note that on platforms where #GPid must be explicitly closed |
||
5388 | * (see g_spawn_close_pid()) @pid must not be closed while the |
||
5389 | * source is still active. Typically, you will want to call |
||
5390 | * g_spawn_close_pid() in the callback function for the source. |
||
5391 | * |
||
5392 | * GLib supports only a single callback per process id. |
||
5393 | * |
||
5394 | * This internally creates a main loop source using |
||
5395 | * g_child_watch_source_new() and attaches it to the main loop context |
||
5396 | * using g_source_attach(). You can do these steps manually if you |
||
5397 | * need greater control. |
||
5398 | * |
||
5399 | * Returns: the ID (greater than 0) of the event source. |
||
5400 | * |
||
5401 | * Since: 2.4 |
||
5402 | **/ |
||
5403 | guint |
||
5404 | g_child_watch_add (GPid pid, |
||
5405 | GChildWatchFunc function, |
||
5406 | gpointer data) |
||
5407 | { |
||
5408 | return g_child_watch_add_full (G_PRIORITY_DEFAULT, pid, function, data, NULL); |
||
5409 | } |
||
5410 | |||
5411 | |||
5412 | /* Idle functions */ |
||
5413 | |||
5414 | static gboolean |
||
5415 | g_idle_prepare (GSource *source, |
||
5416 | gint *timeout) |
||
5417 | { |
||
5418 | *timeout = 0; |
||
5419 | |||
5420 | return TRUE; |
||
5421 | } |
||
5422 | |||
5423 | static gboolean |
||
5424 | g_idle_check (GSource *source) |
||
5425 | { |
||
5426 | return TRUE; |
||
5427 | } |
||
5428 | |||
5429 | static gboolean |
||
5430 | g_idle_dispatch (GSource *source, |
||
5431 | GSourceFunc callback, |
||
5432 | gpointer user_data) |
||
5433 | { |
||
5434 | if (!callback) |
||
5435 | { |
||
5436 | g_warning ("Idle source dispatched without callback\n" |
||
5437 | "You must call g_source_set_callback()."); |
||
5438 | return FALSE; |
||
5439 | } |
||
5440 | |||
5441 | return callback (user_data); |
||
5442 | } |
||
5443 | |||
5444 | /** |
||
5445 | * g_idle_source_new: |
||
5446 | * |
||
5447 | * Creates a new idle source. |
||
5448 | * |
||
5449 | * The source will not initially be associated with any #GMainContext |
||
5450 | * and must be added to one with g_source_attach() before it will be |
||
5451 | * executed. Note that the default priority for idle sources is |
||
5452 | * %G_PRIORITY_DEFAULT_IDLE, as compared to other sources which |
||
5453 | * have a default priority of %G_PRIORITY_DEFAULT. |
||
5454 | * |
||
5455 | * Returns: the newly-created idle source |
||
5456 | **/ |
||
5457 | GSource * |
||
5458 | g_idle_source_new (void) |
||
5459 | { |
||
5460 | GSource *source; |
||
5461 | |||
5462 | source = g_source_new (&g_idle_funcs, sizeof (GSource)); |
||
5463 | g_source_set_priority (source, G_PRIORITY_DEFAULT_IDLE); |
||
5464 | |||
5465 | return source; |
||
5466 | } |
||
5467 | |||
5468 | /** |
||
5469 | * g_idle_add_full: (rename-to g_idle_add) |
||
5470 | * @priority: the priority of the idle source. Typically this will be in the |
||
5471 | * range between #G_PRIORITY_DEFAULT_IDLE and #G_PRIORITY_HIGH_IDLE. |
||
5472 | * @function: function to call |
||
5473 | * @data: data to pass to @function |
||
5474 | * @notify: (allow-none): function to call when the idle is removed, or %NULL |
||
5475 | * |
||
5476 | * Adds a function to be called whenever there are no higher priority |
||
5477 | * events pending. If the function returns %FALSE it is automatically |
||
5478 | * removed from the list of event sources and will not be called again. |
||
5479 | * |
||
5480 | * See [memory management of sources][mainloop-memory-management] for details |
||
5481 | * on how to handle the return value and memory management of @data. |
||
5482 | * |
||
5483 | * This internally creates a main loop source using g_idle_source_new() |
||
5484 | * and attaches it to the global #GMainContext using g_source_attach(), so |
||
5485 | * the callback will be invoked in whichever thread is running that main |
||
5486 | * context. You can do these steps manually if you need greater control or to |
||
5487 | * use a custom main context. |
||
5488 | * |
||
5489 | * Returns: the ID (greater than 0) of the event source. |
||
5490 | **/ |
||
5491 | guint |
||
5492 | g_idle_add_full (gint priority, |
||
5493 | GSourceFunc function, |
||
5494 | gpointer data, |
||
5495 | GDestroyNotify notify) |
||
5496 | { |
||
5497 | GSource *source; |
||
5498 | guint id; |
||
5499 | |||
5500 | g_return_val_if_fail (function != NULL, 0); |
||
5501 | |||
5502 | source = g_idle_source_new (); |
||
5503 | |||
5504 | if (priority != G_PRIORITY_DEFAULT_IDLE) |
||
5505 | g_source_set_priority (source, priority); |
||
5506 | |||
5507 | g_source_set_callback (source, function, data, notify); |
||
5508 | id = g_source_attach (source, NULL); |
||
5509 | g_source_unref (source); |
||
5510 | |||
5511 | return id; |
||
5512 | } |
||
5513 | |||
5514 | /** |
||
5515 | * g_idle_add: |
||
5516 | * @function: function to call |
||
5517 | * @data: data to pass to @function. |
||
5518 | * |
||
5519 | * Adds a function to be called whenever there are no higher priority |
||
5520 | * events pending to the default main loop. The function is given the |
||
5521 | * default idle priority, #G_PRIORITY_DEFAULT_IDLE. If the function |
||
5522 | * returns %FALSE it is automatically removed from the list of event |
||
5523 | * sources and will not be called again. |
||
5524 | * |
||
5525 | * See [memory management of sources][mainloop-memory-management] for details |
||
5526 | * on how to handle the return value and memory management of @data. |
||
5527 | * |
||
5528 | * This internally creates a main loop source using g_idle_source_new() |
||
5529 | * and attaches it to the global #GMainContext using g_source_attach(), so |
||
5530 | * the callback will be invoked in whichever thread is running that main |
||
5531 | * context. You can do these steps manually if you need greater control or to |
||
5532 | * use a custom main context. |
||
5533 | * |
||
5534 | * Returns: the ID (greater than 0) of the event source. |
||
5535 | **/ |
||
5536 | guint |
||
5537 | g_idle_add (GSourceFunc function, |
||
5538 | gpointer data) |
||
5539 | { |
||
5540 | return g_idle_add_full (G_PRIORITY_DEFAULT_IDLE, function, data, NULL); |
||
5541 | } |
||
5542 | |||
5543 | /** |
||
5544 | * g_idle_remove_by_data: |
||
5545 | * @data: the data for the idle source's callback. |
||
5546 | * |
||
5547 | * Removes the idle function with the given data. |
||
5548 | * |
||
5549 | * Returns: %TRUE if an idle source was found and removed. |
||
5550 | **/ |
||
5551 | gboolean |
||
5552 | g_idle_remove_by_data (gpointer data) |
||
5553 | { |
||
5554 | return g_source_remove_by_funcs_user_data (&g_idle_funcs, data); |
||
5555 | } |
||
5556 | |||
5557 | /** |
||
5558 | * g_main_context_invoke: |
||
5559 | * @context: (allow-none): a #GMainContext, or %NULL |
||
5560 | * @function: function to call |
||
5561 | * @data: data to pass to @function |
||
5562 | * |
||
5563 | * Invokes a function in such a way that @context is owned during the |
||
5564 | * invocation of @function. |
||
5565 | * |
||
5566 | * If @context is %NULL then the global default main context — as |
||
5567 | * returned by g_main_context_default() — is used. |
||
5568 | * |
||
5569 | * If @context is owned by the current thread, @function is called |
||
5570 | * directly. Otherwise, if @context is the thread-default main context |
||
5571 | * of the current thread and g_main_context_acquire() succeeds, then |
||
5572 | * @function is called and g_main_context_release() is called |
||
5573 | * afterwards. |
||
5574 | * |
||
5575 | * In any other case, an idle source is created to call @function and |
||
5576 | * that source is attached to @context (presumably to be run in another |
||
5577 | * thread). The idle source is attached with #G_PRIORITY_DEFAULT |
||
5578 | * priority. If you want a different priority, use |
||
5579 | * g_main_context_invoke_full(). |
||
5580 | * |
||
5581 | * Note that, as with normal idle functions, @function should probably |
||
5582 | * return %FALSE. If it returns %TRUE, it will be continuously run in a |
||
5583 | * loop (and may prevent this call from returning). |
||
5584 | * |
||
5585 | * Since: 2.28 |
||
5586 | **/ |
||
5587 | void |
||
5588 | g_main_context_invoke (GMainContext *context, |
||
5589 | GSourceFunc function, |
||
5590 | gpointer data) |
||
5591 | { |
||
5592 | g_main_context_invoke_full (context, |
||
5593 | G_PRIORITY_DEFAULT, |
||
5594 | function, data, NULL); |
||
5595 | } |
||
5596 | |||
5597 | /** |
||
5598 | * g_main_context_invoke_full: |
||
5599 | * @context: (allow-none): a #GMainContext, or %NULL |
||
5600 | * @priority: the priority at which to run @function |
||
5601 | * @function: function to call |
||
5602 | * @data: data to pass to @function |
||
5603 | * @notify: (allow-none): a function to call when @data is no longer in use, or %NULL. |
||
5604 | * |
||
5605 | * Invokes a function in such a way that @context is owned during the |
||
5606 | * invocation of @function. |
||
5607 | * |
||
5608 | * This function is the same as g_main_context_invoke() except that it |
||
5609 | * lets you specify the priority incase @function ends up being |
||
5610 | * scheduled as an idle and also lets you give a #GDestroyNotify for @data. |
||
5611 | * |
||
5612 | * @notify should not assume that it is called from any particular |
||
5613 | * thread or with any particular context acquired. |
||
5614 | * |
||
5615 | * Since: 2.28 |
||
5616 | **/ |
||
5617 | void |
||
5618 | g_main_context_invoke_full (GMainContext *context, |
||
5619 | gint priority, |
||
5620 | GSourceFunc function, |
||
5621 | gpointer data, |
||
5622 | GDestroyNotify notify) |
||
5623 | { |
||
5624 | g_return_if_fail (function != NULL); |
||
5625 | |||
5626 | if (!context) |
||
5627 | context = g_main_context_default (); |
||
5628 | |||
5629 | if (g_main_context_is_owner (context)) |
||
5630 | { |
||
5631 | while (function (data)); |
||
5632 | if (notify != NULL) |
||
5633 | notify (data); |
||
5634 | } |
||
5635 | |||
5636 | else |
||
5637 | { |
||
5638 | GMainContext *thread_default; |
||
5639 | |||
5640 | thread_default = g_main_context_get_thread_default (); |
||
5641 | |||
5642 | if (!thread_default) |
||
5643 | thread_default = g_main_context_default (); |
||
5644 | |||
5645 | if (thread_default == context && g_main_context_acquire (context)) |
||
5646 | { |
||
5647 | while (function (data)); |
||
5648 | |||
5649 | g_main_context_release (context); |
||
5650 | |||
5651 | if (notify != NULL) |
||
5652 | notify (data); |
||
5653 | } |
||
5654 | else |
||
5655 | { |
||
5656 | GSource *source; |
||
5657 | |||
5658 | source = g_idle_source_new (); |
||
5659 | g_source_set_priority (source, priority); |
||
5660 | g_source_set_callback (source, function, data, notify); |
||
5661 | g_source_attach (source, context); |
||
5662 | g_source_unref (source); |
||
5663 | } |
||
5664 | } |
||
5665 | } |
||
5666 | |||
5667 | static gpointer |
||
5668 | glib_worker_main (gpointer data) |
||
5669 | { |
||
5670 | while (TRUE) |
||
5671 | { |
||
5672 | g_main_context_iteration (glib_worker_context, TRUE); |
||
5673 | |||
5674 | #ifdef G_OS_UNIX |
||
5675 | if (any_unix_signal_pending) |
||
5676 | dispatch_unix_signals (); |
||
5677 | #endif |
||
5678 | } |
||
5679 | |||
5680 | return NULL; /* worst GCC warning message ever... */ |
||
5681 | } |
||
5682 | |||
5683 | GMainContext * |
||
5684 | g_get_worker_context (void) |
||
5685 | { |
||
5686 | static gsize initialised; |
||
5687 | |||
5688 | if (g_once_init_enter (&initialised)) |
||
5689 | { |
||
5690 | /* mask all signals in the worker thread */ |
||
5691 | #ifdef G_OS_UNIX |
||
5692 | sigset_t prev_mask; |
||
5693 | sigset_t all; |
||
5694 | |||
5695 | sigfillset (&all); |
||
5696 | pthread_sigmask (SIG_SETMASK, &all, &prev_mask); |
||
5697 | #endif |
||
5698 | glib_worker_context = g_main_context_new (); |
||
5699 | g_thread_new ("gmain", glib_worker_main, NULL); |
||
5700 | #ifdef G_OS_UNIX |
||
5701 | pthread_sigmask (SIG_SETMASK, &prev_mask, NULL); |
||
5702 | #endif |
||
5703 | g_once_init_leave (&initialised, TRUE); |
||
5704 | } |
||
5705 | |||
5706 | return glib_worker_context; |
||
5707 | } |