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