• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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, write to the
19  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20  * Boston, MA 02111-1307, USA.
21  */
22 
23 /*
24  * Modified by the GLib Team and others 1997-2000.  See the AUTHORS
25  * file for a list of people on the GLib Team.  See the ChangeLog
26  * files for a list of changes.  These files are distributed with
27  * GLib at ftp://ftp.gtk.org/pub/gtk/.
28  */
29 
30 /*
31  * MT safe
32  */
33 
34 #include "config.h"
35 
36 /* Uncomment the next line (and the corresponding line in gpoll.c) to
37  * enable debugging printouts if the environment variable
38  * G_MAIN_POLL_DEBUG is set to some value.
39  */
40 /* #define G_MAIN_POLL_DEBUG */
41 
42 #ifdef _WIN32
43 /* Always enable debugging printout on Windows, as it is more often
44  * needed there...
45  */
46 #define G_MAIN_POLL_DEBUG
47 #endif
48 
49 #include "glib.h"
50 #include "gthreadprivate.h"
51 #include <signal.h>
52 #include <sys/types.h>
53 #include <time.h>
54 #include <stdlib.h>
55 #ifdef HAVE_SYS_TIME_H
56 #include <sys/time.h>
57 #endif /* HAVE_SYS_TIME_H */
58 #ifdef HAVE_UNISTD_H
59 #include <unistd.h>
60 #endif /* HAVE_UNISTD_H */
61 #include <errno.h>
62 
63 #ifdef G_OS_WIN32
64 #define STRICT
65 #include <windows.h>
66 #endif /* G_OS_WIN32 */
67 
68 #ifdef G_OS_BEOS
69 #include <sys/socket.h>
70 #include <sys/wait.h>
71 #endif /* G_OS_BEOS */
72 
73 #ifdef G_OS_UNIX
74 #include <fcntl.h>
75 #include <sys/wait.h>
76 #endif
77 
78 #include "galias.h"
79 
80 /* Types */
81 
82 typedef struct _GTimeoutSource GTimeoutSource;
83 typedef struct _GChildWatchSource GChildWatchSource;
84 typedef struct _GPollRec GPollRec;
85 typedef struct _GSourceCallback GSourceCallback;
86 
87 typedef enum
88 {
89   G_SOURCE_READY = 1 << G_HOOK_FLAG_USER_SHIFT,
90   G_SOURCE_CAN_RECURSE = 1 << (G_HOOK_FLAG_USER_SHIFT + 1)
91 } GSourceFlags;
92 
93 #ifdef G_THREADS_ENABLED
94 typedef struct _GMainWaiter GMainWaiter;
95 
96 struct _GMainWaiter
97 {
98   GCond *cond;
99   GMutex *mutex;
100 };
101 #endif
102 
103 typedef struct _GMainDispatch GMainDispatch;
104 
105 struct _GMainDispatch
106 {
107   gint depth;
108   GSList *dispatching_sources; /* stack of current sources */
109 };
110 
111 #ifdef G_MAIN_POLL_DEBUG
112 gboolean _g_main_poll_debug = FALSE;
113 #endif
114 
115 struct _GMainContext
116 {
117 #ifdef G_THREADS_ENABLED
118   /* The following lock is used for both the list of sources
119    * and the list of poll records
120    */
121   GStaticMutex mutex;
122   GCond *cond;
123   GThread *owner;
124   guint owner_count;
125   GSList *waiters;
126 #endif
127 
128   gint ref_count;
129 
130   GPtrArray *pending_dispatches;
131   gint timeout;			/* Timeout for current iteration */
132 
133   guint next_id;
134   GSource *source_list;
135   gint in_check_or_prepare;
136 
137   GPollRec *poll_records;
138   guint n_poll_records;
139   GPollFD *cached_poll_array;
140   guint cached_poll_array_size;
141 
142 #ifdef G_THREADS_ENABLED
143 #ifndef G_OS_WIN32
144 /* this pipe is used to wake up the main loop when a source is added.
145  */
146   gint wake_up_pipe[2];
147 #else /* G_OS_WIN32 */
148   HANDLE wake_up_semaphore;
149 #endif /* G_OS_WIN32 */
150 
151   GPollFD wake_up_rec;
152   gboolean poll_waiting;
153 
154 /* Flag indicating whether the set of fd's changed during a poll */
155   gboolean poll_changed;
156 #endif /* G_THREADS_ENABLED */
157 
158   GPollFunc poll_func;
159 
160   GTimeVal current_time;
161   gboolean time_is_current;
162 };
163 
164 struct _GSourceCallback
165 {
166   guint ref_count;
167   GSourceFunc func;
168   gpointer    data;
169   GDestroyNotify notify;
170 };
171 
172 struct _GMainLoop
173 {
174   GMainContext *context;
175   gboolean is_running;
176   gint ref_count;
177 };
178 
179 struct _GTimeoutSource
180 {
181   GSource     source;
182   GTimeVal    expiration;
183   guint       interval;
184   guint	      granularity;
185 };
186 
187 struct _GChildWatchSource
188 {
189   GSource     source;
190   GPid        pid;
191   gint        child_status;
192 #ifdef G_OS_WIN32
193   GPollFD     poll;
194 #else /* G_OS_WIN32 */
195   gint        count;
196   gboolean    child_exited;
197 #endif /* G_OS_WIN32 */
198 };
199 
200 struct _GPollRec
201 {
202   GPollFD *fd;
203   GPollRec *next;
204   gint priority;
205 };
206 
207 #ifdef G_THREADS_ENABLED
208 #define LOCK_CONTEXT(context) g_static_mutex_lock (&context->mutex)
209 #define UNLOCK_CONTEXT(context) g_static_mutex_unlock (&context->mutex)
210 #define G_THREAD_SELF g_thread_self ()
211 #else
212 #define LOCK_CONTEXT(context) (void)0
213 #define UNLOCK_CONTEXT(context) (void)0
214 #define G_THREAD_SELF NULL
215 #endif
216 
217 #define SOURCE_DESTROYED(source) (((source)->flags & G_HOOK_FLAG_ACTIVE) == 0)
218 #define SOURCE_BLOCKED(source) (((source)->flags & G_HOOK_FLAG_IN_CALL) != 0 && \
219 		                ((source)->flags & G_SOURCE_CAN_RECURSE) == 0)
220 
221 #define SOURCE_UNREF(source, context)                       \
222    G_STMT_START {                                           \
223     if ((source)->ref_count > 1)                            \
224       (source)->ref_count--;                                \
225     else                                                    \
226       g_source_unref_internal ((source), (context), TRUE);  \
227    } G_STMT_END
228 
229 
230 /* Forward declarations */
231 
232 static void g_source_unref_internal             (GSource      *source,
233 						 GMainContext *context,
234 						 gboolean      have_lock);
235 static void g_source_destroy_internal           (GSource      *source,
236 						 GMainContext *context,
237 						 gboolean      have_lock);
238 static void g_main_context_poll                 (GMainContext *context,
239 						 gint          timeout,
240 						 gint          priority,
241 						 GPollFD      *fds,
242 						 gint          n_fds);
243 static void g_main_context_add_poll_unlocked    (GMainContext *context,
244 						 gint          priority,
245 						 GPollFD      *fd);
246 static void g_main_context_remove_poll_unlocked (GMainContext *context,
247 						 GPollFD      *fd);
248 static void g_main_context_wakeup_unlocked      (GMainContext *context);
249 
250 static gboolean g_timeout_prepare  (GSource     *source,
251 				    gint        *timeout);
252 static gboolean g_timeout_check    (GSource     *source);
253 static gboolean g_timeout_dispatch (GSource     *source,
254 				    GSourceFunc  callback,
255 				    gpointer     user_data);
256 static gboolean g_child_watch_prepare  (GSource     *source,
257 				        gint        *timeout);
258 static gboolean g_child_watch_check    (GSource     *source);
259 static gboolean g_child_watch_dispatch (GSource     *source,
260 					GSourceFunc  callback,
261 					gpointer     user_data);
262 static gboolean g_idle_prepare     (GSource     *source,
263 				    gint        *timeout);
264 static gboolean g_idle_check       (GSource     *source);
265 static gboolean g_idle_dispatch    (GSource     *source,
266 				    GSourceFunc  callback,
267 				    gpointer     user_data);
268 
269 G_LOCK_DEFINE_STATIC (main_loop);
270 static GMainContext *default_main_context;
271 static GSList *main_contexts_without_pipe = NULL;
272 
273 #ifndef G_OS_WIN32
274 /* Child status monitoring code */
275 enum {
276   CHILD_WATCH_UNINITIALIZED,
277   CHILD_WATCH_INITIALIZED_SINGLE,
278   CHILD_WATCH_INITIALIZED_THREADED
279 };
280 static gint child_watch_init_state = CHILD_WATCH_UNINITIALIZED;
281 static gint child_watch_count = 1;
282 static gint child_watch_wake_up_pipe[2] = {0, 0};
283 #endif /* !G_OS_WIN32 */
284 G_LOCK_DEFINE_STATIC (main_context_list);
285 static GSList *main_context_list = NULL;
286 
287 static gint timer_perturb = -1;
288 
289 GSourceFuncs g_timeout_funcs =
290 {
291   g_timeout_prepare,
292   g_timeout_check,
293   g_timeout_dispatch,
294   NULL
295 };
296 
297 GSourceFuncs g_child_watch_funcs =
298 {
299   g_child_watch_prepare,
300   g_child_watch_check,
301   g_child_watch_dispatch,
302   NULL
303 };
304 
305 GSourceFuncs g_idle_funcs =
306 {
307   g_idle_prepare,
308   g_idle_check,
309   g_idle_dispatch,
310   NULL
311 };
312 
313 /**
314  * g_main_context_ref:
315  * @context: a #GMainContext
316  *
317  * Increases the reference count on a #GMainContext object by one.
318  *
319  * Returns: the @context that was passed in (since 2.6)
320  **/
321 GMainContext *
g_main_context_ref(GMainContext * context)322 g_main_context_ref (GMainContext *context)
323 {
324   g_return_val_if_fail (context != NULL, NULL);
325   g_return_val_if_fail (g_atomic_int_get (&context->ref_count) > 0, NULL);
326 
327   g_atomic_int_inc (&context->ref_count);
328 
329   return context;
330 }
331 
332 static inline void
poll_rec_list_free(GMainContext * context,GPollRec * list)333 poll_rec_list_free (GMainContext *context,
334 		    GPollRec     *list)
335 {
336   g_slice_free_chain (GPollRec, list, next);
337 }
338 
339 /**
340  * g_main_context_unref:
341  * @context: a #GMainContext
342  *
343  * Decreases the reference count on a #GMainContext object by one. If
344  * the result is zero, free the context and free all associated memory.
345  **/
346 void
g_main_context_unref(GMainContext * context)347 g_main_context_unref (GMainContext *context)
348 {
349   GSource *source;
350   g_return_if_fail (context != NULL);
351   g_return_if_fail (g_atomic_int_get (&context->ref_count) > 0);
352 
353   if (!g_atomic_int_dec_and_test (&context->ref_count))
354     return;
355 
356   G_LOCK (main_context_list);
357   main_context_list = g_slist_remove (main_context_list, context);
358   G_UNLOCK (main_context_list);
359 
360   source = context->source_list;
361   while (source)
362     {
363       GSource *next = source->next;
364       g_source_destroy_internal (source, context, FALSE);
365       source = next;
366     }
367 
368 #ifdef G_THREADS_ENABLED
369   g_static_mutex_free (&context->mutex);
370 #endif
371 
372   g_ptr_array_free (context->pending_dispatches, TRUE);
373   g_free (context->cached_poll_array);
374 
375   poll_rec_list_free (context, context->poll_records);
376 
377 #ifdef G_THREADS_ENABLED
378   if (g_thread_supported())
379     {
380 #ifndef G_OS_WIN32
381       close (context->wake_up_pipe[0]);
382       close (context->wake_up_pipe[1]);
383 #else
384       CloseHandle (context->wake_up_semaphore);
385 #endif
386     }
387   else
388     main_contexts_without_pipe = g_slist_remove (main_contexts_without_pipe,
389 						 context);
390 
391   if (context->cond != NULL)
392     g_cond_free (context->cond);
393 #endif
394 
395   g_free (context);
396 }
397 
398 #ifdef G_THREADS_ENABLED
399 static void
g_main_context_init_pipe(GMainContext * context)400 g_main_context_init_pipe (GMainContext *context)
401 {
402 # ifndef G_OS_WIN32
403   if (context->wake_up_pipe[0] != -1)
404     return;
405   if (pipe (context->wake_up_pipe) < 0)
406     g_error ("Cannot create pipe main loop wake-up: %s\n",
407 	     g_strerror (errno));
408 
409   fcntl (context->wake_up_pipe[0], F_SETFD, FD_CLOEXEC);
410   fcntl (context->wake_up_pipe[1], F_SETFD, FD_CLOEXEC);
411 
412   context->wake_up_rec.fd = context->wake_up_pipe[0];
413   context->wake_up_rec.events = G_IO_IN;
414 # else
415   if (context->wake_up_semaphore != NULL)
416     return;
417   context->wake_up_semaphore = CreateSemaphore (NULL, 0, 100, NULL);
418   if (context->wake_up_semaphore == NULL)
419     g_error ("Cannot create wake-up semaphore: %s",
420 	     g_win32_error_message (GetLastError ()));
421   context->wake_up_rec.fd = (gintptr) context->wake_up_semaphore;
422   context->wake_up_rec.events = G_IO_IN;
423 
424   if (_g_main_poll_debug)
425     g_print ("wake-up semaphore: %p\n", context->wake_up_semaphore);
426 # endif
427   g_main_context_add_poll_unlocked (context, 0, &context->wake_up_rec);
428 }
429 
430 void
_g_main_thread_init(void)431 _g_main_thread_init (void)
432 {
433   GSList *curr = main_contexts_without_pipe;
434   while (curr)
435     {
436       g_main_context_init_pipe ((GMainContext *)curr->data);
437       curr = curr->next;
438     }
439   g_slist_free (main_contexts_without_pipe);
440   main_contexts_without_pipe = NULL;
441 }
442 #endif /* G_THREADS_ENABLED */
443 
444 /**
445  * g_main_context_new:
446  *
447  * Creates a new #GMainContext structure.
448  *
449  * Return value: the new #GMainContext
450  **/
451 GMainContext *
g_main_context_new(void)452 g_main_context_new (void)
453 {
454   GMainContext *context = g_new0 (GMainContext, 1);
455 
456 #ifdef G_MAIN_POLL_DEBUG
457   {
458     static gboolean beenhere = FALSE;
459 
460     if (!beenhere)
461       {
462 	if (getenv ("G_MAIN_POLL_DEBUG") != NULL)
463 	  _g_main_poll_debug = TRUE;
464 	beenhere = TRUE;
465       }
466   }
467 #endif
468 
469 #ifdef G_THREADS_ENABLED
470   g_static_mutex_init (&context->mutex);
471 
472   context->owner = NULL;
473   context->waiters = NULL;
474 
475 # ifndef G_OS_WIN32
476   context->wake_up_pipe[0] = -1;
477   context->wake_up_pipe[1] = -1;
478 # else
479   context->wake_up_semaphore = NULL;
480 # endif
481 #endif
482 
483   context->ref_count = 1;
484 
485   context->next_id = 1;
486 
487   context->source_list = NULL;
488 
489   context->poll_func = g_poll;
490 
491   context->cached_poll_array = NULL;
492   context->cached_poll_array_size = 0;
493 
494   context->pending_dispatches = g_ptr_array_new ();
495 
496   context->time_is_current = FALSE;
497 
498 #ifdef G_THREADS_ENABLED
499   if (g_thread_supported ())
500     g_main_context_init_pipe (context);
501   else
502     main_contexts_without_pipe = g_slist_prepend (main_contexts_without_pipe,
503 						  context);
504 #endif
505 
506   G_LOCK (main_context_list);
507   main_context_list = g_slist_append (main_context_list, context);
508 
509 #ifdef G_MAIN_POLL_DEBUG
510   if (_g_main_poll_debug)
511     g_print ("created context=%p\n", context);
512 #endif
513 
514   G_UNLOCK (main_context_list);
515 
516   return context;
517 }
518 
519 /**
520  * g_main_context_default:
521  *
522  * Returns the default main context. This is the main context used
523  * for main loop functions when a main loop is not explicitly
524  * specified.
525  *
526  * Return value: the default main context.
527  **/
528 GMainContext *
g_main_context_default(void)529 g_main_context_default (void)
530 {
531   /* Slow, but safe */
532 
533   G_LOCK (main_loop);
534 
535   if (!default_main_context)
536     {
537       default_main_context = g_main_context_new ();
538 #ifdef G_MAIN_POLL_DEBUG
539       if (_g_main_poll_debug)
540 	g_print ("default context=%p\n", default_main_context);
541 #endif
542     }
543 
544   G_UNLOCK (main_loop);
545 
546   return default_main_context;
547 }
548 
549 /* Hooks for adding to the main loop */
550 
551 /**
552  * g_source_new:
553  * @source_funcs: structure containing functions that implement
554  *                the sources behavior.
555  * @struct_size: size of the #GSource structure to create.
556  *
557  * Creates a new #GSource structure. The size is specified to
558  * allow creating structures derived from #GSource that contain
559  * additional data. The size passed in must be at least
560  * <literal>sizeof (GSource)</literal>.
561  *
562  * The source will not initially be associated with any #GMainContext
563  * and must be added to one with g_source_attach() before it will be
564  * executed.
565  *
566  * Return value: the newly-created #GSource.
567  **/
568 GSource *
g_source_new(GSourceFuncs * source_funcs,guint struct_size)569 g_source_new (GSourceFuncs *source_funcs,
570 	      guint         struct_size)
571 {
572   GSource *source;
573 
574   g_return_val_if_fail (source_funcs != NULL, NULL);
575   g_return_val_if_fail (struct_size >= sizeof (GSource), NULL);
576 
577   source = (GSource*) g_malloc0 (struct_size);
578 
579   source->source_funcs = source_funcs;
580   source->ref_count = 1;
581 
582   source->priority = G_PRIORITY_DEFAULT;
583 
584   source->flags = G_HOOK_FLAG_ACTIVE;
585 
586   /* NULL/0 initialization for all other fields */
587 
588   return source;
589 }
590 
591 /* Holds context's lock
592  */
593 static void
g_source_list_add(GSource * source,GMainContext * context)594 g_source_list_add (GSource      *source,
595 		   GMainContext *context)
596 {
597   GSource *tmp_source, *last_source;
598 
599   last_source = NULL;
600   tmp_source = context->source_list;
601   while (tmp_source && tmp_source->priority <= source->priority)
602     {
603       last_source = tmp_source;
604       tmp_source = tmp_source->next;
605     }
606 
607   source->next = tmp_source;
608   if (tmp_source)
609     tmp_source->prev = source;
610 
611   source->prev = last_source;
612   if (last_source)
613     last_source->next = source;
614   else
615     context->source_list = source;
616 }
617 
618 /* Holds context's lock
619  */
620 static void
g_source_list_remove(GSource * source,GMainContext * context)621 g_source_list_remove (GSource      *source,
622 		      GMainContext *context)
623 {
624   if (source->prev)
625     source->prev->next = source->next;
626   else
627     context->source_list = source->next;
628 
629   if (source->next)
630     source->next->prev = source->prev;
631 
632   source->prev = NULL;
633   source->next = NULL;
634 }
635 
636 /**
637  * g_source_attach:
638  * @source: a #GSource
639  * @context: a #GMainContext (if %NULL, the default context will be used)
640  *
641  * Adds a #GSource to a @context so that it will be executed within
642  * that context. Remove it by calling g_source_destroy().
643  *
644  * Return value: the ID (greater than 0) for the source within the
645  *   #GMainContext.
646  **/
647 guint
g_source_attach(GSource * source,GMainContext * context)648 g_source_attach (GSource      *source,
649 		 GMainContext *context)
650 {
651   guint result = 0;
652   GSList *tmp_list;
653 
654   g_return_val_if_fail (source->context == NULL, 0);
655   g_return_val_if_fail (!SOURCE_DESTROYED (source), 0);
656 
657   if (!context)
658     context = g_main_context_default ();
659 
660   LOCK_CONTEXT (context);
661 
662   source->context = context;
663   result = source->source_id = context->next_id++;
664 
665   source->ref_count++;
666   g_source_list_add (source, context);
667 
668   tmp_list = source->poll_fds;
669   while (tmp_list)
670     {
671       g_main_context_add_poll_unlocked (context, source->priority, tmp_list->data);
672       tmp_list = tmp_list->next;
673     }
674 
675 #ifdef G_THREADS_ENABLED
676   /* Now wake up the main loop if it is waiting in the poll() */
677   g_main_context_wakeup_unlocked (context);
678 #endif
679 
680   UNLOCK_CONTEXT (context);
681 
682   return result;
683 }
684 
685 static void
g_source_destroy_internal(GSource * source,GMainContext * context,gboolean have_lock)686 g_source_destroy_internal (GSource      *source,
687 			   GMainContext *context,
688 			   gboolean      have_lock)
689 {
690   if (!have_lock)
691     LOCK_CONTEXT (context);
692 
693   if (!SOURCE_DESTROYED (source))
694     {
695       GSList *tmp_list;
696       gpointer old_cb_data;
697       GSourceCallbackFuncs *old_cb_funcs;
698 
699       source->flags &= ~G_HOOK_FLAG_ACTIVE;
700 
701       old_cb_data = source->callback_data;
702       old_cb_funcs = source->callback_funcs;
703 
704       source->callback_data = NULL;
705       source->callback_funcs = NULL;
706 
707       if (old_cb_funcs)
708 	{
709 	  UNLOCK_CONTEXT (context);
710 	  old_cb_funcs->unref (old_cb_data);
711 	  LOCK_CONTEXT (context);
712 	}
713 
714       if (!SOURCE_BLOCKED (source))
715 	{
716 	  tmp_list = source->poll_fds;
717 	  while (tmp_list)
718 	    {
719 	      g_main_context_remove_poll_unlocked (context, tmp_list->data);
720 	      tmp_list = tmp_list->next;
721 	    }
722 	}
723 
724       g_source_unref_internal (source, context, TRUE);
725     }
726 
727   if (!have_lock)
728     UNLOCK_CONTEXT (context);
729 }
730 
731 /**
732  * g_source_destroy:
733  * @source: a #GSource
734  *
735  * Removes a source from its #GMainContext, if any, and mark it as
736  * destroyed.  The source cannot be subsequently added to another
737  * context.
738  **/
739 void
g_source_destroy(GSource * source)740 g_source_destroy (GSource *source)
741 {
742   GMainContext *context;
743 
744   g_return_if_fail (source != NULL);
745 
746   context = source->context;
747 
748   if (context)
749     g_source_destroy_internal (source, context, FALSE);
750   else
751     source->flags &= ~G_HOOK_FLAG_ACTIVE;
752 }
753 
754 /**
755  * g_source_get_id:
756  * @source: a #GSource
757  *
758  * Returns the numeric ID for a particular source. The ID of a source
759  * is a positive integer which is unique within a particular main loop
760  * context. The reverse
761  * mapping from ID to source is done by g_main_context_find_source_by_id().
762  *
763  * Return value: the ID (greater than 0) for the source
764  **/
765 guint
g_source_get_id(GSource * source)766 g_source_get_id (GSource *source)
767 {
768   guint result;
769 
770   g_return_val_if_fail (source != NULL, 0);
771   g_return_val_if_fail (source->context != NULL, 0);
772 
773   LOCK_CONTEXT (source->context);
774   result = source->source_id;
775   UNLOCK_CONTEXT (source->context);
776 
777   return result;
778 }
779 
780 /**
781  * g_source_get_context:
782  * @source: a #GSource
783  *
784  * Gets the #GMainContext with which the source is associated.
785  * Calling this function on a destroyed source is an error.
786  *
787  * Return value: the #GMainContext with which the source is associated,
788  *               or %NULL if the context has not yet been added
789  *               to a source.
790  **/
791 GMainContext *
g_source_get_context(GSource * source)792 g_source_get_context (GSource *source)
793 {
794   g_return_val_if_fail (!SOURCE_DESTROYED (source), NULL);
795 
796   return source->context;
797 }
798 
799 /**
800  * g_source_add_poll:
801  * @source:a #GSource
802  * @fd: a #GPollFD structure holding information about a file
803  *      descriptor to watch.
804  *
805  * Adds a file descriptor to the set of file descriptors polled for
806  * this source. This is usually combined with g_source_new() to add an
807  * event source. The event source's check function will typically test
808  * the @revents field in the #GPollFD struct and return %TRUE if events need
809  * to be processed.
810  **/
811 void
g_source_add_poll(GSource * source,GPollFD * fd)812 g_source_add_poll (GSource *source,
813 		   GPollFD *fd)
814 {
815   GMainContext *context;
816 
817   g_return_if_fail (source != NULL);
818   g_return_if_fail (fd != NULL);
819   g_return_if_fail (!SOURCE_DESTROYED (source));
820 
821   context = source->context;
822 
823   if (context)
824     LOCK_CONTEXT (context);
825 
826   source->poll_fds = g_slist_prepend (source->poll_fds, fd);
827 
828   if (context)
829     {
830       if (!SOURCE_BLOCKED (source))
831 	g_main_context_add_poll_unlocked (context, source->priority, fd);
832       UNLOCK_CONTEXT (context);
833     }
834 }
835 
836 /**
837  * g_source_remove_poll:
838  * @source:a #GSource
839  * @fd: a #GPollFD structure previously passed to g_source_add_poll().
840  *
841  * Removes a file descriptor from the set of file descriptors polled for
842  * this source.
843  **/
844 void
g_source_remove_poll(GSource * source,GPollFD * fd)845 g_source_remove_poll (GSource *source,
846 		      GPollFD *fd)
847 {
848   GMainContext *context;
849 
850   g_return_if_fail (source != NULL);
851   g_return_if_fail (fd != NULL);
852   g_return_if_fail (!SOURCE_DESTROYED (source));
853 
854   context = source->context;
855 
856   if (context)
857     LOCK_CONTEXT (context);
858 
859   source->poll_fds = g_slist_remove (source->poll_fds, fd);
860 
861   if (context)
862     {
863       if (!SOURCE_BLOCKED (source))
864 	g_main_context_remove_poll_unlocked (context, fd);
865       UNLOCK_CONTEXT (context);
866     }
867 }
868 
869 /**
870  * g_source_set_callback_indirect:
871  * @source: the source
872  * @callback_data: pointer to callback data "object"
873  * @callback_funcs: functions for reference counting @callback_data
874  *                  and getting the callback and data
875  *
876  * Sets the callback function storing the data as a refcounted callback
877  * "object". This is used internally. Note that calling
878  * g_source_set_callback_indirect() assumes
879  * an initial reference count on @callback_data, and thus
880  * @callback_funcs->unref will eventually be called once more
881  * than @callback_funcs->ref.
882  **/
883 void
g_source_set_callback_indirect(GSource * source,gpointer callback_data,GSourceCallbackFuncs * callback_funcs)884 g_source_set_callback_indirect (GSource              *source,
885 				gpointer              callback_data,
886 				GSourceCallbackFuncs *callback_funcs)
887 {
888   GMainContext *context;
889   gpointer old_cb_data;
890   GSourceCallbackFuncs *old_cb_funcs;
891 
892   g_return_if_fail (source != NULL);
893   g_return_if_fail (callback_funcs != NULL || callback_data == NULL);
894 
895   context = source->context;
896 
897   if (context)
898     LOCK_CONTEXT (context);
899 
900   old_cb_data = source->callback_data;
901   old_cb_funcs = source->callback_funcs;
902 
903   source->callback_data = callback_data;
904   source->callback_funcs = callback_funcs;
905 
906   if (context)
907     UNLOCK_CONTEXT (context);
908 
909   if (old_cb_funcs)
910     old_cb_funcs->unref (old_cb_data);
911 }
912 
913 static void
g_source_callback_ref(gpointer cb_data)914 g_source_callback_ref (gpointer cb_data)
915 {
916   GSourceCallback *callback = cb_data;
917 
918   callback->ref_count++;
919 }
920 
921 
922 static void
g_source_callback_unref(gpointer cb_data)923 g_source_callback_unref (gpointer cb_data)
924 {
925   GSourceCallback *callback = cb_data;
926 
927   callback->ref_count--;
928   if (callback->ref_count == 0)
929     {
930       if (callback->notify)
931 	callback->notify (callback->data);
932       g_free (callback);
933     }
934 }
935 
936 static void
g_source_callback_get(gpointer cb_data,GSource * source,GSourceFunc * func,gpointer * data)937 g_source_callback_get (gpointer     cb_data,
938 		       GSource     *source,
939 		       GSourceFunc *func,
940 		       gpointer    *data)
941 {
942   GSourceCallback *callback = cb_data;
943 
944   *func = callback->func;
945   *data = callback->data;
946 }
947 
948 static GSourceCallbackFuncs g_source_callback_funcs = {
949   g_source_callback_ref,
950   g_source_callback_unref,
951   g_source_callback_get,
952 };
953 
954 /**
955  * g_source_set_callback:
956  * @source: the source
957  * @func: a callback function
958  * @data: the data to pass to callback function
959  * @notify: a function to call when @data is no longer in use, or %NULL.
960  *
961  * Sets the callback function for a source. The callback for a source is
962  * called from the source's dispatch function.
963  *
964  * The exact type of @func depends on the type of source; ie. you
965  * should not count on @func being called with @data as its first
966  * parameter.
967  *
968  * Typically, you won't use this function. Instead use functions specific
969  * to the type of source you are using.
970  **/
971 void
g_source_set_callback(GSource * source,GSourceFunc func,gpointer data,GDestroyNotify notify)972 g_source_set_callback (GSource        *source,
973 		       GSourceFunc     func,
974 		       gpointer        data,
975 		       GDestroyNotify  notify)
976 {
977   GSourceCallback *new_callback;
978 
979   g_return_if_fail (source != NULL);
980 
981   new_callback = g_new (GSourceCallback, 1);
982 
983   new_callback->ref_count = 1;
984   new_callback->func = func;
985   new_callback->data = data;
986   new_callback->notify = notify;
987 
988   g_source_set_callback_indirect (source, new_callback, &g_source_callback_funcs);
989 }
990 
991 
992 /**
993  * g_source_set_funcs:
994  * @source: a #GSource
995  * @funcs: the new #GSourceFuncs
996  *
997  * Sets the source functions (can be used to override
998  * default implementations) of an unattached source.
999  *
1000  * Since: 2.12
1001  */
1002 void
g_source_set_funcs(GSource * source,GSourceFuncs * funcs)1003 g_source_set_funcs (GSource     *source,
1004 	           GSourceFuncs *funcs)
1005 {
1006   g_return_if_fail (source != NULL);
1007   g_return_if_fail (source->context == NULL);
1008   g_return_if_fail (source->ref_count > 0);
1009   g_return_if_fail (funcs != NULL);
1010 
1011   source->source_funcs = funcs;
1012 }
1013 
1014 /**
1015  * g_source_set_priority:
1016  * @source: a #GSource
1017  * @priority: the new priority.
1018  *
1019  * Sets the priority of a source. While the main loop is being
1020  * run, a source will be dispatched if it is ready to be dispatched and no sources
1021  * at a higher (numerically smaller) priority are ready to be dispatched.
1022  **/
1023 void
g_source_set_priority(GSource * source,gint priority)1024 g_source_set_priority (GSource  *source,
1025 		       gint      priority)
1026 {
1027   GSList *tmp_list;
1028   GMainContext *context;
1029 
1030   g_return_if_fail (source != NULL);
1031 
1032   context = source->context;
1033 
1034   if (context)
1035     LOCK_CONTEXT (context);
1036 
1037   source->priority = priority;
1038 
1039   if (context)
1040     {
1041       /* Remove the source from the context's source and then
1042        * add it back so it is sorted in the correct plcae
1043        */
1044       g_source_list_remove (source, source->context);
1045       g_source_list_add (source, source->context);
1046 
1047       if (!SOURCE_BLOCKED (source))
1048 	{
1049 	  tmp_list = source->poll_fds;
1050 	  while (tmp_list)
1051 	    {
1052 	      g_main_context_remove_poll_unlocked (context, tmp_list->data);
1053 	      g_main_context_add_poll_unlocked (context, priority, tmp_list->data);
1054 
1055 	      tmp_list = tmp_list->next;
1056 	    }
1057 	}
1058 
1059       UNLOCK_CONTEXT (source->context);
1060     }
1061 }
1062 
1063 /**
1064  * g_source_get_priority:
1065  * @source: a #GSource
1066  *
1067  * Gets the priority of a source.
1068  *
1069  * Return value: the priority of the source
1070  **/
1071 gint
g_source_get_priority(GSource * source)1072 g_source_get_priority (GSource *source)
1073 {
1074   g_return_val_if_fail (source != NULL, 0);
1075 
1076   return source->priority;
1077 }
1078 
1079 /**
1080  * g_source_set_can_recurse:
1081  * @source: a #GSource
1082  * @can_recurse: whether recursion is allowed for this source
1083  *
1084  * Sets whether a source can be called recursively. If @can_recurse is
1085  * %TRUE, then while the source is being dispatched then this source
1086  * will be processed normally. Otherwise, all processing of this
1087  * source is blocked until the dispatch function returns.
1088  **/
1089 void
g_source_set_can_recurse(GSource * source,gboolean can_recurse)1090 g_source_set_can_recurse (GSource  *source,
1091 			  gboolean  can_recurse)
1092 {
1093   GMainContext *context;
1094 
1095   g_return_if_fail (source != NULL);
1096 
1097   context = source->context;
1098 
1099   if (context)
1100     LOCK_CONTEXT (context);
1101 
1102   if (can_recurse)
1103     source->flags |= G_SOURCE_CAN_RECURSE;
1104   else
1105     source->flags &= ~G_SOURCE_CAN_RECURSE;
1106 
1107   if (context)
1108     UNLOCK_CONTEXT (context);
1109 }
1110 
1111 /**
1112  * g_source_get_can_recurse:
1113  * @source: a #GSource
1114  *
1115  * Checks whether a source is allowed to be called recursively.
1116  * see g_source_set_can_recurse().
1117  *
1118  * Return value: whether recursion is allowed.
1119  **/
1120 gboolean
g_source_get_can_recurse(GSource * source)1121 g_source_get_can_recurse (GSource  *source)
1122 {
1123   g_return_val_if_fail (source != NULL, FALSE);
1124 
1125   return (source->flags & G_SOURCE_CAN_RECURSE) != 0;
1126 }
1127 
1128 /**
1129  * g_source_ref:
1130  * @source: a #GSource
1131  *
1132  * Increases the reference count on a source by one.
1133  *
1134  * Return value: @source
1135  **/
1136 GSource *
g_source_ref(GSource * source)1137 g_source_ref (GSource *source)
1138 {
1139   GMainContext *context;
1140 
1141   g_return_val_if_fail (source != NULL, NULL);
1142 
1143   context = source->context;
1144 
1145   if (context)
1146     LOCK_CONTEXT (context);
1147 
1148   source->ref_count++;
1149 
1150   if (context)
1151     UNLOCK_CONTEXT (context);
1152 
1153   return source;
1154 }
1155 
1156 /* g_source_unref() but possible to call within context lock
1157  */
1158 static void
g_source_unref_internal(GSource * source,GMainContext * context,gboolean have_lock)1159 g_source_unref_internal (GSource      *source,
1160 			 GMainContext *context,
1161 			 gboolean      have_lock)
1162 {
1163   gpointer old_cb_data = NULL;
1164   GSourceCallbackFuncs *old_cb_funcs = NULL;
1165 
1166   g_return_if_fail (source != NULL);
1167 
1168   if (!have_lock && context)
1169     LOCK_CONTEXT (context);
1170 
1171   source->ref_count--;
1172   if (source->ref_count == 0)
1173     {
1174       old_cb_data = source->callback_data;
1175       old_cb_funcs = source->callback_funcs;
1176 
1177       source->callback_data = NULL;
1178       source->callback_funcs = NULL;
1179 
1180       if (context && !SOURCE_DESTROYED (source))
1181 	{
1182 	  g_warning (G_STRLOC ": ref_count == 0, but source is still attached to a context!");
1183 	  source->ref_count++;
1184 	}
1185       else if (context)
1186 	g_source_list_remove (source, context);
1187 
1188       if (source->source_funcs->finalize)
1189 	source->source_funcs->finalize (source);
1190 
1191       g_slist_free (source->poll_fds);
1192       source->poll_fds = NULL;
1193       g_free (source);
1194     }
1195 
1196   if (!have_lock && context)
1197     UNLOCK_CONTEXT (context);
1198 
1199   if (old_cb_funcs)
1200     {
1201       if (have_lock)
1202 	UNLOCK_CONTEXT (context);
1203 
1204       old_cb_funcs->unref (old_cb_data);
1205 
1206       if (have_lock)
1207 	LOCK_CONTEXT (context);
1208     }
1209 }
1210 
1211 /**
1212  * g_source_unref:
1213  * @source: a #GSource
1214  *
1215  * Decreases the reference count of a source by one. If the
1216  * resulting reference count is zero the source and associated
1217  * memory will be destroyed.
1218  **/
1219 void
g_source_unref(GSource * source)1220 g_source_unref (GSource *source)
1221 {
1222   g_return_if_fail (source != NULL);
1223 
1224   g_source_unref_internal (source, source->context, FALSE);
1225 }
1226 
1227 /**
1228  * g_main_context_find_source_by_id:
1229  * @context: a #GMainContext (if %NULL, the default context will be used)
1230  * @source_id: the source ID, as returned by g_source_get_id().
1231  *
1232  * Finds a #GSource given a pair of context and ID.
1233  *
1234  * Return value: the #GSource if found, otherwise, %NULL
1235  **/
1236 GSource *
g_main_context_find_source_by_id(GMainContext * context,guint source_id)1237 g_main_context_find_source_by_id (GMainContext *context,
1238 				  guint         source_id)
1239 {
1240   GSource *source;
1241 
1242   g_return_val_if_fail (source_id > 0, NULL);
1243 
1244   if (context == NULL)
1245     context = g_main_context_default ();
1246 
1247   LOCK_CONTEXT (context);
1248 
1249   source = context->source_list;
1250   while (source)
1251     {
1252       if (!SOURCE_DESTROYED (source) &&
1253 	  source->source_id == source_id)
1254 	break;
1255       source = source->next;
1256     }
1257 
1258   UNLOCK_CONTEXT (context);
1259 
1260   return source;
1261 }
1262 
1263 /**
1264  * g_main_context_find_source_by_funcs_user_data:
1265  * @context: a #GMainContext (if %NULL, the default context will be used).
1266  * @funcs: the @source_funcs passed to g_source_new().
1267  * @user_data: the user data from the callback.
1268  *
1269  * Finds a source with the given source functions and user data.  If
1270  * multiple sources exist with the same source function and user data,
1271  * the first one found will be returned.
1272  *
1273  * Return value: the source, if one was found, otherwise %NULL
1274  **/
1275 GSource *
g_main_context_find_source_by_funcs_user_data(GMainContext * context,GSourceFuncs * funcs,gpointer user_data)1276 g_main_context_find_source_by_funcs_user_data (GMainContext *context,
1277 					       GSourceFuncs *funcs,
1278 					       gpointer      user_data)
1279 {
1280   GSource *source;
1281 
1282   g_return_val_if_fail (funcs != NULL, NULL);
1283 
1284   if (context == NULL)
1285     context = g_main_context_default ();
1286 
1287   LOCK_CONTEXT (context);
1288 
1289   source = context->source_list;
1290   while (source)
1291     {
1292       if (!SOURCE_DESTROYED (source) &&
1293 	  source->source_funcs == funcs &&
1294 	  source->callback_funcs)
1295 	{
1296 	  GSourceFunc callback;
1297 	  gpointer callback_data;
1298 
1299 	  source->callback_funcs->get (source->callback_data, source, &callback, &callback_data);
1300 
1301 	  if (callback_data == user_data)
1302 	    break;
1303 	}
1304       source = source->next;
1305     }
1306 
1307   UNLOCK_CONTEXT (context);
1308 
1309   return source;
1310 }
1311 
1312 /**
1313  * g_main_context_find_source_by_user_data:
1314  * @context: a #GMainContext
1315  * @user_data: the user_data for the callback.
1316  *
1317  * Finds a source with the given user data for the callback.  If
1318  * multiple sources exist with the same user data, the first
1319  * one found will be returned.
1320  *
1321  * Return value: the source, if one was found, otherwise %NULL
1322  **/
1323 GSource *
g_main_context_find_source_by_user_data(GMainContext * context,gpointer user_data)1324 g_main_context_find_source_by_user_data (GMainContext *context,
1325 					 gpointer      user_data)
1326 {
1327   GSource *source;
1328 
1329   if (context == NULL)
1330     context = g_main_context_default ();
1331 
1332   LOCK_CONTEXT (context);
1333 
1334   source = context->source_list;
1335   while (source)
1336     {
1337       if (!SOURCE_DESTROYED (source) &&
1338 	  source->callback_funcs)
1339 	{
1340 	  GSourceFunc callback;
1341 	  gpointer callback_data = NULL;
1342 
1343 	  source->callback_funcs->get (source->callback_data, source, &callback, &callback_data);
1344 
1345 	  if (callback_data == user_data)
1346 	    break;
1347 	}
1348       source = source->next;
1349     }
1350 
1351   UNLOCK_CONTEXT (context);
1352 
1353   return source;
1354 }
1355 
1356 /**
1357  * g_source_remove:
1358  * @tag: the ID of the source to remove.
1359  *
1360  * Removes the source with the given id from the default main context.
1361  * The id of
1362  * a #GSource is given by g_source_get_id(), or will be returned by the
1363  * functions g_source_attach(), g_idle_add(), g_idle_add_full(),
1364  * g_timeout_add(), g_timeout_add_full(), g_child_watch_add(),
1365  * g_child_watch_add_full(), g_io_add_watch(), and g_io_add_watch_full().
1366  *
1367  * See also g_source_destroy(). You must use g_source_destroy() for sources
1368  * added to a non-default main context.
1369  *
1370  * Return value: %TRUE if the source was found and removed.
1371  **/
1372 gboolean
g_source_remove(guint tag)1373 g_source_remove (guint tag)
1374 {
1375   GSource *source;
1376 
1377   g_return_val_if_fail (tag > 0, FALSE);
1378 
1379   source = g_main_context_find_source_by_id (NULL, tag);
1380   if (source)
1381     g_source_destroy (source);
1382 
1383   return source != NULL;
1384 }
1385 
1386 /**
1387  * g_source_remove_by_user_data:
1388  * @user_data: the user_data for the callback.
1389  *
1390  * Removes a source from the default main loop context given the user
1391  * data for the callback. If multiple sources exist with the same user
1392  * data, only one will be destroyed.
1393  *
1394  * Return value: %TRUE if a source was found and removed.
1395  **/
1396 gboolean
g_source_remove_by_user_data(gpointer user_data)1397 g_source_remove_by_user_data (gpointer user_data)
1398 {
1399   GSource *source;
1400 
1401   source = g_main_context_find_source_by_user_data (NULL, user_data);
1402   if (source)
1403     {
1404       g_source_destroy (source);
1405       return TRUE;
1406     }
1407   else
1408     return FALSE;
1409 }
1410 
1411 /**
1412  * g_source_remove_by_funcs_user_data:
1413  * @funcs: The @source_funcs passed to g_source_new()
1414  * @user_data: the user data for the callback
1415  *
1416  * Removes a source from the default main loop context given the
1417  * source functions and user data. If multiple sources exist with the
1418  * same source functions and user data, only one will be destroyed.
1419  *
1420  * Return value: %TRUE if a source was found and removed.
1421  **/
1422 gboolean
g_source_remove_by_funcs_user_data(GSourceFuncs * funcs,gpointer user_data)1423 g_source_remove_by_funcs_user_data (GSourceFuncs *funcs,
1424 				    gpointer      user_data)
1425 {
1426   GSource *source;
1427 
1428   g_return_val_if_fail (funcs != NULL, FALSE);
1429 
1430   source = g_main_context_find_source_by_funcs_user_data (NULL, funcs, user_data);
1431   if (source)
1432     {
1433       g_source_destroy (source);
1434       return TRUE;
1435     }
1436   else
1437     return FALSE;
1438 }
1439 
1440 /**
1441  * g_get_current_time:
1442  * @result: #GTimeVal structure in which to store current time.
1443  *
1444  * Equivalent to the UNIX gettimeofday() function, but portable.
1445  **/
1446 void
g_get_current_time(GTimeVal * result)1447 g_get_current_time (GTimeVal *result)
1448 {
1449 #ifndef G_OS_WIN32
1450   struct timeval r;
1451 
1452   g_return_if_fail (result != NULL);
1453 
1454   /*this is required on alpha, there the timeval structs are int's
1455     not longs and a cast only would fail horribly*/
1456   gettimeofday (&r, NULL);
1457   result->tv_sec = r.tv_sec;
1458   result->tv_usec = r.tv_usec;
1459 #else
1460   FILETIME ft;
1461   guint64 time64;
1462 
1463   g_return_if_fail (result != NULL);
1464 
1465   GetSystemTimeAsFileTime (&ft);
1466   memmove (&time64, &ft, sizeof (FILETIME));
1467 
1468   /* Convert from 100s of nanoseconds since 1601-01-01
1469    * to Unix epoch. Yes, this is Y2038 unsafe.
1470    */
1471   time64 -= G_GINT64_CONSTANT (116444736000000000);
1472   time64 /= 10;
1473 
1474   result->tv_sec = time64 / 1000000;
1475   result->tv_usec = time64 % 1000000;
1476 #endif
1477 }
1478 
1479 static void
g_main_dispatch_free(gpointer dispatch)1480 g_main_dispatch_free (gpointer dispatch)
1481 {
1482   g_slice_free (GMainDispatch, dispatch);
1483 }
1484 
1485 /* Running the main loop */
1486 
1487 static GMainDispatch *
get_dispatch(void)1488 get_dispatch (void)
1489 {
1490   static GStaticPrivate depth_private = G_STATIC_PRIVATE_INIT;
1491   GMainDispatch *dispatch = g_static_private_get (&depth_private);
1492   if (!dispatch)
1493     {
1494       dispatch = g_slice_new0 (GMainDispatch);
1495       g_static_private_set (&depth_private, dispatch, g_main_dispatch_free);
1496     }
1497 
1498   return dispatch;
1499 }
1500 
1501 /**
1502  * g_main_depth:
1503  *
1504  * Returns the depth of the stack of calls to
1505  * g_main_context_dispatch() on any #GMainContext in the current thread.
1506  *  That is, when called from the toplevel, it gives 0. When
1507  * called from within a callback from g_main_context_iteration()
1508  * (or g_main_loop_run(), etc.) it returns 1. When called from within
1509  * a callback to a recursive call to g_main_context_iterate(),
1510  * it returns 2. And so forth.
1511  *
1512  * This function is useful in a situation like the following:
1513  * Imagine an extremely simple "garbage collected" system.
1514  *
1515  * |[
1516  * static GList *free_list;
1517  *
1518  * gpointer
1519  * allocate_memory (gsize size)
1520  * {
1521  *   gpointer result = g_malloc (size);
1522  *   free_list = g_list_prepend (free_list, result);
1523  *   return result;
1524  * }
1525  *
1526  * void
1527  * free_allocated_memory (void)
1528  * {
1529  *   GList *l;
1530  *   for (l = free_list; l; l = l->next);
1531  *     g_free (l->data);
1532  *   g_list_free (free_list);
1533  *   free_list = NULL;
1534  *  }
1535  *
1536  * [...]
1537  *
1538  * while (TRUE);
1539  *  {
1540  *    g_main_context_iteration (NULL, TRUE);
1541  *    free_allocated_memory();
1542  *   }
1543  * ]|
1544  *
1545  * This works from an application, however, if you want to do the same
1546  * thing from a library, it gets more difficult, since you no longer
1547  * control the main loop. You might think you can simply use an idle
1548  * function to make the call to free_allocated_memory(), but that
1549  * doesn't work, since the idle function could be called from a
1550  * recursive callback. This can be fixed by using g_main_depth()
1551  *
1552  * |[
1553  * gpointer
1554  * allocate_memory (gsize size)
1555  * {
1556  *   FreeListBlock *block = g_new (FreeListBlock, 1);
1557  *   block->mem = g_malloc (size);
1558  *   block->depth = g_main_depth ();
1559  *   free_list = g_list_prepend (free_list, block);
1560  *   return block->mem;
1561  * }
1562  *
1563  * void
1564  * free_allocated_memory (void)
1565  * {
1566  *   GList *l;
1567  *
1568  *   int depth = g_main_depth ();
1569  *   for (l = free_list; l; );
1570  *     {
1571  *       GList *next = l->next;
1572  *       FreeListBlock *block = l->data;
1573  *       if (block->depth > depth)
1574  *         {
1575  *           g_free (block->mem);
1576  *           g_free (block);
1577  *           free_list = g_list_delete_link (free_list, l);
1578  *         }
1579  *
1580  *       l = next;
1581  *     }
1582  *   }
1583  * ]|
1584  *
1585  * There is a temptation to use g_main_depth() to solve
1586  * problems with reentrancy. For instance, while waiting for data
1587  * to be received from the network in response to a menu item,
1588  * the menu item might be selected again. It might seem that
1589  * one could make the menu item's callback return immediately
1590  * and do nothing if g_main_depth() returns a value greater than 1.
1591  * However, this should be avoided since the user then sees selecting
1592  * the menu item do nothing. Furthermore, you'll find yourself adding
1593  * these checks all over your code, since there are doubtless many,
1594  * many things that the user could do. Instead, you can use the
1595  * following techniques:
1596  *
1597  * <orderedlist>
1598  *  <listitem>
1599  *   <para>
1600  *     Use gtk_widget_set_sensitive() or modal dialogs to prevent
1601  *     the user from interacting with elements while the main
1602  *     loop is recursing.
1603  *   </para>
1604  *  </listitem>
1605  *  <listitem>
1606  *   <para>
1607  *     Avoid main loop recursion in situations where you can't handle
1608  *     arbitrary  callbacks. Instead, structure your code so that you
1609  *     simply return to the main loop and then get called again when
1610  *     there is more work to do.
1611  *   </para>
1612  *  </listitem>
1613  * </orderedlist>
1614  *
1615  * Return value: The main loop recursion level in the current thread
1616  **/
1617 int
g_main_depth(void)1618 g_main_depth (void)
1619 {
1620   GMainDispatch *dispatch = get_dispatch ();
1621   return dispatch->depth;
1622 }
1623 
1624 /**
1625  * g_main_current_source:
1626  *
1627  * Returns the currently firing source for this thread.
1628  *
1629  * Return value: The currently firing source or %NULL.
1630  *
1631  * Since: 2.12
1632  */
1633 GSource *
g_main_current_source(void)1634 g_main_current_source (void)
1635 {
1636   GMainDispatch *dispatch = get_dispatch ();
1637   return dispatch->dispatching_sources ? dispatch->dispatching_sources->data : NULL;
1638 }
1639 
1640 /**
1641  * g_source_is_destroyed:
1642  * @source: a #GSource
1643  *
1644  * Returns whether @source has been destroyed.
1645  *
1646  * This is important when you operate upon your objects
1647  * from within idle handlers, but may have freed the object
1648  * before the dispatch of your idle handler.
1649  *
1650  * |[
1651  * static gboolean
1652  * idle_callback (gpointer data)
1653  * {
1654  *   SomeWidget *self = data;
1655  *
1656  *   GDK_THREADS_ENTER (<!-- -->);
1657  *   /<!-- -->* do stuff with self *<!-- -->/
1658  *   self->idle_id = 0;
1659  *   GDK_THREADS_LEAVE (<!-- -->);
1660  *
1661  *   return FALSE;
1662  * }
1663  *
1664  * static void
1665  * some_widget_do_stuff_later (SomeWidget *self)
1666  * {
1667  *   self->idle_id = g_idle_add (idle_callback, self);
1668  * }
1669  *
1670  * static void
1671  * some_widget_finalize (GObject *object)
1672  * {
1673  *   SomeWidget *self = SOME_WIDGET (object);
1674  *
1675  *   if (self->idle_id)
1676  *     g_source_remove (self->idle_id);
1677  *
1678  *   G_OBJECT_CLASS (parent_class)->finalize (object);
1679  * }
1680  * ]|
1681  *
1682  * This will fail in a multi-threaded application if the
1683  * widget is destroyed before the idle handler fires due
1684  * to the use after free in the callback. A solution, to
1685  * this particular problem, is to check to if the source
1686  * has already been destroy within the callback.
1687  *
1688  * |[
1689  * static gboolean
1690  * idle_callback (gpointer data)
1691  * {
1692  *   SomeWidget *self = data;
1693  *
1694  *   GDK_THREADS_ENTER ();
1695  *   if (!g_source_is_destroyed (g_main_current_source ()))
1696  *     {
1697  *       /<!-- -->* do stuff with self *<!-- -->/
1698  *     }
1699  *   GDK_THREADS_LEAVE ();
1700  *
1701  *   return FALSE;
1702  * }
1703  * ]|
1704  *
1705  * Return value: %TRUE if the source has been destroyed
1706  *
1707  * Since: 2.12
1708  */
1709 gboolean
g_source_is_destroyed(GSource * source)1710 g_source_is_destroyed (GSource *source)
1711 {
1712   return SOURCE_DESTROYED (source);
1713 }
1714 
1715 
1716 /* Temporarily remove all this source's file descriptors from the
1717  * poll(), so that if data comes available for one of the file descriptors
1718  * we don't continually spin in the poll()
1719  */
1720 /* HOLDS: source->context's lock */
1721 static void
block_source(GSource * source)1722 block_source (GSource *source)
1723 {
1724   GSList *tmp_list;
1725 
1726   g_return_if_fail (!SOURCE_BLOCKED (source));
1727 
1728   tmp_list = source->poll_fds;
1729   while (tmp_list)
1730     {
1731       g_main_context_remove_poll_unlocked (source->context, tmp_list->data);
1732       tmp_list = tmp_list->next;
1733     }
1734 }
1735 
1736 /* HOLDS: source->context's lock */
1737 static void
unblock_source(GSource * source)1738 unblock_source (GSource *source)
1739 {
1740   GSList *tmp_list;
1741 
1742   g_return_if_fail (!SOURCE_BLOCKED (source)); /* Source already unblocked */
1743   g_return_if_fail (!SOURCE_DESTROYED (source));
1744 
1745   tmp_list = source->poll_fds;
1746   while (tmp_list)
1747     {
1748       g_main_context_add_poll_unlocked (source->context, source->priority, tmp_list->data);
1749       tmp_list = tmp_list->next;
1750     }
1751 }
1752 
1753 /* HOLDS: context's lock */
1754 static void
g_main_dispatch(GMainContext * context)1755 g_main_dispatch (GMainContext *context)
1756 {
1757   GMainDispatch *current = get_dispatch ();
1758   guint i;
1759 
1760   for (i = 0; i < context->pending_dispatches->len; i++)
1761     {
1762       GSource *source = context->pending_dispatches->pdata[i];
1763 
1764       context->pending_dispatches->pdata[i] = NULL;
1765       g_assert (source);
1766 
1767       source->flags &= ~G_SOURCE_READY;
1768 
1769       if (!SOURCE_DESTROYED (source))
1770 	{
1771 	  gboolean was_in_call;
1772 	  gpointer user_data = NULL;
1773 	  GSourceFunc callback = NULL;
1774 	  GSourceCallbackFuncs *cb_funcs;
1775 	  gpointer cb_data;
1776 	  gboolean need_destroy;
1777 
1778 	  gboolean (*dispatch) (GSource *,
1779 				GSourceFunc,
1780 				gpointer);
1781 	  GSList current_source_link;
1782 
1783 	  dispatch = source->source_funcs->dispatch;
1784 	  cb_funcs = source->callback_funcs;
1785 	  cb_data = source->callback_data;
1786 
1787 	  if (cb_funcs)
1788 	    cb_funcs->ref (cb_data);
1789 
1790 	  if ((source->flags & G_SOURCE_CAN_RECURSE) == 0)
1791 	    block_source (source);
1792 
1793 	  was_in_call = source->flags & G_HOOK_FLAG_IN_CALL;
1794 	  source->flags |= G_HOOK_FLAG_IN_CALL;
1795 
1796 	  if (cb_funcs)
1797 	    cb_funcs->get (cb_data, source, &callback, &user_data);
1798 
1799 	  UNLOCK_CONTEXT (context);
1800 
1801 	  current->depth++;
1802 	  /* The on-stack allocation of the GSList is unconventional, but
1803 	   * we know that the lifetime of the link is bounded to this
1804 	   * function as the link is kept in a thread specific list and
1805 	   * not manipulated outside of this function and its descendants.
1806 	   * Avoiding the overhead of a g_slist_alloc() is useful as many
1807 	   * applications do little more than dispatch events.
1808 	   *
1809 	   * This is a performance hack - do not revert to g_slist_prepend()!
1810 	   */
1811 	  current_source_link.data = source;
1812 	  current_source_link.next = current->dispatching_sources;
1813 	  current->dispatching_sources = &current_source_link;
1814 	  need_destroy = ! dispatch (source,
1815 				     callback,
1816 				     user_data);
1817 	  g_assert (current->dispatching_sources == &current_source_link);
1818 	  current->dispatching_sources = current_source_link.next;
1819 	  current->depth--;
1820 
1821 	  if (cb_funcs)
1822 	    cb_funcs->unref (cb_data);
1823 
1824  	  LOCK_CONTEXT (context);
1825 
1826 	  if (!was_in_call)
1827 	    source->flags &= ~G_HOOK_FLAG_IN_CALL;
1828 
1829 	  if ((source->flags & G_SOURCE_CAN_RECURSE) == 0 &&
1830 	      !SOURCE_DESTROYED (source))
1831 	    unblock_source (source);
1832 
1833 	  /* Note: this depends on the fact that we can't switch
1834 	   * sources from one main context to another
1835 	   */
1836 	  if (need_destroy && !SOURCE_DESTROYED (source))
1837 	    {
1838 	      g_assert (source->context == context);
1839 	      g_source_destroy_internal (source, context, TRUE);
1840 	    }
1841 	}
1842 
1843       SOURCE_UNREF (source, context);
1844     }
1845 
1846   g_ptr_array_set_size (context->pending_dispatches, 0);
1847 }
1848 
1849 /* Holds context's lock */
1850 static inline GSource *
next_valid_source(GMainContext * context,GSource * source)1851 next_valid_source (GMainContext *context,
1852 		   GSource      *source)
1853 {
1854   GSource *new_source = source ? source->next : context->source_list;
1855 
1856   while (new_source)
1857     {
1858       if (!SOURCE_DESTROYED (new_source))
1859 	{
1860 	  new_source->ref_count++;
1861 	  break;
1862 	}
1863 
1864       new_source = new_source->next;
1865     }
1866 
1867   if (source)
1868     SOURCE_UNREF (source, context);
1869 
1870   return new_source;
1871 }
1872 
1873 /**
1874  * g_main_context_acquire:
1875  * @context: a #GMainContext
1876  *
1877  * Tries to become the owner of the specified context.
1878  * If some other thread is the owner of the context,
1879  * returns %FALSE immediately. Ownership is properly
1880  * recursive: the owner can require ownership again
1881  * and will release ownership when g_main_context_release()
1882  * is called as many times as g_main_context_acquire().
1883  *
1884  * You must be the owner of a context before you
1885  * can call g_main_context_prepare(), g_main_context_query(),
1886  * g_main_context_check(), g_main_context_dispatch().
1887  *
1888  * Return value: %TRUE if the operation succeeded, and
1889  *   this thread is now the owner of @context.
1890  **/
1891 gboolean
g_main_context_acquire(GMainContext * context)1892 g_main_context_acquire (GMainContext *context)
1893 {
1894 #ifdef G_THREADS_ENABLED
1895   gboolean result = FALSE;
1896   GThread *self = G_THREAD_SELF;
1897 
1898   if (context == NULL)
1899     context = g_main_context_default ();
1900 
1901   LOCK_CONTEXT (context);
1902 
1903   if (!context->owner)
1904     {
1905       context->owner = self;
1906       g_assert (context->owner_count == 0);
1907     }
1908 
1909   if (context->owner == self)
1910     {
1911       context->owner_count++;
1912       result = TRUE;
1913     }
1914 
1915   UNLOCK_CONTEXT (context);
1916 
1917   return result;
1918 #else /* !G_THREADS_ENABLED */
1919   return TRUE;
1920 #endif /* G_THREADS_ENABLED */
1921 }
1922 
1923 /**
1924  * g_main_context_release:
1925  * @context: a #GMainContext
1926  *
1927  * Releases ownership of a context previously acquired by this thread
1928  * with g_main_context_acquire(). If the context was acquired multiple
1929  * times, the ownership will be released only when g_main_context_release()
1930  * is called as many times as it was acquired.
1931  **/
1932 void
g_main_context_release(GMainContext * context)1933 g_main_context_release (GMainContext *context)
1934 {
1935 #ifdef G_THREADS_ENABLED
1936   if (context == NULL)
1937     context = g_main_context_default ();
1938 
1939   LOCK_CONTEXT (context);
1940 
1941   context->owner_count--;
1942   if (context->owner_count == 0)
1943     {
1944       context->owner = NULL;
1945 
1946       if (context->waiters)
1947 	{
1948 	  GMainWaiter *waiter = context->waiters->data;
1949 	  gboolean loop_internal_waiter =
1950 	    (waiter->mutex == g_static_mutex_get_mutex (&context->mutex));
1951 	  context->waiters = g_slist_delete_link (context->waiters,
1952 						  context->waiters);
1953 	  if (!loop_internal_waiter)
1954 	    g_mutex_lock (waiter->mutex);
1955 
1956 	  g_cond_signal (waiter->cond);
1957 
1958 	  if (!loop_internal_waiter)
1959 	    g_mutex_unlock (waiter->mutex);
1960 	}
1961     }
1962 
1963   UNLOCK_CONTEXT (context);
1964 #endif /* G_THREADS_ENABLED */
1965 }
1966 
1967 /**
1968  * g_main_context_wait:
1969  * @context: a #GMainContext
1970  * @cond: a condition variable
1971  * @mutex: a mutex, currently held
1972  *
1973  * Tries to become the owner of the specified context,
1974  * as with g_main_context_acquire(). But if another thread
1975  * is the owner, atomically drop @mutex and wait on @cond until
1976  * that owner releases ownership or until @cond is signaled, then
1977  * try again (once) to become the owner.
1978  *
1979  * Return value: %TRUE if the operation succeeded, and
1980  *   this thread is now the owner of @context.
1981  **/
1982 gboolean
g_main_context_wait(GMainContext * context,GCond * cond,GMutex * mutex)1983 g_main_context_wait (GMainContext *context,
1984 		     GCond        *cond,
1985 		     GMutex       *mutex)
1986 {
1987 #ifdef G_THREADS_ENABLED
1988   gboolean result = FALSE;
1989   GThread *self = G_THREAD_SELF;
1990   gboolean loop_internal_waiter;
1991 
1992   if (context == NULL)
1993     context = g_main_context_default ();
1994 
1995   loop_internal_waiter = (mutex == g_static_mutex_get_mutex (&context->mutex));
1996 
1997   if (!loop_internal_waiter)
1998     LOCK_CONTEXT (context);
1999 
2000   if (context->owner && context->owner != self)
2001     {
2002       GMainWaiter waiter;
2003 
2004       waiter.cond = cond;
2005       waiter.mutex = mutex;
2006 
2007       context->waiters = g_slist_append (context->waiters, &waiter);
2008 
2009       if (!loop_internal_waiter)
2010 	UNLOCK_CONTEXT (context);
2011       g_cond_wait (cond, mutex);
2012       if (!loop_internal_waiter)
2013 	LOCK_CONTEXT (context);
2014 
2015       context->waiters = g_slist_remove (context->waiters, &waiter);
2016     }
2017 
2018   if (!context->owner)
2019     {
2020       context->owner = self;
2021       g_assert (context->owner_count == 0);
2022     }
2023 
2024   if (context->owner == self)
2025     {
2026       context->owner_count++;
2027       result = TRUE;
2028     }
2029 
2030   if (!loop_internal_waiter)
2031     UNLOCK_CONTEXT (context);
2032 
2033   return result;
2034 #else /* !G_THREADS_ENABLED */
2035   return TRUE;
2036 #endif /* G_THREADS_ENABLED */
2037 }
2038 
2039 /**
2040  * g_main_context_prepare:
2041  * @context: a #GMainContext
2042  * @priority: location to store priority of highest priority
2043  *            source already ready.
2044  *
2045  * Prepares to poll sources within a main loop. The resulting information
2046  * for polling is determined by calling g_main_context_query ().
2047  *
2048  * Return value: %TRUE if some source is ready to be dispatched
2049  *               prior to polling.
2050  **/
2051 gboolean
g_main_context_prepare(GMainContext * context,gint * priority)2052 g_main_context_prepare (GMainContext *context,
2053 			gint         *priority)
2054 {
2055   gint i;
2056   gint n_ready = 0;
2057   gint current_priority = G_MAXINT;
2058   GSource *source;
2059 
2060   if (context == NULL)
2061     context = g_main_context_default ();
2062 
2063   LOCK_CONTEXT (context);
2064 
2065   context->time_is_current = FALSE;
2066 
2067   if (context->in_check_or_prepare)
2068     {
2069       g_warning ("g_main_context_prepare() called recursively from within a source's check() or "
2070 		 "prepare() member.");
2071       UNLOCK_CONTEXT (context);
2072       return FALSE;
2073     }
2074 
2075 #ifdef G_THREADS_ENABLED
2076   if (context->poll_waiting)
2077     {
2078       g_warning("g_main_context_prepare(): main loop already active in another thread");
2079       UNLOCK_CONTEXT (context);
2080       return FALSE;
2081     }
2082 
2083   context->poll_waiting = TRUE;
2084 #endif /* G_THREADS_ENABLED */
2085 
2086 #if 0
2087   /* If recursing, finish up current dispatch, before starting over */
2088   if (context->pending_dispatches)
2089     {
2090       if (dispatch)
2091 	g_main_dispatch (context, &current_time);
2092 
2093       UNLOCK_CONTEXT (context);
2094       return TRUE;
2095     }
2096 #endif
2097 
2098   /* If recursing, clear list of pending dispatches */
2099 
2100   for (i = 0; i < context->pending_dispatches->len; i++)
2101     {
2102       if (context->pending_dispatches->pdata[i])
2103 	SOURCE_UNREF ((GSource *)context->pending_dispatches->pdata[i], context);
2104     }
2105   g_ptr_array_set_size (context->pending_dispatches, 0);
2106 
2107   /* Prepare all sources */
2108 
2109   context->timeout = -1;
2110 
2111   source = next_valid_source (context, NULL);
2112   while (source)
2113     {
2114       gint source_timeout = -1;
2115 
2116       if ((n_ready > 0) && (source->priority > current_priority))
2117 	{
2118 	  SOURCE_UNREF (source, context);
2119 	  break;
2120 	}
2121       if (SOURCE_BLOCKED (source))
2122 	goto next;
2123 
2124       if (!(source->flags & G_SOURCE_READY))
2125 	{
2126 	  gboolean result;
2127 	  gboolean (*prepare)  (GSource  *source,
2128 				gint     *timeout);
2129 
2130 	  prepare = source->source_funcs->prepare;
2131 	  context->in_check_or_prepare++;
2132 	  UNLOCK_CONTEXT (context);
2133 
2134 	  result = (*prepare) (source, &source_timeout);
2135 
2136 	  LOCK_CONTEXT (context);
2137 	  context->in_check_or_prepare--;
2138 
2139 	  if (result)
2140 	    source->flags |= G_SOURCE_READY;
2141 	}
2142 
2143       if (source->flags & G_SOURCE_READY)
2144 	{
2145 	  n_ready++;
2146 	  current_priority = source->priority;
2147 	  context->timeout = 0;
2148 	}
2149 
2150       if (source_timeout >= 0)
2151 	{
2152 	  if (context->timeout < 0)
2153 	    context->timeout = source_timeout;
2154 	  else
2155 	    context->timeout = MIN (context->timeout, source_timeout);
2156 	}
2157 
2158     next:
2159       source = next_valid_source (context, source);
2160     }
2161 
2162   UNLOCK_CONTEXT (context);
2163 
2164   if (priority)
2165     *priority = current_priority;
2166 
2167   return (n_ready > 0);
2168 }
2169 
2170 /**
2171  * g_main_context_query:
2172  * @context: a #GMainContext
2173  * @max_priority: maximum priority source to check
2174  * @timeout_: location to store timeout to be used in polling
2175  * @fds: location to store #GPollFD records that need to be polled.
2176  * @n_fds: length of @fds.
2177  *
2178  * Determines information necessary to poll this main loop.
2179  *
2180  * Return value: the number of records actually stored in @fds,
2181  *   or, if more than @n_fds records need to be stored, the number
2182  *   of records that need to be stored.
2183  **/
2184 gint
g_main_context_query(GMainContext * context,gint max_priority,gint * timeout,GPollFD * fds,gint n_fds)2185 g_main_context_query (GMainContext *context,
2186 		      gint          max_priority,
2187 		      gint         *timeout,
2188 		      GPollFD      *fds,
2189 		      gint          n_fds)
2190 {
2191   gint n_poll;
2192   GPollRec *pollrec;
2193 
2194   LOCK_CONTEXT (context);
2195 
2196   pollrec = context->poll_records;
2197   n_poll = 0;
2198   while (pollrec && max_priority >= pollrec->priority)
2199     {
2200       /* We need to include entries with fd->events == 0 in the array because
2201        * otherwise if the application changes fd->events behind our back and
2202        * makes it non-zero, we'll be out of sync when we check the fds[] array.
2203        * (Changing fd->events after adding an FD wasn't an anticipated use of
2204        * this API, but it occurs in practice.) */
2205       if (n_poll < n_fds)
2206 	{
2207 	  fds[n_poll].fd = pollrec->fd->fd;
2208 	  /* In direct contradiction to the Unix98 spec, IRIX runs into
2209 	   * difficulty if you pass in POLLERR, POLLHUP or POLLNVAL
2210 	   * flags in the events field of the pollfd while it should
2211 	   * just ignoring them. So we mask them out here.
2212 	   */
2213 	  fds[n_poll].events = pollrec->fd->events & ~(G_IO_ERR|G_IO_HUP|G_IO_NVAL);
2214 	  fds[n_poll].revents = 0;
2215 	}
2216 
2217       pollrec = pollrec->next;
2218       n_poll++;
2219     }
2220 
2221 #ifdef G_THREADS_ENABLED
2222   context->poll_changed = FALSE;
2223 #endif
2224 
2225   if (timeout)
2226     {
2227       *timeout = context->timeout;
2228       if (*timeout != 0)
2229 	context->time_is_current = FALSE;
2230     }
2231 
2232   UNLOCK_CONTEXT (context);
2233 
2234   return n_poll;
2235 }
2236 
2237 /**
2238  * g_main_context_check:
2239  * @context: a #GMainContext
2240  * @max_priority: the maximum numerical priority of sources to check
2241  * @fds: array of #GPollFD's that was passed to the last call to
2242  *       g_main_context_query()
2243  * @n_fds: return value of g_main_context_query()
2244  *
2245  * Passes the results of polling back to the main loop.
2246  *
2247  * Return value: %TRUE if some sources are ready to be dispatched.
2248  **/
2249 gboolean
g_main_context_check(GMainContext * context,gint max_priority,GPollFD * fds,gint n_fds)2250 g_main_context_check (GMainContext *context,
2251 		      gint          max_priority,
2252 		      GPollFD      *fds,
2253 		      gint          n_fds)
2254 {
2255   GSource *source;
2256   GPollRec *pollrec;
2257   gint n_ready = 0;
2258   gint i;
2259 
2260   LOCK_CONTEXT (context);
2261 
2262   if (context->in_check_or_prepare)
2263     {
2264       g_warning ("g_main_context_check() called recursively from within a source's check() or "
2265 		 "prepare() member.");
2266       UNLOCK_CONTEXT (context);
2267       return FALSE;
2268     }
2269 
2270 #ifdef G_THREADS_ENABLED
2271   if (!context->poll_waiting)
2272     {
2273 #ifndef G_OS_WIN32
2274       gchar a;
2275       read (context->wake_up_pipe[0], &a, 1);
2276 #endif
2277     }
2278   else
2279     context->poll_waiting = FALSE;
2280 
2281   /* If the set of poll file descriptors changed, bail out
2282    * and let the main loop rerun
2283    */
2284   if (context->poll_changed)
2285     {
2286       UNLOCK_CONTEXT (context);
2287       return FALSE;
2288     }
2289 #endif /* G_THREADS_ENABLED */
2290 
2291   pollrec = context->poll_records;
2292   i = 0;
2293   while (i < n_fds)
2294     {
2295       if (pollrec->fd->events)
2296 	pollrec->fd->revents = fds[i].revents;
2297 
2298       pollrec = pollrec->next;
2299       i++;
2300     }
2301 
2302   source = next_valid_source (context, NULL);
2303   while (source)
2304     {
2305       if ((n_ready > 0) && (source->priority > max_priority))
2306 	{
2307 	  SOURCE_UNREF (source, context);
2308 	  break;
2309 	}
2310       if (SOURCE_BLOCKED (source))
2311 	goto next;
2312 
2313       if (!(source->flags & G_SOURCE_READY))
2314 	{
2315 	  gboolean result;
2316 	  gboolean (*check) (GSource  *source);
2317 
2318 	  check = source->source_funcs->check;
2319 
2320 	  context->in_check_or_prepare++;
2321 	  UNLOCK_CONTEXT (context);
2322 
2323 	  result = (*check) (source);
2324 
2325 	  LOCK_CONTEXT (context);
2326 	  context->in_check_or_prepare--;
2327 
2328 	  if (result)
2329 	    source->flags |= G_SOURCE_READY;
2330 	}
2331 
2332       if (source->flags & G_SOURCE_READY)
2333 	{
2334 	  source->ref_count++;
2335 	  g_ptr_array_add (context->pending_dispatches, source);
2336 
2337 	  n_ready++;
2338 
2339           /* never dispatch sources with less priority than the first
2340            * one we choose to dispatch
2341            */
2342           max_priority = source->priority;
2343 	}
2344 
2345     next:
2346       source = next_valid_source (context, source);
2347     }
2348 
2349   UNLOCK_CONTEXT (context);
2350 
2351   return n_ready > 0;
2352 }
2353 
2354 /**
2355  * g_main_context_dispatch:
2356  * @context: a #GMainContext
2357  *
2358  * Dispatches all pending sources.
2359  **/
2360 void
g_main_context_dispatch(GMainContext * context)2361 g_main_context_dispatch (GMainContext *context)
2362 {
2363   LOCK_CONTEXT (context);
2364 
2365   if (context->pending_dispatches->len > 0)
2366     {
2367       g_main_dispatch (context);
2368     }
2369 
2370   UNLOCK_CONTEXT (context);
2371 }
2372 
2373 /* HOLDS context lock */
2374 static gboolean
g_main_context_iterate(GMainContext * context,gboolean block,gboolean dispatch,GThread * self)2375 g_main_context_iterate (GMainContext *context,
2376 			gboolean      block,
2377 			gboolean      dispatch,
2378 			GThread      *self)
2379 {
2380   gint max_priority;
2381   gint timeout;
2382   gboolean some_ready;
2383   gint nfds, allocated_nfds;
2384   GPollFD *fds = NULL;
2385 
2386   UNLOCK_CONTEXT (context);
2387 
2388 #ifdef G_THREADS_ENABLED
2389   if (!g_main_context_acquire (context))
2390     {
2391       gboolean got_ownership;
2392 
2393       LOCK_CONTEXT (context);
2394 
2395       g_return_val_if_fail (g_thread_supported (), FALSE);
2396 
2397       if (!block)
2398 	return FALSE;
2399 
2400       if (!context->cond)
2401 	context->cond = g_cond_new ();
2402 
2403       got_ownership = g_main_context_wait (context,
2404 					   context->cond,
2405 					   g_static_mutex_get_mutex (&context->mutex));
2406 
2407       if (!got_ownership)
2408 	return FALSE;
2409     }
2410   else
2411     LOCK_CONTEXT (context);
2412 #endif /* G_THREADS_ENABLED */
2413 
2414   if (!context->cached_poll_array)
2415     {
2416       context->cached_poll_array_size = context->n_poll_records;
2417       context->cached_poll_array = g_new (GPollFD, context->n_poll_records);
2418     }
2419 
2420   allocated_nfds = context->cached_poll_array_size;
2421   fds = context->cached_poll_array;
2422 
2423   UNLOCK_CONTEXT (context);
2424 
2425   g_main_context_prepare (context, &max_priority);
2426 
2427   while ((nfds = g_main_context_query (context, max_priority, &timeout, fds,
2428 				       allocated_nfds)) > allocated_nfds)
2429     {
2430       LOCK_CONTEXT (context);
2431       g_free (fds);
2432       context->cached_poll_array_size = allocated_nfds = nfds;
2433       context->cached_poll_array = fds = g_new (GPollFD, nfds);
2434       UNLOCK_CONTEXT (context);
2435     }
2436 
2437   if (!block)
2438     timeout = 0;
2439 
2440   g_main_context_poll (context, timeout, max_priority, fds, nfds);
2441 
2442   some_ready = g_main_context_check (context, max_priority, fds, nfds);
2443 
2444   if (dispatch)
2445     g_main_context_dispatch (context);
2446 
2447 #ifdef G_THREADS_ENABLED
2448   g_main_context_release (context);
2449 #endif /* G_THREADS_ENABLED */
2450 
2451   LOCK_CONTEXT (context);
2452 
2453   return some_ready;
2454 }
2455 
2456 /**
2457  * g_main_context_pending:
2458  * @context: a #GMainContext (if %NULL, the default context will be used)
2459  *
2460  * Checks if any sources have pending events for the given context.
2461  *
2462  * Return value: %TRUE if events are pending.
2463  **/
2464 gboolean
g_main_context_pending(GMainContext * context)2465 g_main_context_pending (GMainContext *context)
2466 {
2467   gboolean retval;
2468 
2469   if (!context)
2470     context = g_main_context_default();
2471 
2472   LOCK_CONTEXT (context);
2473   retval = g_main_context_iterate (context, FALSE, FALSE, G_THREAD_SELF);
2474   UNLOCK_CONTEXT (context);
2475 
2476   return retval;
2477 }
2478 
2479 /**
2480  * g_main_context_iteration:
2481  * @context: a #GMainContext (if %NULL, the default context will be used)
2482  * @may_block: whether the call may block.
2483  *
2484  * Runs a single iteration for the given main loop. This involves
2485  * checking to see if any event sources are ready to be processed,
2486  * then if no events sources are ready and @may_block is %TRUE, waiting
2487  * for a source to become ready, then dispatching the highest priority
2488  * events sources that are ready. Otherwise, if @may_block is %FALSE
2489  * sources are not waited to become ready, only those highest priority
2490  * events sources will be dispatched (if any), that are ready at this
2491  * given moment without further waiting.
2492  *
2493  * Note that even when @may_block is %TRUE, it is still possible for
2494  * g_main_context_iteration() to return %FALSE, since the the wait may
2495  * be interrupted for other reasons than an event source becoming ready.
2496  *
2497  * Return value: %TRUE if events were dispatched.
2498  **/
2499 gboolean
g_main_context_iteration(GMainContext * context,gboolean may_block)2500 g_main_context_iteration (GMainContext *context, gboolean may_block)
2501 {
2502   gboolean retval;
2503 
2504   if (!context)
2505     context = g_main_context_default();
2506 
2507   LOCK_CONTEXT (context);
2508   retval = g_main_context_iterate (context, may_block, TRUE, G_THREAD_SELF);
2509   UNLOCK_CONTEXT (context);
2510 
2511   return retval;
2512 }
2513 
2514 /**
2515  * g_main_loop_new:
2516  * @context: a #GMainContext  (if %NULL, the default context will be used).
2517  * @is_running: set to %TRUE to indicate that the loop is running. This
2518  * is not very important since calling g_main_loop_run() will set this to
2519  * %TRUE anyway.
2520  *
2521  * Creates a new #GMainLoop structure.
2522  *
2523  * Return value: a new #GMainLoop.
2524  **/
2525 GMainLoop *
g_main_loop_new(GMainContext * context,gboolean is_running)2526 g_main_loop_new (GMainContext *context,
2527 		 gboolean      is_running)
2528 {
2529   GMainLoop *loop;
2530 
2531   if (!context)
2532     context = g_main_context_default();
2533 
2534   g_main_context_ref (context);
2535 
2536   loop = g_new0 (GMainLoop, 1);
2537   loop->context = context;
2538   loop->is_running = is_running != FALSE;
2539   loop->ref_count = 1;
2540 
2541   return loop;
2542 }
2543 
2544 /**
2545  * g_main_loop_ref:
2546  * @loop: a #GMainLoop
2547  *
2548  * Increases the reference count on a #GMainLoop object by one.
2549  *
2550  * Return value: @loop
2551  **/
2552 GMainLoop *
g_main_loop_ref(GMainLoop * loop)2553 g_main_loop_ref (GMainLoop *loop)
2554 {
2555   g_return_val_if_fail (loop != NULL, NULL);
2556   g_return_val_if_fail (g_atomic_int_get (&loop->ref_count) > 0, NULL);
2557 
2558   g_atomic_int_inc (&loop->ref_count);
2559 
2560   return loop;
2561 }
2562 
2563 /**
2564  * g_main_loop_unref:
2565  * @loop: a #GMainLoop
2566  *
2567  * Decreases the reference count on a #GMainLoop object by one. If
2568  * the result is zero, free the loop and free all associated memory.
2569  **/
2570 void
g_main_loop_unref(GMainLoop * loop)2571 g_main_loop_unref (GMainLoop *loop)
2572 {
2573   g_return_if_fail (loop != NULL);
2574   g_return_if_fail (g_atomic_int_get (&loop->ref_count) > 0);
2575 
2576   if (!g_atomic_int_dec_and_test (&loop->ref_count))
2577     return;
2578 
2579   g_main_context_unref (loop->context);
2580   g_free (loop);
2581 }
2582 
2583 /**
2584  * g_main_loop_run:
2585  * @loop: a #GMainLoop
2586  *
2587  * Runs a main loop until g_main_loop_quit() is called on the loop.
2588  * If this is called for the thread of the loop's #GMainContext,
2589  * it will process events from the loop, otherwise it will
2590  * simply wait.
2591  **/
2592 void
g_main_loop_run(GMainLoop * loop)2593 g_main_loop_run (GMainLoop *loop)
2594 {
2595   GThread *self = G_THREAD_SELF;
2596 
2597   g_return_if_fail (loop != NULL);
2598   g_return_if_fail (g_atomic_int_get (&loop->ref_count) > 0);
2599 
2600 #ifdef G_THREADS_ENABLED
2601   if (!g_main_context_acquire (loop->context))
2602     {
2603       gboolean got_ownership = FALSE;
2604 
2605       /* Another thread owns this context */
2606       if (!g_thread_supported ())
2607 	{
2608 	  g_warning ("g_main_loop_run() was called from second thread but "
2609 		     "g_thread_init() was never called.");
2610 	  return;
2611 	}
2612 
2613       LOCK_CONTEXT (loop->context);
2614 
2615       g_atomic_int_inc (&loop->ref_count);
2616 
2617       if (!loop->is_running)
2618 	loop->is_running = TRUE;
2619 
2620       if (!loop->context->cond)
2621 	loop->context->cond = g_cond_new ();
2622 
2623       while (loop->is_running && !got_ownership)
2624 	got_ownership = g_main_context_wait (loop->context,
2625 					     loop->context->cond,
2626 					     g_static_mutex_get_mutex (&loop->context->mutex));
2627 
2628       if (!loop->is_running)
2629 	{
2630 	  UNLOCK_CONTEXT (loop->context);
2631 	  if (got_ownership)
2632 	    g_main_context_release (loop->context);
2633 	  g_main_loop_unref (loop);
2634 	  return;
2635 	}
2636 
2637       g_assert (got_ownership);
2638     }
2639   else
2640     LOCK_CONTEXT (loop->context);
2641 #endif /* G_THREADS_ENABLED */
2642 
2643   if (loop->context->in_check_or_prepare)
2644     {
2645       g_warning ("g_main_loop_run(): called recursively from within a source's "
2646 		 "check() or prepare() member, iteration not possible.");
2647       return;
2648     }
2649 
2650   g_atomic_int_inc (&loop->ref_count);
2651   loop->is_running = TRUE;
2652   while (loop->is_running)
2653     g_main_context_iterate (loop->context, TRUE, TRUE, self);
2654 
2655   UNLOCK_CONTEXT (loop->context);
2656 
2657 #ifdef G_THREADS_ENABLED
2658   g_main_context_release (loop->context);
2659 #endif /* G_THREADS_ENABLED */
2660 
2661   g_main_loop_unref (loop);
2662 }
2663 
2664 /**
2665  * g_main_loop_quit:
2666  * @loop: a #GMainLoop
2667  *
2668  * Stops a #GMainLoop from running. Any calls to g_main_loop_run()
2669  * for the loop will return.
2670  *
2671  * Note that sources that have already been dispatched when
2672  * g_main_loop_quit() is called will still be executed.
2673  **/
2674 void
g_main_loop_quit(GMainLoop * loop)2675 g_main_loop_quit (GMainLoop *loop)
2676 {
2677   g_return_if_fail (loop != NULL);
2678   g_return_if_fail (g_atomic_int_get (&loop->ref_count) > 0);
2679 
2680   LOCK_CONTEXT (loop->context);
2681   loop->is_running = FALSE;
2682   g_main_context_wakeup_unlocked (loop->context);
2683 
2684 #ifdef G_THREADS_ENABLED
2685   if (loop->context->cond)
2686     g_cond_broadcast (loop->context->cond);
2687 #endif /* G_THREADS_ENABLED */
2688 
2689   UNLOCK_CONTEXT (loop->context);
2690 }
2691 
2692 /**
2693  * g_main_loop_is_running:
2694  * @loop: a #GMainLoop.
2695  *
2696  * Checks to see if the main loop is currently being run via g_main_loop_run().
2697  *
2698  * Return value: %TRUE if the mainloop is currently being run.
2699  **/
2700 gboolean
g_main_loop_is_running(GMainLoop * loop)2701 g_main_loop_is_running (GMainLoop *loop)
2702 {
2703   g_return_val_if_fail (loop != NULL, FALSE);
2704   g_return_val_if_fail (g_atomic_int_get (&loop->ref_count) > 0, FALSE);
2705 
2706   return loop->is_running;
2707 }
2708 
2709 /**
2710  * g_main_loop_get_context:
2711  * @loop: a #GMainLoop.
2712  *
2713  * Returns the #GMainContext of @loop.
2714  *
2715  * Return value: the #GMainContext of @loop
2716  **/
2717 GMainContext *
g_main_loop_get_context(GMainLoop * loop)2718 g_main_loop_get_context (GMainLoop *loop)
2719 {
2720   g_return_val_if_fail (loop != NULL, NULL);
2721   g_return_val_if_fail (g_atomic_int_get (&loop->ref_count) > 0, NULL);
2722 
2723   return loop->context;
2724 }
2725 
2726 /* HOLDS: context's lock */
2727 static void
g_main_context_poll(GMainContext * context,gint timeout,gint priority,GPollFD * fds,gint n_fds)2728 g_main_context_poll (GMainContext *context,
2729 		     gint          timeout,
2730 		     gint          priority,
2731 		     GPollFD      *fds,
2732 		     gint          n_fds)
2733 {
2734 #ifdef  G_MAIN_POLL_DEBUG
2735   GTimer *poll_timer;
2736   GPollRec *pollrec;
2737   gint i;
2738 #endif
2739 
2740   GPollFunc poll_func;
2741 
2742   if (n_fds || timeout != 0)
2743     {
2744 #ifdef	G_MAIN_POLL_DEBUG
2745       if (_g_main_poll_debug)
2746 	{
2747 	  g_print ("polling context=%p n=%d timeout=%d\n",
2748 		   context, n_fds, timeout);
2749 	  poll_timer = g_timer_new ();
2750 	}
2751 #endif
2752 
2753       LOCK_CONTEXT (context);
2754 
2755       poll_func = context->poll_func;
2756 
2757       UNLOCK_CONTEXT (context);
2758       if ((*poll_func) (fds, n_fds, timeout) < 0 && errno != EINTR)
2759 	{
2760 #ifndef G_OS_WIN32
2761 	  g_warning ("poll(2) failed due to: %s.",
2762 		     g_strerror (errno));
2763 #else
2764 	  /* If g_poll () returns -1, it has already called g_warning() */
2765 #endif
2766 	}
2767 
2768 #ifdef	G_MAIN_POLL_DEBUG
2769       if (_g_main_poll_debug)
2770 	{
2771 	  LOCK_CONTEXT (context);
2772 
2773 	  g_print ("g_main_poll(%d) timeout: %d - elapsed %12.10f seconds",
2774 		   n_fds,
2775 		   timeout,
2776 		   g_timer_elapsed (poll_timer, NULL));
2777 	  g_timer_destroy (poll_timer);
2778 	  pollrec = context->poll_records;
2779 
2780 	  while (pollrec != NULL)
2781 	    {
2782 	      i = 0;
2783 	      while (i < n_fds)
2784 		{
2785 		  if (fds[i].fd == pollrec->fd->fd &&
2786 		      pollrec->fd->events &&
2787 		      fds[i].revents)
2788 		    {
2789 		      g_print (" [" G_POLLFD_FORMAT " :", fds[i].fd);
2790 		      if (fds[i].revents & G_IO_IN)
2791 			g_print ("i");
2792 		      if (fds[i].revents & G_IO_OUT)
2793 			g_print ("o");
2794 		      if (fds[i].revents & G_IO_PRI)
2795 			g_print ("p");
2796 		      if (fds[i].revents & G_IO_ERR)
2797 			g_print ("e");
2798 		      if (fds[i].revents & G_IO_HUP)
2799 			g_print ("h");
2800 		      if (fds[i].revents & G_IO_NVAL)
2801 			g_print ("n");
2802 		      g_print ("]");
2803 		    }
2804 		  i++;
2805 		}
2806 	      pollrec = pollrec->next;
2807 	    }
2808 	  g_print ("\n");
2809 
2810 	  UNLOCK_CONTEXT (context);
2811 	}
2812 #endif
2813     } /* if (n_fds || timeout != 0) */
2814 }
2815 
2816 /**
2817  * g_main_context_add_poll:
2818  * @context: a #GMainContext (or %NULL for the default context)
2819  * @fd: a #GPollFD structure holding information about a file
2820  *      descriptor to watch.
2821  * @priority: the priority for this file descriptor which should be
2822  *      the same as the priority used for g_source_attach() to ensure that the
2823  *      file descriptor is polled whenever the results may be needed.
2824  *
2825  * Adds a file descriptor to the set of file descriptors polled for
2826  * this context. This will very seldomly be used directly. Instead
2827  * a typical event source will use g_source_add_poll() instead.
2828  **/
2829 void
g_main_context_add_poll(GMainContext * context,GPollFD * fd,gint priority)2830 g_main_context_add_poll (GMainContext *context,
2831 			 GPollFD      *fd,
2832 			 gint          priority)
2833 {
2834   if (!context)
2835     context = g_main_context_default ();
2836 
2837   g_return_if_fail (g_atomic_int_get (&context->ref_count) > 0);
2838   g_return_if_fail (fd);
2839 
2840   LOCK_CONTEXT (context);
2841   g_main_context_add_poll_unlocked (context, priority, fd);
2842   UNLOCK_CONTEXT (context);
2843 }
2844 
2845 /* HOLDS: main_loop_lock */
2846 static void
g_main_context_add_poll_unlocked(GMainContext * context,gint priority,GPollFD * fd)2847 g_main_context_add_poll_unlocked (GMainContext *context,
2848 				  gint          priority,
2849 				  GPollFD      *fd)
2850 {
2851   GPollRec *lastrec, *pollrec;
2852   GPollRec *newrec = g_slice_new (GPollRec);
2853 
2854   /* This file descriptor may be checked before we ever poll */
2855   fd->revents = 0;
2856   newrec->fd = fd;
2857   newrec->priority = priority;
2858 
2859   lastrec = NULL;
2860   pollrec = context->poll_records;
2861   while (pollrec && priority >= pollrec->priority)
2862     {
2863       lastrec = pollrec;
2864       pollrec = pollrec->next;
2865     }
2866 
2867   if (lastrec)
2868     lastrec->next = newrec;
2869   else
2870     context->poll_records = newrec;
2871 
2872   newrec->next = pollrec;
2873 
2874   context->n_poll_records++;
2875 
2876 #ifdef G_THREADS_ENABLED
2877   context->poll_changed = TRUE;
2878 
2879   /* Now wake up the main loop if it is waiting in the poll() */
2880   g_main_context_wakeup_unlocked (context);
2881 #endif
2882 }
2883 
2884 /**
2885  * g_main_context_remove_poll:
2886  * @context:a #GMainContext
2887  * @fd: a #GPollFD descriptor previously added with g_main_context_add_poll()
2888  *
2889  * Removes file descriptor from the set of file descriptors to be
2890  * polled for a particular context.
2891  **/
2892 void
g_main_context_remove_poll(GMainContext * context,GPollFD * fd)2893 g_main_context_remove_poll (GMainContext *context,
2894 			    GPollFD      *fd)
2895 {
2896   if (!context)
2897     context = g_main_context_default ();
2898 
2899   g_return_if_fail (g_atomic_int_get (&context->ref_count) > 0);
2900   g_return_if_fail (fd);
2901 
2902   LOCK_CONTEXT (context);
2903   g_main_context_remove_poll_unlocked (context, fd);
2904   UNLOCK_CONTEXT (context);
2905 }
2906 
2907 static void
g_main_context_remove_poll_unlocked(GMainContext * context,GPollFD * fd)2908 g_main_context_remove_poll_unlocked (GMainContext *context,
2909 				     GPollFD      *fd)
2910 {
2911   GPollRec *pollrec, *lastrec;
2912 
2913   lastrec = NULL;
2914   pollrec = context->poll_records;
2915 
2916   while (pollrec)
2917     {
2918       if (pollrec->fd == fd)
2919 	{
2920 	  if (lastrec != NULL)
2921 	    lastrec->next = pollrec->next;
2922 	  else
2923 	    context->poll_records = pollrec->next;
2924 
2925 	  g_slice_free (GPollRec, pollrec);
2926 
2927 	  context->n_poll_records--;
2928 	  break;
2929 	}
2930       lastrec = pollrec;
2931       pollrec = pollrec->next;
2932     }
2933 
2934 #ifdef G_THREADS_ENABLED
2935   context->poll_changed = TRUE;
2936 
2937   /* Now wake up the main loop if it is waiting in the poll() */
2938   g_main_context_wakeup_unlocked (context);
2939 #endif
2940 }
2941 
2942 /**
2943  * g_source_get_current_time:
2944  * @source:  a #GSource
2945  * @timeval: #GTimeVal structure in which to store current time.
2946  *
2947  * Gets the "current time" to be used when checking
2948  * this source. The advantage of calling this function over
2949  * calling g_get_current_time() directly is that when
2950  * checking multiple sources, GLib can cache a single value
2951  * instead of having to repeatedly get the system time.
2952  **/
2953 void
g_source_get_current_time(GSource * source,GTimeVal * timeval)2954 g_source_get_current_time (GSource  *source,
2955 			   GTimeVal *timeval)
2956 {
2957   GMainContext *context;
2958 
2959   g_return_if_fail (source->context != NULL);
2960 
2961   context = source->context;
2962 
2963   LOCK_CONTEXT (context);
2964 
2965   if (!context->time_is_current)
2966     {
2967       g_get_current_time (&context->current_time);
2968       context->time_is_current = TRUE;
2969     }
2970 
2971   *timeval = context->current_time;
2972 
2973   UNLOCK_CONTEXT (context);
2974 }
2975 
2976 /**
2977  * g_main_context_set_poll_func:
2978  * @context: a #GMainContext
2979  * @func: the function to call to poll all file descriptors
2980  *
2981  * Sets the function to use to handle polling of file descriptors. It
2982  * will be used instead of the poll() system call
2983  * (or GLib's replacement function, which is used where
2984  * poll() isn't available).
2985  *
2986  * This function could possibly be used to integrate the GLib event
2987  * loop with an external event loop.
2988  **/
2989 void
g_main_context_set_poll_func(GMainContext * context,GPollFunc func)2990 g_main_context_set_poll_func (GMainContext *context,
2991 			      GPollFunc     func)
2992 {
2993   if (!context)
2994     context = g_main_context_default ();
2995 
2996   g_return_if_fail (g_atomic_int_get (&context->ref_count) > 0);
2997 
2998   LOCK_CONTEXT (context);
2999 
3000   if (func)
3001     context->poll_func = func;
3002   else
3003     context->poll_func = g_poll;
3004 
3005   UNLOCK_CONTEXT (context);
3006 }
3007 
3008 /**
3009  * g_main_context_get_poll_func:
3010  * @context: a #GMainContext
3011  *
3012  * Gets the poll function set by g_main_context_set_poll_func().
3013  *
3014  * Return value: the poll function
3015  **/
3016 GPollFunc
g_main_context_get_poll_func(GMainContext * context)3017 g_main_context_get_poll_func (GMainContext *context)
3018 {
3019   GPollFunc result;
3020 
3021   if (!context)
3022     context = g_main_context_default ();
3023 
3024   g_return_val_if_fail (g_atomic_int_get (&context->ref_count) > 0, NULL);
3025 
3026   LOCK_CONTEXT (context);
3027   result = context->poll_func;
3028   UNLOCK_CONTEXT (context);
3029 
3030   return result;
3031 }
3032 
3033 /* HOLDS: context's lock */
3034 /* Wake the main loop up from a poll() */
3035 static void
g_main_context_wakeup_unlocked(GMainContext * context)3036 g_main_context_wakeup_unlocked (GMainContext *context)
3037 {
3038 #ifdef G_THREADS_ENABLED
3039   if (g_thread_supported() && context->poll_waiting)
3040     {
3041       context->poll_waiting = FALSE;
3042 #ifndef G_OS_WIN32
3043       write (context->wake_up_pipe[1], "A", 1);
3044 #else
3045       ReleaseSemaphore (context->wake_up_semaphore, 1, NULL);
3046 #endif
3047     }
3048 #endif
3049 }
3050 
3051 /**
3052  * g_main_context_wakeup:
3053  * @context: a #GMainContext
3054  *
3055  * If @context is currently waiting in a poll(), interrupt
3056  * the poll(), and continue the iteration process.
3057  **/
3058 void
g_main_context_wakeup(GMainContext * context)3059 g_main_context_wakeup (GMainContext *context)
3060 {
3061   if (!context)
3062     context = g_main_context_default ();
3063 
3064   g_return_if_fail (g_atomic_int_get (&context->ref_count) > 0);
3065 
3066   LOCK_CONTEXT (context);
3067   g_main_context_wakeup_unlocked (context);
3068   UNLOCK_CONTEXT (context);
3069 }
3070 
3071 /**
3072  * g_main_context_is_owner:
3073  * @context: a #GMainContext
3074  *
3075  * Determines whether this thread holds the (recursive)
3076  * ownership of this #GMaincontext. This is useful to
3077  * know before waiting on another thread that may be
3078  * blocking to get ownership of @context.
3079  *
3080  * Returns: %TRUE if current thread is owner of @context.
3081  *
3082  * Since: 2.10
3083  **/
3084 gboolean
g_main_context_is_owner(GMainContext * context)3085 g_main_context_is_owner (GMainContext *context)
3086 {
3087   gboolean is_owner;
3088 
3089   if (!context)
3090     context = g_main_context_default ();
3091 
3092 #ifdef G_THREADS_ENABLED
3093   LOCK_CONTEXT (context);
3094   is_owner = context->owner == G_THREAD_SELF;
3095   UNLOCK_CONTEXT (context);
3096 #else
3097   is_owner = TRUE;
3098 #endif
3099 
3100   return is_owner;
3101 }
3102 
3103 /* Timeouts */
3104 
3105 static void
g_timeout_set_expiration(GTimeoutSource * timeout_source,GTimeVal * current_time)3106 g_timeout_set_expiration (GTimeoutSource *timeout_source,
3107 			  GTimeVal       *current_time)
3108 {
3109   guint seconds = timeout_source->interval / 1000;
3110   guint msecs = timeout_source->interval - seconds * 1000;
3111 
3112   timeout_source->expiration.tv_sec = current_time->tv_sec + seconds;
3113   timeout_source->expiration.tv_usec = current_time->tv_usec + msecs * 1000;
3114   if (timeout_source->expiration.tv_usec >= 1000000)
3115     {
3116       timeout_source->expiration.tv_usec -= 1000000;
3117       timeout_source->expiration.tv_sec++;
3118     }
3119   if (timer_perturb==-1)
3120     {
3121       /*
3122        * we want a per machine/session unique 'random' value; try the dbus
3123        * address first, that has a UUID in it. If there is no dbus, use the
3124        * hostname for hashing.
3125        */
3126       const char *session_bus_address = g_getenv ("DBUS_SESSION_BUS_ADDRESS");
3127       if (!session_bus_address)
3128         session_bus_address = g_getenv ("HOSTNAME");
3129       if (session_bus_address)
3130         timer_perturb = ABS ((gint) g_str_hash (session_bus_address));
3131       else
3132         timer_perturb = 0;
3133     }
3134   if (timeout_source->granularity)
3135     {
3136       gint remainder;
3137       gint gran; /* in usecs */
3138       gint perturb;
3139 
3140       gran = timeout_source->granularity * 1000;
3141       perturb = timer_perturb % gran;
3142       /*
3143        * We want to give each machine a per machine pertubation;
3144        * shift time back first, and forward later after the rounding
3145        */
3146 
3147       timeout_source->expiration.tv_usec -= perturb;
3148       if (timeout_source->expiration.tv_usec < 0)
3149         {
3150           timeout_source->expiration.tv_usec += 1000000;
3151           timeout_source->expiration.tv_sec--;
3152         }
3153 
3154       remainder = timeout_source->expiration.tv_usec % gran;
3155       if (remainder >= gran/4) /* round up */
3156         timeout_source->expiration.tv_usec += gran;
3157       timeout_source->expiration.tv_usec -= remainder;
3158       /* shift back */
3159       timeout_source->expiration.tv_usec += perturb;
3160 
3161       /* the rounding may have overflown tv_usec */
3162       while (timeout_source->expiration.tv_usec > 1000000)
3163         {
3164           timeout_source->expiration.tv_usec -= 1000000;
3165           timeout_source->expiration.tv_sec++;
3166         }
3167     }
3168 }
3169 
3170 static gboolean
g_timeout_prepare(GSource * source,gint * timeout)3171 g_timeout_prepare (GSource *source,
3172 		   gint    *timeout)
3173 {
3174   glong sec;
3175   glong msec;
3176   GTimeVal current_time;
3177 
3178   GTimeoutSource *timeout_source = (GTimeoutSource *)source;
3179 
3180   g_source_get_current_time (source, &current_time);
3181 
3182   sec = timeout_source->expiration.tv_sec - current_time.tv_sec;
3183   msec = (timeout_source->expiration.tv_usec - current_time.tv_usec) / 1000;
3184 
3185   /* We do the following in a rather convoluted fashion to deal with
3186    * the fact that we don't have an integral type big enough to hold
3187    * the difference of two timevals in millseconds.
3188    */
3189   if (sec < 0 || (sec == 0 && msec < 0))
3190     msec = 0;
3191   else
3192     {
3193       glong interval_sec = timeout_source->interval / 1000;
3194       glong interval_msec = timeout_source->interval % 1000;
3195 
3196       if (msec < 0)
3197 	{
3198 	  msec += 1000;
3199 	  sec -= 1;
3200 	}
3201 
3202       if (sec > interval_sec ||
3203 	  (sec == interval_sec && msec > interval_msec))
3204 	{
3205 	  /* The system time has been set backwards, so we
3206 	   * reset the expiration time to now + timeout_source->interval;
3207 	   * this at least avoids hanging for long periods of time.
3208 	   */
3209 	  g_timeout_set_expiration (timeout_source, &current_time);
3210 	  msec = MIN (G_MAXINT, timeout_source->interval);
3211 	}
3212       else
3213 	{
3214 	  msec = MIN (G_MAXINT, (guint)msec + 1000 * (guint)sec);
3215 	}
3216     }
3217 
3218   *timeout = (gint)msec;
3219 
3220   return msec == 0;
3221 }
3222 
3223 static gboolean
g_timeout_check(GSource * source)3224 g_timeout_check (GSource *source)
3225 {
3226   GTimeVal current_time;
3227   GTimeoutSource *timeout_source = (GTimeoutSource *)source;
3228 
3229   g_source_get_current_time (source, &current_time);
3230 
3231   return ((timeout_source->expiration.tv_sec < current_time.tv_sec) ||
3232 	  ((timeout_source->expiration.tv_sec == current_time.tv_sec) &&
3233 	   (timeout_source->expiration.tv_usec <= current_time.tv_usec)));
3234 }
3235 
3236 static gboolean
g_timeout_dispatch(GSource * source,GSourceFunc callback,gpointer user_data)3237 g_timeout_dispatch (GSource     *source,
3238 		    GSourceFunc  callback,
3239 		    gpointer     user_data)
3240 {
3241   GTimeoutSource *timeout_source = (GTimeoutSource *)source;
3242 
3243   if (!callback)
3244     {
3245       g_warning ("Timeout source dispatched without callback\n"
3246 		 "You must call g_source_set_callback().");
3247       return FALSE;
3248     }
3249 
3250   if (callback (user_data))
3251     {
3252       GTimeVal current_time;
3253 
3254       g_source_get_current_time (source, &current_time);
3255       g_timeout_set_expiration (timeout_source, &current_time);
3256 
3257       return TRUE;
3258     }
3259   else
3260     return FALSE;
3261 }
3262 
3263 /**
3264  * g_timeout_source_new:
3265  * @interval: the timeout interval in milliseconds.
3266  *
3267  * Creates a new timeout source.
3268  *
3269  * The source will not initially be associated with any #GMainContext
3270  * and must be added to one with g_source_attach() before it will be
3271  * executed.
3272  *
3273  * Return value: the newly-created timeout source
3274  **/
3275 GSource *
g_timeout_source_new(guint interval)3276 g_timeout_source_new (guint interval)
3277 {
3278   GSource *source = g_source_new (&g_timeout_funcs, sizeof (GTimeoutSource));
3279   GTimeoutSource *timeout_source = (GTimeoutSource *)source;
3280   GTimeVal current_time;
3281 
3282   timeout_source->interval = interval;
3283 
3284   g_get_current_time (&current_time);
3285   g_timeout_set_expiration (timeout_source, &current_time);
3286 
3287   return source;
3288 }
3289 
3290 /**
3291  * g_timeout_source_new_seconds:
3292  * @interval: the timeout interval in seconds
3293  *
3294  * Creates a new timeout source.
3295  *
3296  * The source will not initially be associated with any #GMainContext
3297  * and must be added to one with g_source_attach() before it will be
3298  * executed.
3299  *
3300  * The scheduling granularity/accuracy of this timeout source will be
3301  * in seconds.
3302  *
3303  * Return value: the newly-created timeout source
3304  *
3305  * Since: 2.14
3306  **/
3307 GSource *
g_timeout_source_new_seconds(guint interval)3308 g_timeout_source_new_seconds (guint interval)
3309 {
3310   GSource *source = g_source_new (&g_timeout_funcs, sizeof (GTimeoutSource));
3311   GTimeoutSource *timeout_source = (GTimeoutSource *)source;
3312   GTimeVal current_time;
3313 
3314   timeout_source->interval = 1000*interval;
3315   timeout_source->granularity = 1000;
3316 
3317   g_get_current_time (&current_time);
3318   g_timeout_set_expiration (timeout_source, &current_time);
3319 
3320   return source;
3321 }
3322 
3323 
3324 /**
3325  * g_timeout_add_full:
3326  * @priority: the priority of the timeout source. Typically this will be in
3327  *            the range between #G_PRIORITY_DEFAULT and #G_PRIORITY_HIGH.
3328  * @interval: the time between calls to the function, in milliseconds
3329  *             (1/1000ths of a second)
3330  * @function: function to call
3331  * @data:     data to pass to @function
3332  * @notify:   function to call when the timeout is removed, or %NULL
3333  *
3334  * Sets a function to be called at regular intervals, with the given
3335  * priority.  The function is called repeatedly until it returns
3336  * %FALSE, at which point the timeout is automatically destroyed and
3337  * the function will not be called again.  The @notify function is
3338  * called when the timeout is destroyed.  The first call to the
3339  * function will be at the end of the first @interval.
3340  *
3341  * Note that timeout functions may be delayed, due to the processing of other
3342  * event sources. Thus they should not be relied on for precise timing.
3343  * After each call to the timeout function, the time of the next
3344  * timeout is recalculated based on the current time and the given interval
3345  * (it does not try to 'catch up' time lost in delays).
3346  *
3347  * This internally creates a main loop source using g_timeout_source_new()
3348  * and attaches it to the main loop context using g_source_attach(). You can
3349  * do these steps manually if you need greater control.
3350  *
3351  * Return value: the ID (greater than 0) of the event source.
3352  **/
3353 guint
g_timeout_add_full(gint priority,guint interval,GSourceFunc function,gpointer data,GDestroyNotify notify)3354 g_timeout_add_full (gint           priority,
3355 		    guint          interval,
3356 		    GSourceFunc    function,
3357 		    gpointer       data,
3358 		    GDestroyNotify notify)
3359 {
3360   GSource *source;
3361   guint id;
3362 
3363   g_return_val_if_fail (function != NULL, 0);
3364 
3365   source = g_timeout_source_new (interval);
3366 
3367   if (priority != G_PRIORITY_DEFAULT)
3368     g_source_set_priority (source, priority);
3369 
3370   g_source_set_callback (source, function, data, notify);
3371   id = g_source_attach (source, NULL);
3372   g_source_unref (source);
3373 
3374   return id;
3375 }
3376 
3377 /**
3378  * g_timeout_add:
3379  * @interval: the time between calls to the function, in milliseconds
3380  *             (1/1000ths of a second)
3381  * @function: function to call
3382  * @data:     data to pass to @function
3383  *
3384  * Sets a function to be called at regular intervals, with the default
3385  * priority, #G_PRIORITY_DEFAULT.  The function is called repeatedly
3386  * until it returns %FALSE, at which point the timeout is automatically
3387  * destroyed and the function will not be called again.  The first call
3388  * to the function will be at the end of the first @interval.
3389  *
3390  * Note that timeout functions may be delayed, due to the processing of other
3391  * event sources. Thus they should not be relied on for precise timing.
3392  * After each call to the timeout function, the time of the next
3393  * timeout is recalculated based on the current time and the given interval
3394  * (it does not try to 'catch up' time lost in delays).
3395  *
3396  * If you want to have a timer in the "seconds" range and do not care
3397  * about the exact time of the first call of the timer, use the
3398  * g_timeout_add_seconds() function; this function allows for more
3399  * optimizations and more efficient system power usage.
3400  *
3401  * This internally creates a main loop source using g_timeout_source_new()
3402  * and attaches it to the main loop context using g_source_attach(). You can
3403  * do these steps manually if you need greater control.
3404  *
3405  * Return value: the ID (greater than 0) of the event source.
3406  **/
3407 guint
g_timeout_add(guint32 interval,GSourceFunc function,gpointer data)3408 g_timeout_add (guint32        interval,
3409 	       GSourceFunc    function,
3410 	       gpointer       data)
3411 {
3412   return g_timeout_add_full (G_PRIORITY_DEFAULT,
3413 			     interval, function, data, NULL);
3414 }
3415 
3416 /**
3417  * g_timeout_add_seconds_full:
3418  * @priority: the priority of the timeout source. Typically this will be in
3419  *            the range between #G_PRIORITY_DEFAULT and #G_PRIORITY_HIGH.
3420  * @interval: the time between calls to the function, in seconds
3421  * @function: function to call
3422  * @data:     data to pass to @function
3423  * @notify:   function to call when the timeout is removed, or %NULL
3424  *
3425  * Sets a function to be called at regular intervals, with @priority.
3426  * The function is called repeatedly until it returns %FALSE, at which
3427  * point the timeout is automatically destroyed and the function will
3428  * not be called again.
3429  *
3430  * Unlike g_timeout_add(), this function operates at whole second granularity.
3431  * The initial starting point of the timer is determined by the implementation
3432  * and the implementation is expected to group multiple timers together so that
3433  * they fire all at the same time.
3434  * To allow this grouping, the @interval to the first timer is rounded
3435  * and can deviate up to one second from the specified interval.
3436  * Subsequent timer iterations will generally run at the specified interval.
3437  *
3438  * Note that timeout functions may be delayed, due to the processing of other
3439  * event sources. Thus they should not be relied on for precise timing.
3440  * After each call to the timeout function, the time of the next
3441  * timeout is recalculated based on the current time and the given @interval
3442  *
3443  * If you want timing more precise than whole seconds, use g_timeout_add()
3444  * instead.
3445  *
3446  * The grouping of timers to fire at the same time results in a more power
3447  * and CPU efficient behavior so if your timer is in multiples of seconds
3448  * and you don't require the first timer exactly one second from now, the
3449  * use of g_timeout_add_seconds() is preferred over g_timeout_add().
3450  *
3451  * This internally creates a main loop source using
3452  * g_timeout_source_new_seconds() and attaches it to the main loop context
3453  * using g_source_attach(). You can do these steps manually if you need
3454  * greater control.
3455  *
3456  * Return value: the ID (greater than 0) of the event source.
3457  *
3458  * Since: 2.14
3459  **/
3460 guint
g_timeout_add_seconds_full(gint priority,guint32 interval,GSourceFunc function,gpointer data,GDestroyNotify notify)3461 g_timeout_add_seconds_full (gint           priority,
3462                             guint32        interval,
3463                             GSourceFunc    function,
3464                             gpointer       data,
3465                             GDestroyNotify notify)
3466 {
3467   GSource *source;
3468   guint id;
3469 
3470   g_return_val_if_fail (function != NULL, 0);
3471 
3472   source = g_timeout_source_new_seconds (interval);
3473 
3474   if (priority != G_PRIORITY_DEFAULT)
3475     g_source_set_priority (source, priority);
3476 
3477   g_source_set_callback (source, function, data, notify);
3478   id = g_source_attach (source, NULL);
3479   g_source_unref (source);
3480 
3481   return id;
3482 }
3483 
3484 /**
3485  * g_timeout_add_seconds:
3486  * @interval: the time between calls to the function, in seconds
3487  * @function: function to call
3488  * @data: data to pass to @function
3489  *
3490  * Sets a function to be called at regular intervals with the default
3491  * priority, #G_PRIORITY_DEFAULT. The function is called repeatedly until
3492  * it returns %FALSE, at which point the timeout is automatically destroyed
3493  * and the function will not be called again.
3494  *
3495  * This internally creates a main loop source using
3496  * g_timeout_source_new_seconds() and attaches it to the main loop context
3497  * using g_source_attach(). You can do these steps manually if you need
3498  * greater control. Also see g_timout_add_seconds_full().
3499  *
3500  * Return value: the ID (greater than 0) of the event source.
3501  *
3502  * Since: 2.14
3503  **/
3504 guint
g_timeout_add_seconds(guint interval,GSourceFunc function,gpointer data)3505 g_timeout_add_seconds (guint       interval,
3506                        GSourceFunc function,
3507                        gpointer    data)
3508 {
3509   g_return_val_if_fail (function != NULL, 0);
3510 
3511   return g_timeout_add_seconds_full (G_PRIORITY_DEFAULT, interval, function, data, NULL);
3512 }
3513 
3514 /* Child watch functions */
3515 
3516 #ifdef G_OS_WIN32
3517 
3518 static gboolean
g_child_watch_prepare(GSource * source,gint * timeout)3519 g_child_watch_prepare (GSource *source,
3520 		       gint    *timeout)
3521 {
3522   *timeout = -1;
3523   return FALSE;
3524 }
3525 
3526 
3527 static gboolean
g_child_watch_check(GSource * source)3528 g_child_watch_check (GSource  *source)
3529 {
3530   GChildWatchSource *child_watch_source;
3531   gboolean child_exited;
3532 
3533   child_watch_source = (GChildWatchSource *) source;
3534 
3535   child_exited = child_watch_source->poll.revents & G_IO_IN;
3536 
3537   if (child_exited)
3538     {
3539       DWORD child_status;
3540 
3541       /*
3542        * Note: We do _not_ check for the special value of STILL_ACTIVE
3543        * since we know that the process has exited and doing so runs into
3544        * problems if the child process "happens to return STILL_ACTIVE(259)"
3545        * as Microsoft's Platform SDK puts it.
3546        */
3547       if (!GetExitCodeProcess (child_watch_source->pid, &child_status))
3548         {
3549 	  gchar *emsg = g_win32_error_message (GetLastError ());
3550 	  g_warning (G_STRLOC ": GetExitCodeProcess() failed: %s", emsg);
3551 	  g_free (emsg);
3552 
3553 	  child_watch_source->child_status = -1;
3554 	}
3555       else
3556 	child_watch_source->child_status = child_status;
3557     }
3558 
3559   return child_exited;
3560 }
3561 
3562 #else /* G_OS_WIN32 */
3563 
3564 static gboolean
check_for_child_exited(GSource * source)3565 check_for_child_exited (GSource *source)
3566 {
3567   GChildWatchSource *child_watch_source;
3568   gint count;
3569 
3570   /* protect against another SIGCHLD in the middle of this call */
3571   count = child_watch_count;
3572 
3573   child_watch_source = (GChildWatchSource *) source;
3574 
3575   if (child_watch_source->child_exited)
3576     return TRUE;
3577 
3578   if (child_watch_source->count < count)
3579     {
3580       gint child_status;
3581 
3582       if (waitpid (child_watch_source->pid, &child_status, WNOHANG) > 0)
3583 	{
3584 	  child_watch_source->child_status = child_status;
3585 	  child_watch_source->child_exited = TRUE;
3586 	}
3587       child_watch_source->count = count;
3588     }
3589 
3590   return child_watch_source->child_exited;
3591 }
3592 
3593 static gboolean
g_child_watch_prepare(GSource * source,gint * timeout)3594 g_child_watch_prepare (GSource *source,
3595 		       gint    *timeout)
3596 {
3597   *timeout = -1;
3598 
3599   return check_for_child_exited (source);
3600 }
3601 
3602 
3603 static gboolean
g_child_watch_check(GSource * source)3604 g_child_watch_check (GSource  *source)
3605 {
3606   return check_for_child_exited (source);
3607 }
3608 
3609 #endif /* G_OS_WIN32 */
3610 
3611 static gboolean
g_child_watch_dispatch(GSource * source,GSourceFunc callback,gpointer user_data)3612 g_child_watch_dispatch (GSource    *source,
3613 			GSourceFunc callback,
3614 			gpointer    user_data)
3615 {
3616   GChildWatchSource *child_watch_source;
3617   GChildWatchFunc child_watch_callback = (GChildWatchFunc) callback;
3618 
3619   child_watch_source = (GChildWatchSource *) source;
3620 
3621   if (!callback)
3622     {
3623       g_warning ("Child watch source dispatched without callback\n"
3624 		 "You must call g_source_set_callback().");
3625       return FALSE;
3626     }
3627 
3628   (child_watch_callback) (child_watch_source->pid, child_watch_source->child_status, user_data);
3629 
3630   /* We never keep a child watch source around as the child is gone */
3631   return FALSE;
3632 }
3633 
3634 #ifndef G_OS_WIN32
3635 
3636 static void
g_child_watch_signal_handler(int signum)3637 g_child_watch_signal_handler (int signum)
3638 {
3639   child_watch_count ++;
3640 
3641   if (child_watch_init_state == CHILD_WATCH_INITIALIZED_THREADED)
3642     {
3643       write (child_watch_wake_up_pipe[1], "B", 1);
3644     }
3645   else
3646     {
3647       /* We count on the signal interrupting the poll in the same thread.
3648        */
3649     }
3650 }
3651 
3652 static void
g_child_watch_source_init_single(void)3653 g_child_watch_source_init_single (void)
3654 {
3655   struct sigaction action;
3656 
3657   g_assert (! g_thread_supported());
3658   g_assert (child_watch_init_state == CHILD_WATCH_UNINITIALIZED);
3659 
3660   child_watch_init_state = CHILD_WATCH_INITIALIZED_SINGLE;
3661 
3662   action.sa_handler = g_child_watch_signal_handler;
3663   sigemptyset (&action.sa_mask);
3664   action.sa_flags = SA_NOCLDSTOP;
3665   sigaction (SIGCHLD, &action, NULL);
3666 }
3667 
3668 #ifndef ANDROID_STUB
3669 G_GNUC_NORETURN static gpointer
3670 #else
3671 void
3672 #endif
child_watch_helper_thread(gpointer data)3673 child_watch_helper_thread (gpointer data)
3674 {
3675   while (1)
3676     {
3677       gchar b[20];
3678       GSList *list;
3679 
3680       read (child_watch_wake_up_pipe[0], b, 20);
3681 
3682       /* We were woken up.  Wake up all other contexts in all other threads */
3683       G_LOCK (main_context_list);
3684       for (list = main_context_list; list; list = list->next)
3685 	{
3686 	  GMainContext *context;
3687 
3688 	  context = list->data;
3689 	  if (g_atomic_int_get (&context->ref_count) > 0)
3690 	    /* Due to racing conditions we can find ref_count == 0, in
3691 	     * that case, however, the context is still not destroyed
3692 	     * and no poll can be active, otherwise the ref_count
3693 	     * wouldn't be 0 */
3694 	    g_main_context_wakeup (context);
3695 	}
3696       G_UNLOCK (main_context_list);
3697     }
3698 }
3699 
3700 static void
g_child_watch_source_init_multi_threaded(void)3701 g_child_watch_source_init_multi_threaded (void)
3702 {
3703   GError *error = NULL;
3704   struct sigaction action;
3705 
3706   g_assert (g_thread_supported());
3707 
3708   if (pipe (child_watch_wake_up_pipe) < 0)
3709     g_error ("Cannot create wake up pipe: %s\n", g_strerror (errno));
3710   fcntl (child_watch_wake_up_pipe[1], F_SETFL, O_NONBLOCK | fcntl (child_watch_wake_up_pipe[1], F_GETFL));
3711 
3712   /* We create a helper thread that polls on the wakeup pipe indefinitely */
3713   /* FIXME: Think this through for races */
3714   if (g_thread_create (child_watch_helper_thread, NULL, FALSE, &error) == NULL)
3715     g_error ("Cannot create a thread to monitor child exit status: %s\n", error->message);
3716   child_watch_init_state = CHILD_WATCH_INITIALIZED_THREADED;
3717 
3718   action.sa_handler = g_child_watch_signal_handler;
3719   sigemptyset (&action.sa_mask);
3720   action.sa_flags = SA_RESTART | SA_NOCLDSTOP;
3721   sigaction (SIGCHLD, &action, NULL);
3722 }
3723 
3724 static void
g_child_watch_source_init_promote_single_to_threaded(void)3725 g_child_watch_source_init_promote_single_to_threaded (void)
3726 {
3727   g_child_watch_source_init_multi_threaded ();
3728 }
3729 
3730 static void
g_child_watch_source_init(void)3731 g_child_watch_source_init (void)
3732 {
3733   if (g_thread_supported())
3734     {
3735       if (child_watch_init_state == CHILD_WATCH_UNINITIALIZED)
3736 	g_child_watch_source_init_multi_threaded ();
3737       else if (child_watch_init_state == CHILD_WATCH_INITIALIZED_SINGLE)
3738 	g_child_watch_source_init_promote_single_to_threaded ();
3739     }
3740   else
3741     {
3742       if (child_watch_init_state == CHILD_WATCH_UNINITIALIZED)
3743 	g_child_watch_source_init_single ();
3744     }
3745 }
3746 
3747 #endif /* !G_OS_WIN32 */
3748 
3749 /**
3750  * g_child_watch_source_new:
3751  * @pid: process to watch. On POSIX the pid of a child process. On
3752  * Windows a handle for a process (which doesn't have to be a child).
3753  *
3754  * Creates a new child_watch source.
3755  *
3756  * The source will not initially be associated with any #GMainContext
3757  * and must be added to one with g_source_attach() before it will be
3758  * executed.
3759  *
3760  * Note that child watch sources can only be used in conjunction with
3761  * <literal>g_spawn...</literal> when the %G_SPAWN_DO_NOT_REAP_CHILD
3762  * flag is used.
3763  *
3764  * Note that on platforms where #GPid must be explicitly closed
3765  * (see g_spawn_close_pid()) @pid must not be closed while the
3766  * source is still active. Typically, you will want to call
3767  * g_spawn_close_pid() in the callback function for the source.
3768  *
3769  * Note further that using g_child_watch_source_new() is not
3770  * compatible with calling <literal>waitpid(-1)</literal> in
3771  * the application. Calling waitpid() for individual pids will
3772  * still work fine.
3773  *
3774  * Return value: the newly-created child watch source
3775  *
3776  * Since: 2.4
3777  **/
3778 GSource *
g_child_watch_source_new(GPid pid)3779 g_child_watch_source_new (GPid pid)
3780 {
3781   GSource *source = g_source_new (&g_child_watch_funcs, sizeof (GChildWatchSource));
3782   GChildWatchSource *child_watch_source = (GChildWatchSource *)source;
3783 
3784 #ifdef G_OS_WIN32
3785   child_watch_source->poll.fd = (gintptr) pid;
3786   child_watch_source->poll.events = G_IO_IN;
3787 
3788   g_source_add_poll (source, &child_watch_source->poll);
3789 #else /* G_OS_WIN32 */
3790   g_child_watch_source_init ();
3791 #endif /* G_OS_WIN32 */
3792 
3793   child_watch_source->pid = pid;
3794 
3795   return source;
3796 }
3797 
3798 /**
3799  * g_child_watch_add_full:
3800  * @priority: the priority of the idle source. Typically this will be in the
3801  *            range between #G_PRIORITY_DEFAULT_IDLE and #G_PRIORITY_HIGH_IDLE.
3802  * @pid:      process to watch. On POSIX the pid of a child process. On
3803  * Windows a handle for a process (which doesn't have to be a child).
3804  * @function: function to call
3805  * @data:     data to pass to @function
3806  * @notify:   function to call when the idle is removed, or %NULL
3807  *
3808  * Sets a function to be called when the child indicated by @pid
3809  * exits, at the priority @priority.
3810  *
3811  * If you obtain @pid from g_spawn_async() or g_spawn_async_with_pipes()
3812  * you will need to pass #G_SPAWN_DO_NOT_REAP_CHILD as flag to
3813  * the spawn function for the child watching to work.
3814  *
3815  * Note that on platforms where #GPid must be explicitly closed
3816  * (see g_spawn_close_pid()) @pid must not be closed while the
3817  * source is still active. Typically, you will want to call
3818  * g_spawn_close_pid() in the callback function for the source.
3819  *
3820  * GLib supports only a single callback per process id.
3821  *
3822  * This internally creates a main loop source using
3823  * g_child_watch_source_new() and attaches it to the main loop context
3824  * using g_source_attach(). You can do these steps manually if you
3825  * need greater control.
3826  *
3827  * Return value: the ID (greater than 0) of the event source.
3828  *
3829  * Since: 2.4
3830  **/
3831 guint
g_child_watch_add_full(gint priority,GPid pid,GChildWatchFunc function,gpointer data,GDestroyNotify notify)3832 g_child_watch_add_full (gint            priority,
3833 			GPid            pid,
3834 			GChildWatchFunc function,
3835 			gpointer        data,
3836 			GDestroyNotify  notify)
3837 {
3838   GSource *source;
3839   guint id;
3840 
3841   g_return_val_if_fail (function != NULL, 0);
3842 
3843   source = g_child_watch_source_new (pid);
3844 
3845   if (priority != G_PRIORITY_DEFAULT)
3846     g_source_set_priority (source, priority);
3847 
3848   g_source_set_callback (source, (GSourceFunc) function, data, notify);
3849   id = g_source_attach (source, NULL);
3850   g_source_unref (source);
3851 
3852   return id;
3853 }
3854 
3855 /**
3856  * g_child_watch_add:
3857  * @pid:      process id to watch. On POSIX the pid of a child process. On
3858  * Windows a handle for a process (which doesn't have to be a child).
3859  * @function: function to call
3860  * @data:     data to pass to @function
3861  *
3862  * Sets a function to be called when the child indicated by @pid
3863  * exits, at a default priority, #G_PRIORITY_DEFAULT.
3864  *
3865  * If you obtain @pid from g_spawn_async() or g_spawn_async_with_pipes()
3866  * you will need to pass #G_SPAWN_DO_NOT_REAP_CHILD as flag to
3867  * the spawn function for the child watching to work.
3868  *
3869  * Note that on platforms where #GPid must be explicitly closed
3870  * (see g_spawn_close_pid()) @pid must not be closed while the
3871  * source is still active. Typically, you will want to call
3872  * g_spawn_close_pid() in the callback function for the source.
3873  *
3874  * GLib supports only a single callback per process id.
3875  *
3876  * This internally creates a main loop source using
3877  * g_child_watch_source_new() and attaches it to the main loop context
3878  * using g_source_attach(). You can do these steps manually if you
3879  * need greater control.
3880  *
3881  * Return value: the ID (greater than 0) of the event source.
3882  *
3883  * Since: 2.4
3884  **/
3885 guint
g_child_watch_add(GPid pid,GChildWatchFunc function,gpointer data)3886 g_child_watch_add (GPid            pid,
3887 		   GChildWatchFunc function,
3888 		   gpointer        data)
3889 {
3890   return g_child_watch_add_full (G_PRIORITY_DEFAULT, pid, function, data, NULL);
3891 }
3892 
3893 
3894 /* Idle functions */
3895 
3896 static gboolean
g_idle_prepare(GSource * source,gint * timeout)3897 g_idle_prepare  (GSource  *source,
3898 		 gint     *timeout)
3899 {
3900   *timeout = 0;
3901 
3902   return TRUE;
3903 }
3904 
3905 static gboolean
g_idle_check(GSource * source)3906 g_idle_check    (GSource  *source)
3907 {
3908   return TRUE;
3909 }
3910 
3911 static gboolean
g_idle_dispatch(GSource * source,GSourceFunc callback,gpointer user_data)3912 g_idle_dispatch (GSource    *source,
3913 		 GSourceFunc callback,
3914 		 gpointer    user_data)
3915 {
3916   if (!callback)
3917     {
3918       g_warning ("Idle source dispatched without callback\n"
3919 		 "You must call g_source_set_callback().");
3920       return FALSE;
3921     }
3922 
3923   return callback (user_data);
3924 }
3925 
3926 /**
3927  * g_idle_source_new:
3928  *
3929  * Creates a new idle source.
3930  *
3931  * The source will not initially be associated with any #GMainContext
3932  * and must be added to one with g_source_attach() before it will be
3933  * executed. Note that the default priority for idle sources is
3934  * %G_PRIORITY_DEFAULT_IDLE, as compared to other sources which
3935  * have a default priority of %G_PRIORITY_DEFAULT.
3936  *
3937  * Return value: the newly-created idle source
3938  **/
3939 GSource *
g_idle_source_new(void)3940 g_idle_source_new (void)
3941 {
3942   GSource *source;
3943 
3944   source = g_source_new (&g_idle_funcs, sizeof (GSource));
3945   g_source_set_priority (source, G_PRIORITY_DEFAULT_IDLE);
3946 
3947   return source;
3948 }
3949 
3950 /**
3951  * g_idle_add_full:
3952  * @priority: the priority of the idle source. Typically this will be in the
3953  *            range between #G_PRIORITY_DEFAULT_IDLE and #G_PRIORITY_HIGH_IDLE.
3954  * @function: function to call
3955  * @data:     data to pass to @function
3956  * @notify:   function to call when the idle is removed, or %NULL
3957  *
3958  * Adds a function to be called whenever there are no higher priority
3959  * events pending.  If the function returns %FALSE it is automatically
3960  * removed from the list of event sources and will not be called again.
3961  *
3962  * This internally creates a main loop source using g_idle_source_new()
3963  * and attaches it to the main loop context using g_source_attach().
3964  * You can do these steps manually if you need greater control.
3965  *
3966  * Return value: the ID (greater than 0) of the event source.
3967  **/
3968 guint
g_idle_add_full(gint priority,GSourceFunc function,gpointer data,GDestroyNotify notify)3969 g_idle_add_full (gint           priority,
3970 		 GSourceFunc    function,
3971 		 gpointer       data,
3972 		 GDestroyNotify notify)
3973 {
3974   GSource *source;
3975   guint id;
3976 
3977   g_return_val_if_fail (function != NULL, 0);
3978 
3979   source = g_idle_source_new ();
3980 
3981   if (priority != G_PRIORITY_DEFAULT_IDLE)
3982     g_source_set_priority (source, priority);
3983 
3984   g_source_set_callback (source, function, data, notify);
3985   id = g_source_attach (source, NULL);
3986   g_source_unref (source);
3987 
3988   return id;
3989 }
3990 
3991 /**
3992  * g_idle_add:
3993  * @function: function to call
3994  * @data: data to pass to @function.
3995  *
3996  * Adds a function to be called whenever there are no higher priority
3997  * events pending to the default main loop. The function is given the
3998  * default idle priority, #G_PRIORITY_DEFAULT_IDLE.  If the function
3999  * returns %FALSE it is automatically removed from the list of event
4000  * sources and will not be called again.
4001  *
4002  * This internally creates a main loop source using g_idle_source_new()
4003  * and attaches it to the main loop context using g_source_attach().
4004  * You can do these steps manually if you need greater control.
4005  *
4006  * Return value: the ID (greater than 0) of the event source.
4007  **/
4008 guint
g_idle_add(GSourceFunc function,gpointer data)4009 g_idle_add (GSourceFunc    function,
4010 	    gpointer       data)
4011 {
4012   return g_idle_add_full (G_PRIORITY_DEFAULT_IDLE, function, data, NULL);
4013 }
4014 
4015 /**
4016  * g_idle_remove_by_data:
4017  * @data: the data for the idle source's callback.
4018  *
4019  * Removes the idle function with the given data.
4020  *
4021  * Return value: %TRUE if an idle source was found and removed.
4022  **/
4023 gboolean
g_idle_remove_by_data(gpointer data)4024 g_idle_remove_by_data (gpointer data)
4025 {
4026   return g_source_remove_by_funcs_user_data (&g_idle_funcs, data);
4027 }
4028 
4029 #define __G_MAIN_C__
4030 #include "galiasdef.c"
4031