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