source: trunk/third/glib2/glib/gmain.c @ 18159

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