Add gettext support.
[platform/upstream/glib.git] / 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 "glib.h"
40 #include <sys/types.h>
41 #include <time.h>
42 #ifdef HAVE_SYS_TIME_H
43 #include <sys/time.h>
44 #endif /* HAVE_SYS_TIME_H */
45 #ifdef GLIB_HAVE_SYS_POLL_H
46 #  include <sys/poll.h>
47 #  undef events  /* AIX 4.1.5 & 4.3.2 define this for SVR3,4 compatibility */
48 #  undef revents /* AIX 4.1.5 & 4.3.2 define this for SVR3,4 compatibility */
49 #endif /* GLIB_HAVE_SYS_POLL_H */
50 #ifdef HAVE_UNISTD_H
51 #include <unistd.h>
52 #endif /* HAVE_UNISTD_H */
53 #include <errno.h>
54
55 #ifdef G_OS_WIN32
56 #define STRICT
57 #include <windows.h>
58 #endif /* G_OS_WIN32 */
59
60 #ifdef G_OS_BEOS
61 #include <net/socket.h>
62 #endif /* G_OS_BEOS */
63
64 /* Types */
65
66 typedef struct _GTimeoutSource GTimeoutSource;
67 typedef struct _GPollRec GPollRec;
68 typedef struct _GSourceCallback GSourceCallback;
69
70 typedef enum
71 {
72   G_SOURCE_READY = 1 << G_HOOK_FLAG_USER_SHIFT,
73   G_SOURCE_CAN_RECURSE = 1 << (G_HOOK_FLAG_USER_SHIFT + 1)
74 } GSourceFlags;
75
76 struct _GMainContext
77 {
78 #ifdef G_THREADS_ENABLED
79   /* The following lock is used for both the list of sources
80    * and the list of poll records
81    */
82   GMutex *mutex;
83   GThread *thread;
84 #endif  
85
86   GPtrArray *pending_dispatches;
87   gint timeout;                 /* Timeout for current iteration */
88
89   guint next_id;
90   GSource *source_list;
91   gint in_check_or_prepare;
92
93   GPollRec *poll_records;
94   GPollRec *poll_free_list;
95   GMemChunk *poll_chunk;
96   guint n_poll_records;
97   GPollFD *cached_poll_array;
98   gint cached_poll_array_size;
99
100 #ifdef G_THREADS_ENABLED  
101 #ifndef G_OS_WIN32
102 /* this pipe is used to wake up the main loop when a source is added.
103  */
104   gint wake_up_pipe[2];
105 #else /* G_OS_WIN32 */
106   HANDLE wake_up_semaphore;
107 #endif /* G_OS_WIN32 */
108
109   GPollFD wake_up_rec;
110   gboolean poll_waiting;
111
112 /* Flag indicating whether the set of fd's changed during a poll */
113   gboolean poll_changed;
114 #endif /* G_THREADS_ENABLED */
115
116   GPollFunc poll_func;
117
118   GTimeVal current_time;
119   gboolean time_is_current;
120 };
121
122 struct _GSourceCallback
123 {
124   guint ref_count;
125   GSourceFunc func;
126   gpointer    data;
127   GDestroyNotify notify;
128 };
129
130 struct _GMainLoop
131 {
132   GMainContext *context;
133   gboolean is_running;
134   guint ref_count;
135
136 #ifdef G_THREADS_ENABLED
137   GMutex *mutex;
138   GCond *sem_cond;
139 #endif /* G_THREADS_ENABLED */
140 };
141
142 struct _GTimeoutSource
143 {
144   GSource     source;
145   GTimeVal    expiration;
146   gint        interval;
147 };
148
149 struct _GPollRec
150 {
151   gint priority;
152   GPollFD *fd;
153   GPollRec *next;
154 };
155
156 #ifdef G_THREADS_ENABLED
157 #define LOCK_CONTEXT(context) g_mutex_lock(context->mutex)
158 #define UNLOCK_CONTEXT(context) g_mutex_unlock(context->mutex)
159 #define LOCK_LOOP(loop) g_mutex_lock(loop->mutex)
160 #define UNLOCK_LOOP(loop) g_mutex_unlock(loop->mutex)
161 #else
162 #define LOCK_CONTEXT(context) (void)0
163 #define UNLOCK_CONTEXT(context) (void)0
164 #define LOCK_LOOP(context) (void)0
165 #define UNLOCK_LOOP(context) (void)0
166 #endif
167
168 #define SOURCE_DESTROYED(source) (((source)->flags & G_HOOK_FLAG_ACTIVE) == 0)
169
170 #define SOURCE_UNREF(source, context)                       \
171    G_STMT_START {                                           \
172     if ((source)->ref_count > 1)                            \
173       (source)->ref_count--;                                \
174     else                                                    \
175       g_source_unref_internal ((source), (context), TRUE);  \
176    } G_STMT_END
177
178
179 /* Forward declarations */
180
181 static void g_source_unref_internal             (GSource      *source,
182                                                  GMainContext *context,
183                                                  gboolean      have_lock);
184 static void g_source_destroy_internal           (GSource      *source,
185                                                  GMainContext *context,
186                                                  gboolean      have_lock);
187 static void g_main_context_poll                 (GMainContext *context,
188                                                  gint          timeout,
189                                                  gint          priority,
190                                                  GPollFD      *fds,
191                                                  gint          n_fds);
192 static void g_main_context_add_poll_unlocked    (GMainContext *context,
193                                                  gint          priority,
194                                                  GPollFD      *fd);
195 static void g_main_context_remove_poll_unlocked (GMainContext *context,
196                                                  GPollFD      *fd);
197 static void g_main_context_wakeup               (GMainContext *context);
198
199 static gboolean g_timeout_prepare  (GSource     *source,
200                                     gint        *timeout);
201 static gboolean g_timeout_check    (GSource     *source);
202 static gboolean g_timeout_dispatch (GSource     *source,
203                                     GSourceFunc  callback,
204                                     gpointer     user_data);
205 static gboolean g_idle_prepare     (GSource     *source,
206                                     gint        *timeout);
207 static gboolean g_idle_check       (GSource     *source);
208 static gboolean g_idle_dispatch    (GSource     *source,
209                                     GSourceFunc  callback,
210                                     gpointer     user_data);
211
212 G_LOCK_DEFINE_STATIC (main_loop);
213 static GMainContext *default_main_context;
214
215 static GSourceFuncs timeout_funcs =
216 {
217   g_timeout_prepare,
218   g_timeout_check,
219   g_timeout_dispatch,
220   NULL
221 };
222
223 static GSourceFuncs idle_funcs =
224 {
225   g_idle_prepare,
226   g_idle_check,
227   g_idle_dispatch,
228   NULL
229 };
230
231 #ifdef HAVE_POLL
232 /* SunOS has poll, but doesn't provide a prototype. */
233 #  if defined (sun) && !defined (__SVR4)
234 extern gint poll (GPollFD *ufds, guint nfsd, gint timeout);
235 #  endif  /* !sun */
236 #else   /* !HAVE_POLL */
237
238 #ifdef G_OS_WIN32
239
240 static gint
241 g_poll (GPollFD *fds,
242         guint    nfds,
243         gint     timeout)
244 {
245   HANDLE handles[MAXIMUM_WAIT_OBJECTS];
246   gboolean poll_msgs = FALSE;
247   GPollFD *f;
248   DWORD ready;
249   MSG msg;
250   UINT timer;
251   gint nhandles = 0;
252
253   for (f = fds; f < &fds[nfds]; ++f)
254     if (f->fd >= 0)
255       {
256         if (f->events & G_IO_IN)
257           {
258             if (f->fd == G_WIN32_MSG_HANDLE)
259               poll_msgs = TRUE;
260             else
261               {
262 #ifdef G_MAIN_POLL_DEBUG
263                 g_print ("g_poll: waiting for %#x\n", f->fd);
264 #endif
265                 handles[nhandles++] = (HANDLE) f->fd;
266               }
267           }
268       }
269
270   if (timeout == -1)
271     timeout = INFINITE;
272
273   if (poll_msgs)
274     {
275       /* Waiting for messages, and maybe events */
276       if (nhandles == 0)
277         {
278           if (timeout == INFINITE)
279             {
280               /* Waiting just for messages, infinite timeout
281                * -> Use PeekMessage, then WaitMessage
282                */
283 #ifdef G_MAIN_POLL_DEBUG
284               g_print ("PeekMessage, then WaitMessage\n");
285 #endif
286               if (PeekMessage (&msg, NULL, 0, 0, PM_NOREMOVE))
287                 ready = WAIT_OBJECT_0;
288               else if (!WaitMessage ())
289                 g_warning ("g_poll: WaitMessage failed");
290               ready = WAIT_OBJECT_0;
291             }
292           else if (timeout == 0)
293             {
294               /* Waiting just for messages, zero timeout
295                * -> Use PeekMessage
296                */
297 #ifdef G_MAIN_POLL_DEBUG
298               g_print ("PeekMessage\n");
299 #endif
300               if (PeekMessage (&msg, NULL, 0, 0, PM_NOREMOVE))
301                 ready = WAIT_OBJECT_0;
302               else
303                 ready = WAIT_TIMEOUT;
304             }
305           else
306             {
307               /* Waiting just for messages, some timeout
308                * -> First try PeekMessage, then set a timer, wait for message,
309                * kill timer, use PeekMessage
310                */
311 #ifdef G_MAIN_POLL_DEBUG
312               g_print ("PeekMessage\n");
313 #endif
314               if (PeekMessage (&msg, NULL, 0, 0, PM_NOREMOVE))
315                 ready = WAIT_OBJECT_0;
316               else if ((timer = SetTimer (NULL, 0, timeout, NULL)) == 0)
317                 g_warning ("g_poll: SetTimer failed");
318               else
319                 {
320 #ifdef G_MAIN_POLL_DEBUG
321                   g_print ("WaitMessage\n");
322 #endif
323                   WaitMessage ();
324                   KillTimer (NULL, timer);
325                   if (PeekMessage (&msg, NULL, 0, 0, PM_NOREMOVE)
326                       && msg.message != WM_TIMER)
327                     ready = WAIT_OBJECT_0;
328                   else
329                     ready = WAIT_TIMEOUT;
330                 }
331             }
332         }
333       else
334         {
335           /* Wait for either message or event
336            * -> Use MsgWaitForMultipleObjects
337            */
338 #ifdef G_MAIN_POLL_DEBUG
339           g_print ("MsgWaitForMultipleObjects(%d, %d)\n", nhandles, timeout);
340 #endif
341           ready = MsgWaitForMultipleObjects (nhandles, handles, FALSE,
342                                              timeout, QS_ALLINPUT);
343
344           if (ready == WAIT_FAILED)
345             g_warning ("g_poll: MsgWaitForMultipleObjects failed");
346         }
347     }
348   else if (nhandles == 0)
349     {
350       /* Wait for nothing (huh?) */
351       return 0;
352     }
353   else
354     {
355       /* Wait for just events
356        * -> Use WaitForMultipleObjects
357        */
358 #ifdef G_MAIN_POLL_DEBUG
359       g_print ("WaitForMultipleObjects(%d, %d)\n", nhandles, timeout);
360 #endif
361       ready = WaitForMultipleObjects (nhandles, handles, FALSE, timeout);
362       if (ready == WAIT_FAILED)
363         g_warning ("g_poll: WaitForMultipleObjects failed");
364     }
365
366   for (f = fds; f < &fds[nfds]; ++f)
367     f->revents = 0;
368
369   if (ready == WAIT_FAILED)
370     return -1;
371   else if (ready == WAIT_TIMEOUT)
372     return 0;
373   else if (poll_msgs && ready == WAIT_OBJECT_0 + nhandles)
374     {
375       for (f = fds; f < &fds[nfds]; ++f)
376         if (f->fd >= 0)
377           {
378             if (f->events & G_IO_IN)
379               if (f->fd == G_WIN32_MSG_HANDLE)
380                 f->revents |= G_IO_IN;
381           }
382     }
383   else if (ready >= WAIT_OBJECT_0 && ready < WAIT_OBJECT_0 + nhandles)
384     for (f = fds; f < &fds[nfds]; ++f)
385       {
386         if ((f->events & G_IO_IN)
387             && f->fd == (gint) handles[ready - WAIT_OBJECT_0])
388           {
389             f->revents |= G_IO_IN;
390 #ifdef G_MAIN_POLL_DEBUG
391             g_print ("g_poll: got event %#x\n", f->fd);
392 #endif
393 #if 0
394             ResetEvent ((HANDLE) f->fd);
395 #endif
396           }
397       }
398     
399   if (ready >= WAIT_OBJECT_0 && ready < WAIT_OBJECT_0 + nhandles)
400     return ready - WAIT_OBJECT_0 + 1;
401   else
402     return 0;
403 }
404
405 #else  /* !G_OS_WIN32 */
406
407 /* The following implementation of poll() comes from the GNU C Library.
408  * Copyright (C) 1994, 1996, 1997 Free Software Foundation, Inc.
409  */
410
411 #include <string.h> /* for bzero on BSD systems */
412
413 #ifdef HAVE_SYS_SELECT_H
414 #include <sys/select.h>
415 #endif /* HAVE_SYS_SELECT_H */
416
417 #ifdef G_OS_BEOS
418 #undef NO_FD_SET
419 #endif /* G_OS_BEOS */
420
421 #ifndef NO_FD_SET
422 #  define SELECT_MASK fd_set
423 #else /* !NO_FD_SET */
424 #  ifndef _AIX
425 typedef long fd_mask;
426 #  endif /* _AIX */
427 #  ifdef _IBMR2
428 #    define SELECT_MASK void
429 #  else /* !_IBMR2 */
430 #    define SELECT_MASK int
431 #  endif /* !_IBMR2 */
432 #endif /* !NO_FD_SET */
433
434 static gint 
435 g_poll (GPollFD *fds,
436         guint    nfds,
437         gint     timeout)
438 {
439   struct timeval tv;
440   SELECT_MASK rset, wset, xset;
441   GPollFD *f;
442   int ready;
443   int maxfd = 0;
444
445   FD_ZERO (&rset);
446   FD_ZERO (&wset);
447   FD_ZERO (&xset);
448
449   for (f = fds; f < &fds[nfds]; ++f)
450     if (f->fd >= 0)
451       {
452         if (f->events & G_IO_IN)
453           FD_SET (f->fd, &rset);
454         if (f->events & G_IO_OUT)
455           FD_SET (f->fd, &wset);
456         if (f->events & G_IO_PRI)
457           FD_SET (f->fd, &xset);
458         if (f->fd > maxfd && (f->events & (G_IO_IN|G_IO_OUT|G_IO_PRI)))
459           maxfd = f->fd;
460       }
461
462   tv.tv_sec = timeout / 1000;
463   tv.tv_usec = (timeout % 1000) * 1000;
464
465   ready = select (maxfd + 1, &rset, &wset, &xset,
466                   timeout == -1 ? NULL : &tv);
467   if (ready > 0)
468     for (f = fds; f < &fds[nfds]; ++f)
469       {
470         f->revents = 0;
471         if (f->fd >= 0)
472           {
473             if (FD_ISSET (f->fd, &rset))
474               f->revents |= G_IO_IN;
475             if (FD_ISSET (f->fd, &wset))
476               f->revents |= G_IO_OUT;
477             if (FD_ISSET (f->fd, &xset))
478               f->revents |= G_IO_PRI;
479           }
480       }
481
482   return ready;
483 }
484
485 #endif /* !G_OS_WIN32 */
486
487 #endif  /* !HAVE_POLL */
488
489 /* Called to clean up when a thread terminates
490  */
491 static void
492 g_main_context_destroy (GMainContext *context)
493 {
494   GSource *source;
495
496   /* We need the lock here only because g_source_destroy expects
497    * to be able to unlock when destroying the source's data
498    */
499   LOCK_CONTEXT (context);
500   source = context->source_list;
501   while (source)
502     {
503       GSource *next = source->next;
504       g_source_destroy_internal (source, context, TRUE);
505       source = next;
506     }
507   UNLOCK_CONTEXT (context);
508
509 #ifdef G_THREADS_ENABLED  
510   g_mutex_free (context->mutex);
511 #endif
512
513   g_ptr_array_free (context->pending_dispatches, TRUE);
514   g_free (context->cached_poll_array);
515   
516   g_mem_chunk_destroy (context->poll_chunk);
517
518 #ifdef G_THREADS_ENABLED
519   if (g_thread_supported())
520     {
521 #ifndef G_OS_WIN32
522       close (context->wake_up_pipe[0]);
523       close (context->wake_up_pipe[1]);
524 #else
525       CloseHandle (context->wake_up_semaphore);
526 #endif
527     }
528 #endif
529   
530   g_free (context);
531 }
532
533 /**
534  * g_main_context_get:
535  * @thread: a #GThread
536  * 
537  * Retrieves the main loop context for a particular thread. This
538  * will create the main context for the thread if none previously
539  * existed. The context will exist until the thread terminates.
540  * 
541  * Return value: the main loop context for @thread.
542  **/
543 GMainContext *
544 g_main_context_get (GThread *thread)
545 {
546   static GStaticPrivate private_key = G_STATIC_PRIVATE_INIT;
547   GMainContext *context;
548
549   g_return_val_if_fail (thread != NULL, NULL);
550
551   if (g_thread_supported ())
552     context = g_static_private_get_for_thread (&private_key, thread);
553   else
554     context = default_main_context;
555
556   if (!context)
557     {
558       context = g_new0 (GMainContext, 1);
559
560 #ifdef G_THREADS_ENABLED
561       if (g_thread_supported ())
562         context->mutex = g_mutex_new();
563
564       context->thread = thread;
565 #endif
566       
567       context->next_id = 1;
568       
569       context->source_list = NULL;
570
571 #if HAVE_POLL
572       context->poll_func = (GPollFunc)poll;
573 #else
574       context->poll_func = g_poll;
575 #endif
576
577       context->cached_poll_array = NULL;
578       context->cached_poll_array_size = 0;
579       
580       context->pending_dispatches = g_ptr_array_new ();
581       
582       context->time_is_current = FALSE;
583
584 #ifdef G_THREADS_ENABLED
585       if (g_thread_supported ())
586         {
587 #ifndef G_OS_WIN32
588           if (pipe (context->wake_up_pipe) < 0)
589             g_error ("Cannot create pipe main loop wake-up: %s\n",
590                      g_strerror (errno));
591           
592           context->wake_up_rec.fd = context->wake_up_pipe[0];
593           context->wake_up_rec.events = G_IO_IN;
594           g_main_context_add_poll_unlocked (context, 0, &context->wake_up_rec);
595 #else
596           if ((context->wake_up_semaphore = CreateSemaphore (NULL, 0, 100, NULL)) == NULL)
597             g_error ("Cannot create wake-up semaphore: %s", g_win32_error_message (GetLastError ()));
598           context->wake_up_rec.fd = (gint) context->wake_up_semaphore;
599           context->wake_up_rec.events = G_IO_IN;
600 #ifdef G_MAIN_POLL_DEBUG
601           g_print ("wake-up semaphore: %#x\n", (guint) context->wake_up_semaphore);
602 #endif
603           g_main_context_add_poll_unlocked (context, 0, &context->wake_up_rec);
604 #endif
605         }
606 #endif
607
608       if (g_thread_supported ())
609         g_static_private_set_for_thread (&private_key, thread,
610                                          context,
611                                          (GDestroyNotify)g_main_context_destroy);
612       else
613         default_main_context = context;
614     }
615
616   return context;
617 }
618
619 /**
620  * g_main_context_default:
621  * 
622  * Return the default main context. This is the main context used
623  * for main loop functions when a main loop is not explicitly
624  * specified.
625  * 
626  * Return value: the default main context.
627  **/
628 GMainContext *
629 g_main_context_default (void)
630 {
631   /* Slow, but safe */
632   
633   G_LOCK (main_loop);
634
635   if (!default_main_context)
636     default_main_context = g_main_context_get (g_thread_self ());
637
638   G_UNLOCK (main_loop);
639
640   return default_main_context;
641 }
642
643 /* Hooks for adding to the main loop */
644
645 /**
646  * g_source_new:
647  * @source_funcs: structure containing functions that implement
648  *                the sources behavior.
649  * @struct_size: size of the #GSource structure to create
650  * 
651  * Create a new GSource structure. The size is specified to
652  * allow creating structures derived from GSource that contain
653  * additional data. The size passed in must be at least
654  * sizeof(GSource).
655  * 
656  * The source will not initially be associated with any #GMainContext
657  * and must be added to one with g_source_add() before it will be
658  * executed.
659  * 
660  * Return value: the newly create #GSource
661  **/
662 GSource *
663 g_source_new (GSourceFuncs *source_funcs,
664               guint         struct_size)
665 {
666   GSource *source;
667
668   g_return_val_if_fail (source_funcs != NULL, NULL);
669   g_return_val_if_fail (struct_size >= sizeof (GSource), NULL);
670   
671   source = (GSource*) g_malloc0 (struct_size);
672
673   source->source_funcs = source_funcs;
674   source->ref_count = 1;
675   
676   source->priority = G_PRIORITY_DEFAULT;
677
678   source->flags = G_HOOK_FLAG_ACTIVE;
679
680   /* NULL/0 initialization for all other fields */
681   
682   return source;
683 }
684
685 /* Holds context's lock
686  */
687 static void
688 g_source_list_add (GSource      *source,
689                    GMainContext *context)
690 {
691   GSource *tmp_source, *last_source;
692   
693   last_source = NULL;
694   tmp_source = context->source_list;
695   while (tmp_source && tmp_source->priority <= source->priority)
696     {
697       last_source = tmp_source;
698       tmp_source = tmp_source->next;
699     }
700
701   source->next = tmp_source;
702   if (tmp_source)
703     tmp_source->prev = source;
704   
705   source->prev = last_source;
706   if (last_source)
707     last_source->next = source;
708   else
709     context->source_list = source;
710 }
711
712 /* Holds context's lock
713  */
714 static void
715 g_source_list_remove (GSource      *source,
716                       GMainContext *context)
717 {
718   if (source->prev)
719     source->prev->next = source->next;
720   else
721     context->source_list = source->next;
722
723   if (source->next)
724     source->next->prev = source->prev;
725
726   source->prev = NULL;
727   source->next = NULL;
728 }
729
730 /**
731  * g_source_attach:
732  * @source: a #GSource
733  * @context: a #GMainContext (if %NULL, the default context will be used)
734  * 
735  * Adds a #GSource to a @context so that it will be executed within
736  * that context.
737  *
738  * Return value: the ID for the source within the #GMainContext
739  **/
740 guint
741 g_source_attach (GSource      *source,
742                  GMainContext *context)
743 {
744   guint result = 0;
745   GSList *tmp_list;
746
747   g_return_val_if_fail (source->context == NULL, 0);
748   g_return_val_if_fail (!SOURCE_DESTROYED (source), 0);
749   
750   if (!context)
751     context = g_main_context_default ();
752
753   LOCK_CONTEXT (context);
754
755   source->context = context;
756   result = source->id = context->next_id++;
757
758   source->ref_count++;
759   g_source_list_add (source, context);
760
761   tmp_list = source->poll_fds;
762   while (tmp_list)
763     {
764       g_main_context_add_poll_unlocked (context, source->priority, tmp_list->data);
765       tmp_list = tmp_list->next;
766     }
767
768 #ifdef G_THREADS_ENABLED
769   /* Now wake up the main loop if it is waiting in the poll() */
770   g_main_context_wakeup (context);
771 #endif
772
773   UNLOCK_CONTEXT (context);
774
775   return result;
776 }
777
778 static void
779 g_source_destroy_internal (GSource      *source,
780                            GMainContext *context,
781                            gboolean      have_lock)
782 {
783   if (!have_lock)
784     LOCK_CONTEXT (context);
785   
786   if (!SOURCE_DESTROYED (source))
787     {
788       GSList *tmp_list;
789       gpointer old_cb_data;
790       GSourceCallbackFuncs *old_cb_funcs;
791       
792       source->flags &= ~G_HOOK_FLAG_ACTIVE;
793
794       old_cb_data = source->callback_data;
795       old_cb_funcs = source->callback_funcs;
796
797       source->callback_data = NULL;
798       source->callback_funcs = NULL;
799
800       if (old_cb_funcs)
801         {
802           UNLOCK_CONTEXT (context);
803           old_cb_funcs->unref (old_cb_data);
804           LOCK_CONTEXT (context);
805         }
806       
807       tmp_list = source->poll_fds;
808       while (tmp_list)
809         {
810           g_main_context_remove_poll_unlocked (context, tmp_list->data);
811           tmp_list = tmp_list->next;
812         }
813       
814       g_source_unref_internal (source, context, TRUE);
815     }
816
817   if (!have_lock)
818     UNLOCK_CONTEXT (context);
819 }
820
821 /**
822  * g_source_destroy:
823  * @source: a #GSource
824  * 
825  * Remove a source from its #GMainContext, if any, and mark it as
826  * destroyed.  The source cannot be subsequently added to another
827  * context.
828  **/
829 void
830 g_source_destroy (GSource *source)
831 {
832   GMainContext *context;
833   
834   g_return_if_fail (source != NULL);
835   
836   context = source->context;
837   
838   if (context)
839     g_source_destroy_internal (source, context, FALSE);
840   else
841     source->flags &= ~G_HOOK_FLAG_ACTIVE;
842 }
843
844 /**
845  * g_source_get_id:
846  * @source: a #GSource
847  * 
848  * Return the numeric ID for a particular source. The ID of a source
849  * is unique within a particular main loop context. The reverse
850  * mapping from ID to source is done by g_main_context_find_source_by_id().
851  *
852  * Return value: the ID for the source
853  **/
854 guint
855 g_source_get_id (GSource *source)
856 {
857   guint result;
858   
859   g_return_val_if_fail (source != NULL, 0);
860   g_return_val_if_fail (source->context != NULL, 0);
861
862   LOCK_CONTEXT (source->context);
863   result = source->id;
864   UNLOCK_CONTEXT (source->context);
865   
866   return result;
867 }
868
869 /**
870  * g_source_get_context:
871  * @source: a #GSource
872  * 
873  * Get the #GMainContext with which the source is associated.
874  * Calling this function on a destroyed source is an error.
875  * 
876  * Return value: the #GMainContext with which the source is associated,
877  *               or %NULL if the context has not yet been added
878  *               to a source.
879  **/
880 GMainContext *
881 g_source_get_context (GSource *source)
882 {
883   g_return_val_if_fail (!SOURCE_DESTROYED (source), NULL);
884
885   return source->context;
886 }
887
888 /**
889  * g_main_source_add_poll:
890  * @source:a #GSource 
891  * @fd: a #GPollFD structure holding information about a file
892  *      descriptor to watch.
893  * 
894  * Add a file descriptor to the set of file descriptors polled * for
895  * this source. This is usually combined with g_source_new() to add an
896  * event source. The event source's check function will typically test
897  * the revents field in the #GPollFD struct and return %TRUE if events need
898  * to be processed.
899  **/
900 void
901 g_source_add_poll (GSource *source,
902                    GPollFD *fd)
903 {
904   GMainContext *context;
905   
906   g_return_if_fail (source != NULL);
907   g_return_if_fail (fd != NULL);
908   g_return_if_fail (!SOURCE_DESTROYED (source));
909   
910   context = source->context;
911
912   if (context)
913     LOCK_CONTEXT (context);
914   
915   source->poll_fds = g_slist_prepend (source->poll_fds, fd);
916
917   if (context)
918     {
919       g_main_context_add_poll_unlocked (context, source->priority, fd);
920       UNLOCK_CONTEXT (context);
921     }
922 }
923
924 /**
925  * g_source_set_callback_indirect:
926  * @source: the source
927  * @callback_data: pointer to callback data "object"
928  * @callback_funcs: functions for reference counting callback_data
929  *                  and getting the callback and data
930  * 
931  * Set the callback function storing the data as a refcounted callback
932  * "object". This is used to implement g_source_set_callback_closure()
933  * and internally. Note that calling g_source_set_callback_indirect() assumes
934  * an initial reference count on @callback_data, and thus
935  * @callback_funcs->unref will eventually be called once more
936  * than @callback_funcs->ref.
937  **/
938 void
939 g_source_set_callback_indirect (GSource              *source,
940                                 gpointer              callback_data,
941                                 GSourceCallbackFuncs *callback_funcs)
942 {
943   GMainContext *context;
944   gpointer old_cb_data;
945   GSourceCallbackFuncs *old_cb_funcs;
946   
947   g_return_if_fail (source != NULL);
948   g_return_if_fail (callback_funcs != NULL || callback_data == NULL);
949
950   context = source->context;
951
952   if (context)
953     LOCK_CONTEXT (context);
954
955   old_cb_data = source->callback_data;
956   old_cb_funcs = source->callback_funcs;
957
958   source->callback_data = callback_data;
959   source->callback_funcs = callback_funcs;
960   
961   if (context)
962     UNLOCK_CONTEXT (context);
963   
964   if (old_cb_funcs)
965     old_cb_funcs->unref (old_cb_data);
966 }
967
968 static void
969 g_source_callback_ref (gpointer cb_data)
970 {
971   GSourceCallback *callback = cb_data;
972
973   callback->ref_count++;
974 }
975
976
977 static void
978 g_source_callback_unref (gpointer cb_data)
979 {
980   GSourceCallback *callback = cb_data;
981
982   callback->ref_count--;
983   if (callback->ref_count == 0)
984     {
985       if (callback->notify)
986         callback->notify (callback->data);
987     }
988 }
989
990 static void
991 g_source_callback_get (gpointer     cb_data,
992                        GSourceFunc *func,
993                        gpointer    *data)
994 {
995   GSourceCallback *callback = cb_data;
996
997   *func = callback->func;
998   *data = callback->data;
999 }
1000
1001 static GSourceCallbackFuncs g_source_callback_funcs = {
1002   g_source_callback_ref,
1003   g_source_callback_unref,
1004   g_source_callback_get,
1005 };
1006
1007 /**
1008  * g_source_set_callback:
1009  * @source: the source
1010  * @func: a callback function
1011  * @data: the data to pass to callback function
1012  * @notify: a function to call when @data is no longer in use, or %NULL.
1013  * 
1014  * Set the callback function for a source.
1015  **/
1016 void
1017 g_source_set_callback (GSource        *source,
1018                        GSourceFunc     func,
1019                        gpointer        data,
1020                        GDestroyNotify  notify)
1021 {
1022   GSourceCallback *new_callback;
1023
1024   g_return_if_fail (source != NULL);
1025
1026   new_callback = g_new (GSourceCallback, 1);
1027   
1028   new_callback->func = func;
1029   new_callback->data = data;
1030   new_callback->notify = notify;
1031
1032   g_source_set_callback_indirect (source, new_callback, &g_source_callback_funcs);
1033 }
1034
1035 /**
1036  * g_source_set_priority:
1037  * @source: a #GSource
1038  * @priority: the new priority.
1039  * 
1040  * Set the priority of a source. While the main loop is being
1041  * run, a source will 
1042  **/
1043 void
1044 g_source_set_priority (GSource  *source,
1045                        gint      priority)
1046 {
1047   GSList *tmp_list;
1048   GMainContext *context;
1049   
1050   g_return_if_fail (source != NULL);
1051
1052   context = source->context;
1053
1054   if (context)
1055     LOCK_CONTEXT (context);
1056   
1057   source->priority = priority;
1058
1059   if (context)
1060     {
1061       source->next = NULL;
1062       source->prev = NULL;
1063       
1064       tmp_list = source->poll_fds;
1065       while (tmp_list)
1066         {
1067           g_main_context_remove_poll_unlocked (context, tmp_list->data);
1068           g_main_context_add_poll_unlocked (context, priority, tmp_list->data);
1069       
1070           tmp_list = tmp_list->next;
1071         }
1072       
1073       UNLOCK_CONTEXT (source->context);
1074     }
1075 }
1076
1077 /**
1078  * g_source_get_priority:
1079  * @source: a #GSource
1080  * 
1081  * Gets the priority of a surce
1082  * 
1083  * Return value: the priority of the source
1084  **/
1085 gint
1086 g_source_get_priority (GSource *source)
1087 {
1088   g_return_val_if_fail (source != NULL, 0);
1089
1090   return source->priority;
1091 }
1092
1093 /**
1094  * g_source_set_can_recurse:
1095  * @source: a #GSource
1096  * @can_recurse: whether recursion is allowed for this source
1097  * 
1098  * Sets whether a source can be called recursively. If @can_recurse is
1099  * %TRUE, then while the source is being dispatched then this source
1100  * will be processed normally. Otherwise, all processing of this
1101  * source is blocked until the dispatch function returns.
1102  **/
1103 void
1104 g_source_set_can_recurse (GSource  *source,
1105                           gboolean  can_recurse)
1106 {
1107   GMainContext *context;
1108   
1109   g_return_if_fail (source != NULL);
1110
1111   context = source->context;
1112
1113   if (context)
1114     LOCK_CONTEXT (context);
1115   
1116   if (can_recurse)
1117     source->flags |= G_SOURCE_CAN_RECURSE;
1118   else
1119     source->flags &= ~G_SOURCE_CAN_RECURSE;
1120
1121   if (context)
1122     UNLOCK_CONTEXT (context);
1123 }
1124
1125 /**
1126  * g_source_get_can_recurse:
1127  * @source: a #GSource
1128  * 
1129  * Checks whether a source is allowed to be called recursively.
1130  * see g_source_set_can_recurse.
1131  * 
1132  * Return value: whether recursion is allowed.
1133  **/
1134 gboolean
1135 g_source_get_can_recurse (GSource  *source)
1136 {
1137   g_return_val_if_fail (source != NULL, FALSE);
1138   
1139   return (source->flags & G_SOURCE_CAN_RECURSE) != 0;
1140 }
1141
1142 /**
1143  * g_source_ref:
1144  * @source: a #GSource
1145  * 
1146  * Increases the reference count on a source by one.
1147  * 
1148  * Return value: @source
1149  **/
1150 GSource *
1151 g_source_ref (GSource *source)
1152 {
1153   GMainContext *context;
1154   
1155   g_return_val_if_fail (source != NULL, NULL);
1156
1157   context = source->context;
1158
1159   if (context)
1160     LOCK_CONTEXT (context);
1161
1162   source->ref_count++;
1163
1164   if (context)
1165     UNLOCK_CONTEXT (context);
1166
1167   return source;
1168 }
1169
1170 /* g_source_unref() but possible to call within context lock
1171  */
1172 static void
1173 g_source_unref_internal (GSource      *source,
1174                          GMainContext *context,
1175                          gboolean      have_lock)
1176 {
1177   gpointer old_cb_data = NULL;
1178   GSourceCallbackFuncs *old_cb_funcs = NULL;
1179
1180   g_return_if_fail (source != NULL);
1181   
1182   if (!have_lock && context)
1183     LOCK_CONTEXT (context);
1184
1185   source->ref_count--;
1186   if (source->ref_count == 0)
1187     {
1188       old_cb_data = source->callback_data;
1189       old_cb_funcs = source->callback_funcs;
1190
1191       source->callback_data = NULL;
1192       source->callback_funcs = NULL;
1193
1194       if (context && !SOURCE_DESTROYED (source))
1195         {
1196           g_warning (G_STRLOC ": ref_count == 0, but source is still attached to a context!");
1197           source->ref_count++;
1198         }
1199       else if (context)
1200         g_source_list_remove (source, context);
1201
1202       if (source->source_funcs->destroy)
1203         source->source_funcs->destroy (source);
1204       
1205       g_slist_free (source->poll_fds);
1206       source->poll_fds = NULL;
1207       g_free (source);
1208     }
1209   
1210   if (!have_lock && context)
1211     UNLOCK_CONTEXT (context);
1212
1213   if (old_cb_funcs)
1214     {
1215       if (have_lock)
1216         UNLOCK_CONTEXT (context);
1217       
1218       old_cb_funcs->unref (old_cb_data);
1219
1220       if (have_lock)
1221         LOCK_CONTEXT (context);
1222     }
1223 }
1224
1225 /**
1226  * g_source_unref:
1227  * @source: a #GSource
1228  * 
1229  * Decreases the reference count of a source by one. If the
1230  * resulting reference count is zero the source and associated
1231  * memory will be destroyed. 
1232  **/
1233 void
1234 g_source_unref (GSource *source)
1235 {
1236   g_return_if_fail (source != NULL);
1237
1238   g_source_unref_internal (source, source->context, FALSE);
1239 }
1240
1241 /**
1242  * g_main_context_find_source_by_id:
1243  * @context: a #GMainContext (if %NULL, the default context will be used)
1244  * @id: the source ID, as returned by g_source_get_id()
1245  * 
1246  * Finds a #GSource given a pair of context and ID
1247  * 
1248  * Return value: the #GSource if found, otherwise, %NULL
1249  **/
1250 GSource *
1251 g_main_context_find_source_by_id (GMainContext *context,
1252                                   guint         id)
1253 {
1254   GSource *source;
1255   
1256   g_return_val_if_fail (id > 0, FALSE);
1257
1258   if (context == NULL)
1259     context = g_main_context_default ();
1260   
1261   LOCK_CONTEXT (context);
1262   
1263   source = context->source_list;
1264   while (source)
1265     {
1266       if (!SOURCE_DESTROYED (source) &&
1267           source->id == id)
1268         break;
1269       source = source->next;
1270     }
1271
1272   UNLOCK_CONTEXT (context);
1273
1274   return source;
1275 }
1276
1277 /**
1278  * g_main_context_find_source_by_funcs_user_data:
1279  * @context: a #GMainContext (if %NULL, the default context will be used).
1280  * @funcs: the @source_funcs passed to g_source_new().
1281  * @user_data: the user data from the callback.
1282  * 
1283  * Finds a source with the given source functions and user data.  If
1284  * multiple sources exist with the same source function and user data,
1285  * the first one found will be returned.
1286  * 
1287  * Return value: the source, if one was found, otherwise %NULL
1288  **/
1289 GSource *
1290 g_main_context_find_source_by_funcs_user_data (GMainContext *context,
1291                                                GSourceFuncs *funcs,
1292                                                gpointer      user_data)
1293 {
1294   GSource *source;
1295   
1296   g_return_val_if_fail (funcs != NULL, FALSE);
1297
1298   if (context == NULL)
1299     context = g_main_context_default ();
1300   
1301   LOCK_CONTEXT (context);
1302
1303   source = context->source_list;
1304   while (source)
1305     {
1306       if (!SOURCE_DESTROYED (source) &&
1307           source->source_funcs == funcs &&
1308           source->callback_data == user_data)
1309         break;
1310       source = source->next;
1311     }
1312
1313   UNLOCK_CONTEXT (context);
1314
1315   return source;
1316 }
1317
1318 /**
1319  * g_main_context_find_source_by_user_data:
1320  * @context: a #GMainContext
1321  * @user_data: the user_data for the callback.
1322  * 
1323  * Finds a source with the given user data for the callback.  If
1324  * multiple sources exist with the same user data, the first
1325  * one found will be returned.
1326  * 
1327  * Return value: the source, if one was found, otherwise %NULL
1328  **/
1329 GSource *
1330 g_main_context_find_source_by_user_data (GMainContext *context,
1331                                          gpointer      user_data)
1332 {
1333   GSource *source;
1334   
1335   if (context == NULL)
1336     context = g_main_context_default ();
1337   
1338   LOCK_CONTEXT (context);
1339
1340   source = context->source_list;
1341   while (source)
1342     {
1343       if (!SOURCE_DESTROYED (source) &&
1344           source->callback_data == user_data)
1345         break;
1346       source = source->next;
1347     }
1348
1349   UNLOCK_CONTEXT (context);
1350
1351   return source;
1352 }
1353
1354 /**
1355  * g_source_remove:
1356  * @tag: the id of the source to remove.
1357  * 
1358  * Removes the source with the given id from the default main
1359  * context. The id of a #GSource is given by g_source_get_id(),
1360  * or will be returned by the functions g_source_attach(),
1361  * g_idle_add(), g_idle_add_full(), g_timeout_add(),
1362  * g_timeout_add_full(), g_io_add_watch, and g_io_add_watch_full().
1363  *
1364  * See also g_source_destroy().
1365  *
1366  * Return value: %TRUE if the source was found and removed.
1367  **/
1368 gboolean
1369 g_source_remove (guint tag)
1370 {
1371   GSource *source;
1372   
1373   g_return_val_if_fail (tag > 0, FALSE);
1374
1375   source = g_main_context_find_source_by_id (NULL, tag);
1376   if (source)
1377     g_source_destroy (source);
1378
1379   return source != NULL;
1380 }
1381
1382 /**
1383  * g_source_remove_by_user_data:
1384  * @user_data: the user_data for the callback.
1385  * 
1386  * Removes a source from the default main loop context given the user
1387  * data for the callback. If multiple sources exist with the same user
1388  * data, only one will be destroyed.
1389  * 
1390  * Return value: %TRUE if a source was found and removed. 
1391  **/
1392 gboolean
1393 g_source_remove_by_user_data (gpointer user_data)
1394 {
1395   GSource *source;
1396   
1397   source = g_main_context_find_source_by_user_data (NULL, user_data);
1398   if (source)
1399     {
1400       g_source_destroy (source);
1401       return TRUE;
1402     }
1403   else
1404     return FALSE;
1405 }
1406
1407 /**
1408  * g_source_remove_by_funcs_user_data:
1409  * @funcs: The @source_funcs passed to g_source_new()
1410  * @user_data: the user data for the callback
1411  * 
1412  * Removes a source from the default main loop context given the
1413  * source functions and user data. If multiple sources exist with the
1414  * same source functions and user data, only one will be destroyed.
1415  * 
1416  * Return value: %TRUE if a source was found and removed. 
1417  **/
1418 gboolean
1419 g_source_remove_by_funcs_user_data (GSourceFuncs *funcs,
1420                                     gpointer      user_data)
1421 {
1422   GSource *source;
1423
1424   g_return_val_if_fail (funcs != NULL, FALSE);
1425
1426   source = g_main_context_find_source_by_funcs_user_data (NULL, funcs, user_data);
1427   if (source)
1428     {
1429       g_source_destroy (source);
1430       return TRUE;
1431     }
1432   else
1433     return FALSE;
1434 }
1435
1436 /**
1437  * g_get_current_time:
1438  * @result: #GTimeVal structure in which to store current time.
1439  * 
1440  * Equivalent to Unix's <function>gettimeofday()</function>, but portable
1441  **/
1442 void
1443 g_get_current_time (GTimeVal *result)
1444 {
1445 #ifndef G_OS_WIN32
1446   struct timeval r;
1447
1448   g_return_if_fail (result != NULL);
1449
1450   /*this is required on alpha, there the timeval structs are int's
1451     not longs and a cast only would fail horribly*/
1452   gettimeofday (&r, NULL);
1453   result->tv_sec = r.tv_sec;
1454   result->tv_usec = r.tv_usec;
1455 #else
1456   /* Avoid calling time() except for the first time.
1457    * GetTickCount() should be pretty fast and low-level?
1458    * I could also use ftime() but it seems unnecessarily overheady.
1459    */
1460   static DWORD start_tick = 0;
1461   static time_t start_time;
1462   DWORD tick;
1463
1464   g_return_if_fail (result != NULL);
1465  
1466   if (start_tick == 0)
1467     {
1468       start_tick = GetTickCount ();
1469       time (&start_time);
1470     }
1471
1472   tick = GetTickCount ();
1473
1474   result->tv_sec = (tick - start_tick) / 1000 + start_time;
1475   result->tv_usec = ((tick - start_tick) % 1000) * 1000;
1476 #endif
1477 }
1478
1479 /* Running the main loop */
1480
1481 /* HOLDS: context's lock */
1482 static void
1483 g_main_dispatch (GMainContext *context)
1484 {
1485   gint i;
1486
1487   for (i = 0; i < context->pending_dispatches->len; i++)
1488     {
1489       GSource *source = context->pending_dispatches->pdata[i];
1490
1491       context->pending_dispatches->pdata[i] = NULL;
1492       g_assert (source);
1493
1494       source->flags &= ~G_SOURCE_READY;
1495
1496       if (!SOURCE_DESTROYED (source))
1497         {
1498           gboolean was_in_call;
1499           gpointer user_data = NULL;
1500           GSourceFunc callback = NULL;
1501           GSourceCallbackFuncs *cb_funcs;
1502           gpointer cb_data;
1503           gboolean need_destroy;
1504
1505           gboolean (*dispatch) (GSource *,
1506                                 GSourceFunc,
1507                                 gpointer);
1508
1509           dispatch = source->source_funcs->dispatch;
1510           cb_funcs = source->callback_funcs;
1511           cb_data = source->callback_data;
1512
1513           if (cb_funcs)
1514             cb_funcs->ref (cb_data);
1515           
1516           was_in_call = source->flags & G_HOOK_FLAG_IN_CALL;
1517           source->flags |= G_HOOK_FLAG_IN_CALL;
1518
1519           UNLOCK_CONTEXT (context);
1520
1521           if (cb_funcs)
1522             cb_funcs->get (cb_data, &callback, &user_data);
1523
1524           need_destroy = ! dispatch (source,
1525                                      callback,
1526                                      user_data);
1527           LOCK_CONTEXT (context);
1528
1529           if (cb_funcs)
1530             cb_funcs->unref (cb_data);
1531
1532          if (!was_in_call)
1533             source->flags &= ~G_HOOK_FLAG_IN_CALL;
1534
1535           /* Note: this depends on the fact that we can't switch
1536            * sources from one main context to another
1537            */
1538           if (need_destroy && !SOURCE_DESTROYED (source))
1539             {
1540               g_assert (source->context == context);
1541               g_source_destroy_internal (source, context, TRUE);
1542             }
1543         }
1544       
1545       SOURCE_UNREF (source, context);
1546     }
1547
1548   g_ptr_array_set_size (context->pending_dispatches, 0);
1549 }
1550
1551 /* Holds context's lock */
1552 static inline GSource *
1553 next_valid_source (GMainContext *context,
1554                    GSource      *source)
1555 {
1556   GSource *new_source = source ? source->next : context->source_list;
1557
1558   while (new_source)
1559     {
1560       if (!SOURCE_DESTROYED (new_source))
1561         {
1562           new_source->ref_count++;
1563           break;
1564         }
1565       
1566       new_source = new_source->next;
1567     }
1568
1569   if (source)
1570     SOURCE_UNREF (source, context);
1571           
1572   return new_source;
1573 }
1574
1575
1576 /**
1577  * g_main_context_prepare:
1578  * @context: a #GMainContext
1579  * @priority: location to store priority of highest priority
1580  *            source already ready.
1581  * 
1582  * Prepares to poll sources within a main loop. The resulting information
1583  * for polling is determined by calling g_main_context_query ().
1584  * 
1585  * Return value: %TRUE if some source is ready to be dispatched
1586  *               prior to polling.
1587  **/
1588 gboolean
1589 g_main_context_prepare (GMainContext *context,
1590                         gint         *priority)
1591 {
1592   gint n_ready = 0;
1593   gint current_priority = G_MAXINT;
1594   GSource *source;
1595
1596   if (context == NULL)
1597     context = g_main_context_default ();
1598   
1599   LOCK_CONTEXT (context);
1600
1601   context->time_is_current = FALSE;
1602
1603   if (context->in_check_or_prepare)
1604     {
1605       g_warning ("g_main_context_prepare() called recursively from within a source's check() or "
1606                  "prepare() member.");
1607       return FALSE;
1608     }
1609
1610 #ifdef G_THREADS_ENABLED
1611   if (context->poll_waiting)
1612     {
1613       g_warning("g_main_context_prepare(): main loop already active in another thread");
1614       UNLOCK_CONTEXT (context);
1615       return FALSE;
1616     }
1617   
1618   context->poll_waiting = TRUE;
1619 #endif /* G_THREADS_ENABLED */
1620
1621 #if 0
1622   /* If recursing, finish up current dispatch, before starting over */
1623   if (context->pending_dispatches)
1624     {
1625       if (dispatch)
1626         g_main_dispatch (context, &current_time);
1627       
1628       UNLOCK_CONTEXT (context);
1629       return TRUE;
1630     }
1631 #endif
1632
1633   /* If recursing, clear list of pending dispatches */
1634   g_ptr_array_set_size (context->pending_dispatches, 0);
1635   
1636   /* Prepare all sources */
1637
1638   context->timeout = -1;
1639   
1640   source = next_valid_source (context, NULL);
1641   while (source)
1642     {
1643       gint source_timeout = -1;
1644
1645       if ((n_ready > 0) && (source->priority > current_priority))
1646         {
1647           SOURCE_UNREF (source, context);
1648           break;
1649         }
1650       if ((source->flags & G_HOOK_FLAG_IN_CALL) && !(source->flags & G_SOURCE_CAN_RECURSE))
1651         goto next;
1652
1653       if (!(source->flags & G_SOURCE_READY))
1654         {
1655           gboolean result;
1656           gboolean (*prepare)  (GSource  *source, 
1657                                 gint     *timeout);
1658
1659           prepare = source->source_funcs->prepare;
1660           context->in_check_or_prepare++;
1661           UNLOCK_CONTEXT (context);
1662
1663           result = (*prepare) (source, &source_timeout);
1664
1665           LOCK_CONTEXT (context);
1666           context->in_check_or_prepare--;
1667
1668           if (result)
1669             source->flags |= G_SOURCE_READY;
1670         }
1671
1672       if (source->flags & G_SOURCE_READY)
1673         {
1674           n_ready++;
1675           current_priority = source->priority;
1676           context->timeout = 0;
1677         }
1678       
1679       if (source_timeout >= 0)
1680         {
1681           if (context->timeout < 0)
1682             context->timeout = source_timeout;
1683           else
1684             context->timeout = MIN (context->timeout, source_timeout);
1685         }
1686
1687     next:
1688       source = next_valid_source (context, source);
1689     }
1690
1691   UNLOCK_CONTEXT (context);
1692   
1693   if (priority)
1694     *priority = current_priority;
1695   
1696   return (n_ready > 0);
1697 }
1698
1699 /**
1700  * g_main_context_query:
1701  * @context: a #GMainContext
1702  * @max_priority: maximum priority source to check
1703  * @timeout: location to store timeout to be used in polling
1704  * @fds: location to store #GPollFD records that need to be polled.
1705  * @n_fds: length of @fds.
1706  * 
1707  * Determines information necessary to poll this main loop.
1708  * 
1709  * Return value: 
1710  **/
1711 gint
1712 g_main_context_query (GMainContext *context,
1713                       gint          max_priority,
1714                       gint         *timeout,
1715                       GPollFD      *fds,
1716                       gint          n_fds)
1717 {
1718   gint n_poll;
1719   GPollRec *pollrec;
1720   
1721   LOCK_CONTEXT (context);
1722
1723   pollrec = context->poll_records;
1724   n_poll = 0;
1725   while (pollrec && max_priority >= pollrec->priority)
1726     {
1727       if (pollrec->fd->events)
1728         {
1729           if (n_poll < n_fds)
1730             {
1731               fds[n_poll].fd = pollrec->fd->fd;
1732               /* In direct contradiction to the Unix98 spec, IRIX runs into
1733                * difficulty if you pass in POLLERR, POLLHUP or POLLNVAL
1734                * flags in the events field of the pollfd while it should
1735                * just ignoring them. So we mask them out here.
1736                */
1737               fds[n_poll].events = pollrec->fd->events & ~(G_IO_ERR|G_IO_HUP|G_IO_NVAL);
1738               fds[n_poll].revents = 0;
1739             }
1740           n_poll++;
1741         }
1742       
1743       pollrec = pollrec->next;
1744     }
1745
1746 #ifdef G_THREADS_ENABLED
1747   context->poll_changed = FALSE;
1748 #endif
1749   
1750   if (timeout)
1751     {
1752       *timeout = context->timeout;
1753       if (timeout != 0)
1754         context->time_is_current = FALSE;
1755     }
1756   
1757   UNLOCK_CONTEXT (context);
1758
1759   return n_poll;
1760 }
1761
1762 /**
1763  * g_main_context_check:
1764  * @context: a #GMainContext
1765  * @max_priority: the maximum numerical priority of sources to check
1766  * @fds: array of #GPollFD's that was passed to the last call to
1767  *       g_main_context_query()
1768  * @n_fds: return value of g_main_context_query()
1769  * 
1770  * Pass the results of polling back to the main loop.
1771  * 
1772  * Return value: %TRUE if some sources are ready to be dispatched.
1773  **/
1774 gboolean
1775 g_main_context_check (GMainContext *context,
1776                       gint          max_priority,
1777                       GPollFD      *fds,
1778                       gint          n_fds)
1779 {
1780   GSource *source;
1781   GPollRec *pollrec;
1782   gint n_ready = 0;
1783   gint i;
1784   
1785   LOCK_CONTEXT (context);
1786
1787   if (context->in_check_or_prepare)
1788     {
1789       g_warning ("g_main_context_check() called recursively from within a source's check() or "
1790                  "prepare() member.");
1791       return FALSE;
1792     }
1793   
1794 #ifdef G_THREADS_ENABLED
1795   if (!context->poll_waiting)
1796     {
1797 #ifndef G_OS_WIN32
1798       gchar c;
1799       read (context->wake_up_pipe[0], &c, 1);
1800 #endif
1801     }
1802   else
1803     context->poll_waiting = FALSE;
1804
1805   /* If the set of poll file descriptors changed, bail out
1806    * and let the main loop rerun
1807    */
1808   if (context->poll_changed)
1809     return 0;
1810 #endif /* G_THREADS_ENABLED */
1811   
1812   pollrec = context->poll_records;
1813   i = 0;
1814   while (i < n_fds)
1815     {
1816       if (pollrec->fd->events)
1817         {
1818           pollrec->fd->revents = fds[i].revents;
1819           i++;
1820         }
1821       pollrec = pollrec->next;
1822     }
1823
1824   source = next_valid_source (context, NULL);
1825   while (source)
1826     {
1827       if ((n_ready > 0) && (source->priority > max_priority))
1828         {
1829           SOURCE_UNREF (source, context);
1830           break;
1831         }
1832       if ((source->flags & G_HOOK_FLAG_IN_CALL) && !(source->flags & G_SOURCE_CAN_RECURSE))
1833         goto next;
1834
1835       if (!(source->flags & G_SOURCE_READY))
1836         {
1837           gboolean result;
1838           gboolean (*check) (GSource  *source);
1839
1840           check = source->source_funcs->check;
1841           
1842           context->in_check_or_prepare++;
1843           UNLOCK_CONTEXT (context);
1844           
1845           result = (*check) (source);
1846           
1847           LOCK_CONTEXT (context);
1848           context->in_check_or_prepare--;
1849           
1850           if (result)
1851             source->flags |= G_SOURCE_READY;
1852         }
1853
1854       if (source->flags & G_SOURCE_READY)
1855         {
1856           source->ref_count++;
1857           g_ptr_array_add (context->pending_dispatches, source);
1858
1859           n_ready++;
1860         }
1861
1862     next:
1863       source = next_valid_source (context, source);
1864     }
1865
1866   UNLOCK_CONTEXT (context);
1867
1868   return n_ready > 0;
1869 }
1870
1871 /**
1872  * g_main_context_dispatch:
1873  * @context: a #GMainContext
1874  * 
1875  * Dispatch all pending sources()
1876  **/
1877 void
1878 g_main_context_dispatch (GMainContext *context)
1879 {
1880   LOCK_CONTEXT (context);
1881
1882   if (context->pending_dispatches->len > 0)
1883     {
1884       g_main_dispatch (context);
1885     }
1886
1887   UNLOCK_CONTEXT (context);
1888 }
1889
1890 static gboolean
1891 g_main_context_iterate (GMainContext *context,
1892                         gboolean      block,
1893                         gboolean      dispatch)
1894 {
1895   gint max_priority;
1896   gint timeout;
1897   gboolean some_ready;
1898   gint nfds, new_nfds;
1899   GPollFD *fds;
1900   
1901   some_ready = g_main_context_prepare (context, &max_priority);
1902
1903   do
1904     {
1905       LOCK_CONTEXT (context);
1906
1907       if (context->cached_poll_array)
1908         {
1909           nfds = context->cached_poll_array_size;
1910           fds = context->cached_poll_array;
1911           context->cached_poll_array = NULL;
1912         }
1913       else
1914         {
1915           nfds = context->cached_poll_array_size = context->n_poll_records;
1916           fds = g_new (GPollFD, nfds);
1917         }
1918
1919       UNLOCK_CONTEXT (context);
1920   
1921       new_nfds = g_main_context_query (context, max_priority,
1922                                        &timeout, fds, nfds);
1923     }
1924   while (new_nfds > nfds);
1925
1926   if (!block)
1927     timeout = 0;
1928   
1929   g_main_context_poll (context, timeout, max_priority,
1930                        fds, new_nfds);
1931
1932   g_main_context_check (context,
1933                         max_priority,
1934                         fds, new_nfds);
1935
1936   LOCK_CONTEXT (context);
1937
1938   g_assert (!context->cached_poll_array);
1939   
1940   context->cached_poll_array = fds;
1941   context->cached_poll_array_size = nfds;
1942
1943   UNLOCK_CONTEXT (context);
1944   
1945   if (dispatch)
1946     g_main_context_dispatch (context);
1947
1948   return some_ready;
1949 }
1950
1951 /**
1952  * g_main_context_pending:
1953  * @context: a #GMainContext (if %NULL, the default context will be used)
1954  *
1955  * Check if any sources have pending events for the given context.
1956  * 
1957  * Return value: %TRUE if events are pending.
1958  **/
1959 gboolean 
1960 g_main_context_pending (GMainContext *context)
1961 {
1962   if (!context)
1963     context = g_main_context_default();
1964   
1965   return g_main_context_iterate (context, FALSE, FALSE);
1966 }
1967
1968 /**
1969  * g_main_context_iteration:
1970  * @context: a #GMainContext (if %NULL, the default context will be used) 
1971  * @may_block: whether the call may block.
1972  * 
1973  * Run a single iteration for the given main loop. This involves
1974  * checking to see if any event sources are ready to be processed,
1975  * then if no events sources are ready and @may_block is %TRUE, waiting
1976  * for a source to become ready, then dispatching the highest priority
1977  * events sources that are ready. Note that even when @may_block is %TRUE,
1978  * it is still possible for g_main_context_iteration() to return
1979  * %FALSE, since the the wait may be interrupted for other
1980  * reasons than an event source becoming ready.
1981  * 
1982  * Return value: %TRUE if events were dispatched.
1983  **/
1984 gboolean
1985 g_main_context_iteration (GMainContext *context, gboolean may_block)
1986 {
1987   if (!context)
1988     context = g_main_context_default();
1989   
1990   return g_main_context_iterate (context, may_block, TRUE);
1991 }
1992
1993 /**
1994  * g_main_loop_new:
1995  * @context: a #GMainContext  (if %NULL, the default context will be used).
1996  * @is_running: set to TRUE to indicate that the loop is running. This
1997  * is not very important since calling g_main_run() will set this to
1998  * TRUE anyway.
1999  * 
2000  * Create a new #GMainLoop structure
2001  * 
2002  * Return value: 
2003  **/
2004 GMainLoop *
2005 g_main_loop_new (GMainContext *context,
2006                  gboolean      is_running)
2007 {
2008   GMainLoop *loop;
2009   
2010   if (!context)
2011     context = g_main_context_default();
2012   
2013   loop = g_new0 (GMainLoop, 1);
2014   loop->context = context;
2015   loop->is_running = is_running != FALSE;
2016   loop->ref_count = 1;
2017   
2018 #ifdef G_THREADS_ENABLED
2019   if (g_thread_supported ())
2020     loop->mutex = g_mutex_new ();
2021   else
2022     loop->mutex = NULL;
2023   loop->sem_cond = NULL;
2024 #endif /* G_THREADS_ENABLED */
2025
2026   return loop;
2027 }
2028
2029 /**
2030  * g_main_loop_ref:
2031  * @loop: a #GMainLoop
2032  * 
2033  * Increase the reference count on a #GMainLoop object by one.
2034  * 
2035  * Return value: @loop
2036  **/
2037 GMainLoop *
2038 g_main_loop_ref (GMainLoop *loop)
2039 {
2040   g_return_val_if_fail (loop != NULL, NULL);
2041
2042   LOCK_LOOP (loop);
2043   loop->ref_count++;
2044   UNLOCK_LOOP (loop);
2045
2046   return loop;
2047 }
2048
2049 static void
2050 main_loop_destroy (GMainLoop *loop)
2051 {
2052 #ifdef G_THREADS_ENABLED
2053   g_mutex_free (loop->mutex);
2054   if (loop->sem_cond)
2055     g_cond_free (loop->sem_cond);
2056 #endif /* G_THREADS_ENABLED */  
2057   
2058   g_free (loop);
2059 }
2060
2061 /**
2062  * g_main_loop_unref:
2063  * @loop: a #GMainLoop
2064  * 
2065  * Decreases the reference count on a #GMainLoop object by one. If
2066  * the result is zero, free the loop and free all associated memory.
2067  **/
2068 void
2069 g_main_loop_unref (GMainLoop *loop)
2070 {
2071   g_return_if_fail (loop != NULL);
2072   g_return_if_fail (loop->ref_count > 0);
2073
2074   LOCK_LOOP (loop);
2075   
2076   loop->ref_count--;
2077   if (loop->ref_count == 0)
2078     {
2079       /* When the ref_count is 0, there can be nobody else using the
2080        * loop, so it is safe to unlock before destroying.
2081        */
2082       UNLOCK_LOOP (loop);
2083       main_loop_destroy (loop);
2084     }
2085   else
2086     UNLOCK_LOOP (loop);
2087 }
2088
2089 /**
2090  * g_main_loop_run:
2091  * @loop: a #GMainLoop
2092  * 
2093  * Run a main loop until g_main_quit() is called on the loop.
2094  * If this is called for the thread of the loop's #GMainContext,
2095  * it will process events from the loop, otherwise it will
2096  * simply wait.
2097  **/
2098 void 
2099 g_main_loop_run (GMainLoop *loop)
2100 {
2101   g_return_if_fail (loop != NULL);
2102
2103   /* The assumption here is that a reference is held to the loop
2104    * until we recursively iterate
2105    */
2106 #ifdef G_THREADS_ENABLED
2107   if (loop->context->thread != g_thread_self ())
2108     {
2109       LOCK_LOOP (loop);
2110
2111       loop->ref_count++;
2112       
2113       if (!g_thread_supported ())
2114         {
2115           g_warning ("g_main_loop_run() was called from second thread but"
2116                      "g_thread_init() was never called.");
2117         }
2118       else
2119         {
2120           if (!loop->sem_cond)
2121             loop->sem_cond = g_cond_new ();
2122           
2123           if (!loop->is_running)
2124             loop->is_running = TRUE;
2125           
2126           while (loop->is_running)
2127             g_cond_wait (loop->sem_cond, loop->mutex);
2128         }
2129     }
2130   else
2131 #endif /* G_THREADS_ENABLED */    
2132     {
2133       LOCK_CONTEXT (loop->context);
2134       if (loop->context->in_check_or_prepare)
2135         {
2136           g_warning ("g_main_run(): called recursively from within a source's check() or "
2137                      "prepare() member, iteration not possible.");
2138           return;
2139         }
2140       UNLOCK_CONTEXT (loop->context);
2141       
2142       LOCK_LOOP (loop);
2143
2144       loop->ref_count++;
2145       loop->is_running = TRUE;
2146       while (loop->is_running)
2147         {
2148           UNLOCK_LOOP (loop);
2149           g_main_context_iterate (loop->context, TRUE, TRUE);
2150           LOCK_LOOP (loop);
2151         }
2152     }
2153
2154   /* We inline this here rather than calling g_main_loop_unref() to
2155    * avoid an extra unlock/lock.
2156    */
2157   loop->ref_count--;
2158   if (loop->ref_count == 0)
2159     {
2160       UNLOCK_LOOP (loop);
2161       main_loop_destroy (loop);
2162     }
2163   else
2164     UNLOCK_LOOP (loop);
2165 }
2166
2167 /**
2168  * g_main_loop_quit:
2169  * @loop: a #GMainLoop
2170  * 
2171  * Stops a #GMainLoop from running. Any calls to g_main_loop_run()
2172  * for the loop will return.
2173  **/
2174 void 
2175 g_main_loop_quit (GMainLoop *loop)
2176 {
2177   g_return_if_fail (loop != NULL);
2178
2179   LOCK_LOOP (loop);
2180   loop->is_running = FALSE;
2181
2182 #ifdef G_THREADS_ENABLED
2183   if (loop->sem_cond)
2184     g_cond_broadcast (loop->sem_cond);
2185 #endif
2186   
2187   UNLOCK_LOOP (loop);
2188
2189   LOCK_CONTEXT (loop->context);
2190   
2191   g_main_context_wakeup (loop->context);
2192   UNLOCK_CONTEXT (loop->context);
2193 }
2194
2195 /**
2196  * g_main_loop_is_running:
2197  * @loop: a #GMainLoop.
2198  * 
2199  * Check to see if the main loop is currently being run via g_main_run()
2200  * 
2201  * Return value: %TRUE if the mainloop is currently being run.
2202  **/
2203 gboolean
2204 g_main_loop_is_running (GMainLoop *loop)
2205 {
2206   gboolean result;
2207   
2208   g_return_val_if_fail (loop != NULL, FALSE);
2209
2210   LOCK_LOOP (loop);
2211   result = loop->is_running;
2212   UNLOCK_LOOP (loop);
2213
2214   return result;
2215 }
2216
2217 /* HOLDS: context's lock */
2218 static void
2219 g_main_context_poll (GMainContext *context,
2220                      gint          timeout,
2221                      gint          priority,
2222                      GPollFD      *fds,
2223                      gint          n_fds)
2224 {
2225 #ifdef  G_MAIN_POLL_DEBUG
2226   GTimer *poll_timer;
2227   GPollRec *pollrec;
2228   gint i;
2229 #endif
2230
2231   GPollFunc poll_func;
2232
2233   if (n_fds || timeout != 0)
2234     {
2235 #ifdef  G_MAIN_POLL_DEBUG
2236       g_print ("g_main_poll(%d) timeout: %d\n", n_fds, timeout);
2237       poll_timer = g_timer_new ();
2238 #endif
2239
2240       LOCK_CONTEXT (context);
2241
2242       poll_func = context->poll_func;
2243       
2244       UNLOCK_CONTEXT (context);
2245       if ((*poll_func) (fds, n_fds, timeout) < 0 && errno != EINTR)
2246         g_warning ("poll(2) failed due to: %s.",
2247                    g_strerror (errno));
2248       
2249 #ifdef  G_MAIN_POLL_DEBUG
2250       LOCK_CONTEXT (context);
2251
2252       g_print ("g_main_poll(%d) timeout: %d - elapsed %12.10f seconds",
2253                n_fds,
2254                timeout,
2255                g_timer_elapsed (poll_timer, NULL));
2256       g_timer_destroy (poll_timer);
2257       pollrec = context->poll_records;
2258       i = 0;
2259       while (i < n_fds)
2260         {
2261           if (pollrec->fd->events)
2262             {
2263               if (fds[i].revents)
2264                 {
2265                   g_print (" [%d:", fds[i].fd);
2266                   if (fds[i].revents & G_IO_IN)
2267                     g_print ("i");
2268                   if (fds[i].revents & G_IO_OUT)
2269                     g_print ("o");
2270                   if (fds[i].revents & G_IO_PRI)
2271                     g_print ("p");
2272                   if (fds[i].revents & G_IO_ERR)
2273                     g_print ("e");
2274                   if (fds[i].revents & G_IO_HUP)
2275                     g_print ("h");
2276                   if (fds[i].revents & G_IO_NVAL)
2277                     g_print ("n");
2278                   g_print ("]");
2279                 }
2280               i++;
2281             }
2282           pollrec = pollrec->next;
2283         }
2284       g_print ("\n");
2285       
2286       UNLOCK_CONTEXT (context);
2287 #endif
2288     } /* if (n_fds || timeout != 0) */
2289 }
2290
2291 /**
2292  * g_main_context_add_poll:
2293  * @context: a #GMainContext (or %NULL for the default context)
2294  * @fd: a #GPollFD structure holding information about a file
2295  *      descriptor to watch.
2296  * @priority: the priority for this file descriptor which should be
2297  *      the same as the priority used for g_source_attach() to ensure that the
2298  *      file descriptor is polled whenever the results may be needed.
2299  * 
2300  * Add a file descriptor to the set of file descriptors polled * for
2301  * this context. This will very seldom be used directly. Instead
2302  * a typical event source will use g_source_add_poll() instead.
2303  **/
2304 void
2305 g_main_context_add_poll (GMainContext *context,
2306                          GPollFD      *fd,
2307                          gint          priority)
2308 {
2309   if (!context)
2310     context = g_main_context_default ();
2311   
2312   LOCK_CONTEXT (context);
2313   g_main_context_add_poll_unlocked (context, priority, fd);
2314   UNLOCK_CONTEXT (context);
2315 }
2316
2317 /* HOLDS: main_loop_lock */
2318 static void 
2319 g_main_context_add_poll_unlocked (GMainContext *context,
2320                                   gint          priority,
2321                                   GPollFD      *fd)
2322 {
2323   GPollRec *lastrec, *pollrec, *newrec;
2324
2325   if (!context->poll_chunk)
2326     context->poll_chunk = g_mem_chunk_create (GPollRec, 32, G_ALLOC_ONLY);
2327
2328   if (context->poll_free_list)
2329     {
2330       newrec = context->poll_free_list;
2331       context->poll_free_list = newrec->next;
2332     }
2333   else
2334     newrec = g_chunk_new (GPollRec, context->poll_chunk);
2335
2336   /* This file descriptor may be checked before we ever poll */
2337   fd->revents = 0;
2338   newrec->fd = fd;
2339   newrec->priority = priority;
2340
2341   lastrec = NULL;
2342   pollrec = context->poll_records;
2343   while (pollrec && priority >= pollrec->priority)
2344     {
2345       lastrec = pollrec;
2346       pollrec = pollrec->next;
2347     }
2348   
2349   if (lastrec)
2350     lastrec->next = newrec;
2351   else
2352     context->poll_records = newrec;
2353
2354   newrec->next = pollrec;
2355
2356   context->n_poll_records++;
2357   if (context->cached_poll_array &&
2358       context->cached_poll_array_size < context->n_poll_records)
2359     {
2360       g_free (context->cached_poll_array);
2361       context->cached_poll_array = NULL;
2362     }
2363
2364 #ifdef G_THREADS_ENABLED
2365   context->poll_changed = TRUE;
2366
2367   /* Now wake up the main loop if it is waiting in the poll() */
2368   g_main_context_wakeup (context);
2369 #endif
2370 }
2371
2372 /**
2373  * g_main_context_remove_poll:
2374  * @context:a #GMainContext 
2375  * @fd: a #GPollFD descriptor previously added with g_main_context_add_poll()
2376  * 
2377  * Remove file descriptor from the set of file descriptors to be
2378  * polled for a particular context.
2379  **/
2380 void
2381 g_main_context_remove_poll (GMainContext *context,
2382                             GPollFD      *fd)
2383 {
2384   if (!context)
2385     context = g_main_context_default ();
2386   
2387   LOCK_CONTEXT (context);
2388
2389   g_main_context_remove_poll_unlocked (context, fd);
2390   
2391   UNLOCK_CONTEXT (context);
2392 }
2393
2394 static void
2395 g_main_context_remove_poll_unlocked (GMainContext *context,
2396                                      GPollFD      *fd)
2397 {
2398   GPollRec *pollrec, *lastrec;
2399
2400   lastrec = NULL;
2401   pollrec = context->poll_records;
2402
2403   while (pollrec)
2404     {
2405       if (pollrec->fd == fd)
2406         {
2407           if (lastrec != NULL)
2408             lastrec->next = pollrec->next;
2409           else
2410             context->poll_records = pollrec->next;
2411
2412 #ifdef ENABLE_GC_FRIENDLY
2413           pollrec->fd = NULL;  
2414 #endif /* ENABLE_GC_FRIENDLY */
2415
2416           pollrec->next = context->poll_free_list;
2417           context->poll_free_list = pollrec;
2418
2419           context->n_poll_records--;
2420           break;
2421         }
2422       lastrec = pollrec;
2423       pollrec = pollrec->next;
2424     }
2425
2426 #ifdef G_THREADS_ENABLED
2427   context->poll_changed = TRUE;
2428   
2429   /* Now wake up the main loop if it is waiting in the poll() */
2430   g_main_context_wakeup (context);
2431 #endif
2432 }
2433
2434 /**
2435  * g_source_get_current_time:
2436  * @source:  a #GSource
2437  * @timeval: #GTimeVal structure in which to store current time.
2438  * 
2439  * Gets the "current time" to be used when checking 
2440  * this source. The advantage of calling this function over
2441  * calling g_get_current_time() directly is that when 
2442  * checking multiple sources, GLib can cache a single value
2443  * instead of having to repeatedly get the system time.
2444  **/
2445 void
2446 g_source_get_current_time (GSource  *source,
2447                            GTimeVal *timeval)
2448 {
2449   GMainContext *context;
2450   
2451   g_return_if_fail (source->context != NULL);
2452  
2453   context = source->context;
2454
2455   LOCK_CONTEXT (context);
2456
2457   if (!context->time_is_current)
2458     {
2459       g_get_current_time (&context->current_time);
2460       context->time_is_current = TRUE;
2461     }
2462   
2463   *timeval = context->current_time;
2464   
2465   UNLOCK_CONTEXT (context);
2466 }
2467
2468 /**
2469  * g_main_context_set_poll_func:
2470  * @context: a #GMainContext
2471  * @func: the function to call to poll all file descriptors
2472  * 
2473  * Sets the function to use to handle polling of file descriptors. It
2474  * will be used instead of the poll() system call (or GLib's
2475  * replacement function, which is used where poll() isn't available).
2476  *
2477  * This function could possibly be used to integrate the GLib event
2478  * loop with an external event loop.
2479  **/
2480 void
2481 g_main_context_set_poll_func (GMainContext *context,
2482                               GPollFunc     func)
2483 {
2484   if (!context)
2485     context = g_main_context_default ();
2486   
2487   LOCK_CONTEXT (context);
2488   
2489   if (func)
2490     context->poll_func = func;
2491   else
2492     {
2493 #ifdef HAVE_POLL
2494       context->poll_func = (GPollFunc) poll;
2495 #else
2496       context->poll_func = (GPollFunc) g_poll;
2497 #endif
2498     }
2499
2500   UNLOCK_CONTEXT (context);
2501 }
2502
2503 /**
2504  * g_main_context_get_poll_func:
2505  * @context: a #GMainContext
2506  * 
2507  * Gets the poll function set by g_main_context_set_poll_func()
2508  * 
2509  * Return value: the poll function
2510  **/
2511 GPollFunc
2512 g_main_context_get_poll_func (GMainContext *context)
2513 {
2514   GPollFunc result;
2515   
2516   if (!context)
2517     context = g_main_context_default ();
2518   
2519   LOCK_CONTEXT (context);
2520   result = context->poll_func;
2521   UNLOCK_CONTEXT (context);
2522
2523   return result;
2524 }
2525
2526 /* HOLDS: context's lock */
2527 /* Wake the main loop up from a poll() */
2528 static void
2529 g_main_context_wakeup (GMainContext *context)
2530 {
2531 #ifdef G_THREADS_ENABLED
2532   if (g_thread_supported() && context->poll_waiting)
2533     {
2534       context->poll_waiting = FALSE;
2535 #ifndef G_OS_WIN32
2536       write (context->wake_up_pipe[1], "A", 1);
2537 #else
2538       ReleaseSemaphore (context->wake_up_semaphore, 1, NULL);
2539 #endif
2540     }
2541 #endif
2542 }
2543
2544 /* Timeouts */
2545
2546 static void
2547 g_timeout_set_expiration (GTimeoutSource *timeout_source,
2548                           GTimeVal       *current_time)
2549 {
2550   guint seconds = timeout_source->interval / 1000;
2551   guint msecs = timeout_source->interval - seconds * 1000;
2552
2553   timeout_source->expiration.tv_sec = current_time->tv_sec + seconds;
2554   timeout_source->expiration.tv_usec = current_time->tv_usec + msecs * 1000;
2555   if (timeout_source->expiration.tv_usec >= 1000000)
2556     {
2557       timeout_source->expiration.tv_usec -= 1000000;
2558       timeout_source->expiration.tv_sec++;
2559     }
2560 }
2561
2562 static gboolean
2563 g_timeout_prepare  (GSource  *source,
2564                     gint     *timeout)
2565 {
2566   glong msec;
2567   GTimeVal current_time;
2568   
2569   GTimeoutSource *timeout_source = (GTimeoutSource *)source;
2570
2571   g_source_get_current_time (source, &current_time);
2572   
2573   msec = ((timeout_source->expiration.tv_sec  - current_time.tv_sec) * 1000 +
2574           (timeout_source->expiration.tv_usec - current_time.tv_usec) / 1000);
2575
2576   if (msec < 0)
2577     msec = 0;
2578   else if (msec > timeout_source->interval)
2579     {
2580       /* The system time has been set backwards, so we
2581        * reset the expiration time to now + timeout_source->interval;
2582        * this at least avoids hanging for long periods of time.
2583        */
2584       g_timeout_set_expiration (timeout_source, &current_time);
2585       msec = timeout_source->interval;
2586     }
2587   
2588   *timeout = msec;
2589   
2590   return msec == 0;
2591 }
2592
2593 static gboolean 
2594 g_timeout_check (GSource  *source)
2595 {
2596   GTimeVal current_time;
2597   GTimeoutSource *timeout_source = (GTimeoutSource *)source;
2598
2599   g_source_get_current_time (source, &current_time);
2600   
2601   return ((timeout_source->expiration.tv_sec < current_time.tv_sec) ||
2602           ((timeout_source->expiration.tv_sec == current_time.tv_sec) &&
2603            (timeout_source->expiration.tv_usec <= current_time.tv_usec)));
2604 }
2605
2606 static gboolean
2607 g_timeout_dispatch (GSource    *source,
2608                     GSourceFunc callback,
2609                     gpointer    user_data)
2610 {
2611   GTimeoutSource *timeout_source = (GTimeoutSource *)source;
2612
2613   if (!callback)
2614     {
2615       g_warning ("Timeout source dispatched without callback\n"
2616                  "You must call g_source_set_callback().");
2617       return FALSE;
2618     }
2619  
2620   if (callback (user_data))
2621     {
2622       GTimeVal current_time;
2623
2624       g_source_get_current_time (source, &current_time);
2625       g_timeout_set_expiration (timeout_source, &current_time);
2626
2627       return TRUE;
2628     }
2629   else
2630     return FALSE;
2631 }
2632
2633 /**
2634  * g_timeout_source_new:
2635  * @interval: the timeout interval in milliseconds.
2636  * 
2637  * Create a new timeout source.
2638  *
2639  * The source will not initially be associated with any #GMainContext
2640  * and must be added to one with g_source_attach() before it will be
2641  * executed.
2642  * 
2643  * Return value: the newly create timeout source
2644  **/
2645 GSource *
2646 g_timeout_source_new (guint interval)
2647 {
2648   GSource *source = g_source_new (&timeout_funcs, sizeof (GTimeoutSource));
2649   GTimeoutSource *timeout_source = (GTimeoutSource *)source;
2650   GTimeVal current_time;
2651
2652   timeout_source->interval = interval;
2653
2654   g_get_current_time (&current_time);
2655   g_timeout_set_expiration (timeout_source, &current_time);
2656   
2657   return source;
2658 }
2659
2660 /**
2661  * g_timeout_add_full:
2662  * @priority: the priority of the idle source. Typically this will be in the
2663  *            range btweeen #G_PRIORITY_DEFAULT_IDLE and #G_PRIORITY_HIGH_IDLE.
2664  * @interval: the time between calls to the function, in milliseconds
2665  *             (1/1000ths of a second.)
2666  * @function: function to call
2667  * @data:     data to pass to @function
2668  * @notify:   function to call when the idle is removed, or %NULL
2669  * 
2670  * Sets a function to be called at regular intervals, with the given
2671  * priority.  The function is called repeatedly until it returns
2672  * FALSE, at which point the timeout is automatically destroyed and
2673  * the function will not be called again.  The @notify function is
2674  * called when the timeout is destroyed.  The first call to the
2675  * function will be at the end of the first @interval.
2676  *
2677  * Note that timeout functions may be delayed, due to the processing of other
2678  * event sources. Thus they should not be relied on for precise timing.
2679  * After each call to the timeout function, the time of the next
2680  * timeout is recalculated based on the current time and the given interval
2681  * (it does not try to 'catch up' time lost in delays).
2682  * 
2683  * Return value: the id of event source.
2684  **/
2685 guint
2686 g_timeout_add_full (gint           priority,
2687                     guint          interval,
2688                     GSourceFunc    function,
2689                     gpointer       data,
2690                     GDestroyNotify notify)
2691 {
2692   GSource *source;
2693   guint id;
2694   
2695   g_return_val_if_fail (function != NULL, 0);
2696
2697   source = g_timeout_source_new (interval);
2698
2699   if (priority != G_PRIORITY_DEFAULT)
2700     g_source_set_priority (source, priority);
2701
2702   g_source_set_callback (source, function, data, notify);
2703   id = g_source_attach (source, NULL);
2704   g_source_unref (source);
2705
2706   return id;
2707 }
2708
2709 /**
2710  * g_timeout_add:
2711  * @interval: the time between calls to the function, in milliseconds
2712  *             (1/1000ths of a second.)
2713  * @function: function to call
2714  * @data:     data to pass to @function
2715  * 
2716  * Sets a function to be called at regular intervals, with the default
2717  * priority, #G_PRIORITY_DEFAULT.  The function is called repeatedly
2718  * until it returns FALSE, at which point the timeout is automatically
2719  * destroyed and the function will not be called again.  The @notify
2720  * function is called when the timeout is destroyed.  The first call
2721  * to the function will be at the end of the first @interval.
2722  *
2723  * Note that timeout functions may be delayed, due to the processing of other
2724  * event sources. Thus they should not be relied on for precise timing.
2725  * After each call to the timeout function, the time of the next
2726  * timeout is recalculated based on the current time and the given interval
2727  * (it does not try to 'catch up' time lost in delays).
2728  * 
2729  * Return value: the id of event source.
2730  **/
2731 guint 
2732 g_timeout_add (guint32        interval,
2733                GSourceFunc    function,
2734                gpointer       data)
2735 {
2736   return g_timeout_add_full (G_PRIORITY_DEFAULT, 
2737                              interval, function, data, NULL);
2738 }
2739
2740 /* Idle functions */
2741
2742 static gboolean 
2743 g_idle_prepare  (GSource  *source,
2744                  gint     *timeout)
2745 {
2746   *timeout = 0;
2747
2748   return TRUE;
2749 }
2750
2751 static gboolean 
2752 g_idle_check    (GSource  *source)
2753 {
2754   return TRUE;
2755 }
2756
2757 static gboolean
2758 g_idle_dispatch (GSource    *source, 
2759                  GSourceFunc callback,
2760                  gpointer    user_data)
2761 {
2762   if (!callback)
2763     {
2764       g_warning ("Idle source dispatched without callback\n"
2765                  "You must call g_source_set_callback().");
2766       return FALSE;
2767     }
2768   
2769   return callback (user_data);
2770 }
2771
2772 /**
2773  * g_idle_source_new:
2774  * 
2775  * Create a new idle source.
2776  *
2777  * The source will not initially be associated with any #GMainContext
2778  * and must be added to one with g_source_attach() before it will be
2779  * executed.
2780  * 
2781  * Return value: the newly created idle source
2782  **/
2783 GSource *
2784 g_idle_source_new (void)
2785 {
2786   return g_source_new (&idle_funcs, sizeof (GSource));
2787 }
2788
2789 /**
2790  * g_idle_add_full:
2791  * @priority: the priority of the idle source. Typically this will be in the
2792  *            range btweeen #G_PRIORITY_DEFAULT_IDLE and #G_PRIORITY_HIGH_IDLE.
2793  * @function: function to call
2794  * @data:     data to pass to @function
2795  * @notify:   function to call when the idle is removed, or %NULL
2796  * 
2797  * Adds a function to be called whenever there are no higher priority
2798  * events pending.  If the function returns FALSE it is automatically
2799  * removed from the list of event sources and will not be called again.
2800  * 
2801  * Return value: the id of the event source.
2802  **/
2803 guint 
2804 g_idle_add_full (gint           priority,
2805                  GSourceFunc    function,
2806                  gpointer       data,
2807                  GDestroyNotify notify)
2808 {
2809   GSource *source;
2810   guint id;
2811   
2812   g_return_val_if_fail (function != NULL, 0);
2813
2814   source = g_idle_source_new ();
2815
2816   if (priority != G_PRIORITY_DEFAULT)
2817     g_source_set_priority (source, priority);
2818
2819   g_source_set_callback (source, function, data, notify);
2820   id = g_source_attach (source, NULL);
2821   g_source_unref (source);
2822
2823   return id;
2824 }
2825
2826 /**
2827  * g_idle_add:
2828  * @function: function to call 
2829  * @data: data to pass to @function.
2830  * 
2831  * Adds a function to be called whenever there are no higher priority
2832  * events pending to the default main loop. The function is given the
2833  * default idle priority, #G_PRIORITY_DEFAULT_IDLE.  If the function
2834  * returns FALSE it is automatically removed from the list of event
2835  * sources and will not be called again.
2836  * 
2837  * Return value: the id of the event source.
2838  **/
2839 guint 
2840 g_idle_add (GSourceFunc    function,
2841             gpointer       data)
2842 {
2843   return g_idle_add_full (G_PRIORITY_DEFAULT_IDLE, function, data, NULL);
2844 }
2845
2846 /**
2847  * g_idle_remove_by_data:
2848  * @data: the data for the idle source's callback.
2849  * 
2850  * Removes the idle function with the given data.
2851  * 
2852  * Return value: %TRUE if an idle source was found and removed.
2853  **/
2854 gboolean
2855 g_idle_remove_by_data (gpointer data)
2856 {
2857   return g_source_remove_by_funcs_user_data (&idle_funcs, data);
2858 }
2859