Main Page | Class List | Directories | File List | Class Members | File Members

gmain.c File Reference

#include "config.h"
#include "glib.h"
#include <sys/types.h>
#include <time.h>
#include <errno.h>
#include <string.h>

Go to the source code of this file.

Classes

struct  _GSource
struct  _GMainLoop
struct  _GTimeoutData
struct  _GPollRec

Defines

#define SELECT_MASK   fd_set

Typedefs

typedef _GTimeoutData GTimeoutData
typedef _GSource GSource
typedef _GPollRec GPollRec

Enumerations

enum  GSourceFlags { G_SOURCE_READY = 1 << G_HOOK_FLAG_USER_SHIFT, G_SOURCE_CAN_RECURSE = 1 << (G_HOOK_FLAG_USER_SHIFT + 1) }

Functions

static gint g_source_compare (GHook *a, GHook *b)
static void g_source_destroy_func (GHookList *hook_list, GHook *hook)
static void g_main_poll (gint timeout, gboolean use_priority, gint priority)
static void g_main_add_poll_unlocked (gint priority, GPollFD *fd)
static void g_main_wakeup (void)
static gboolean g_timeout_prepare (gpointer source_data, GTimeVal *current_time, gint *timeout, gpointer user_data)
static gboolean g_timeout_check (gpointer source_data, GTimeVal *current_time, gpointer user_data)
static gboolean g_timeout_dispatch (gpointer source_data, GTimeVal *dispatch_time, gpointer user_data)
static gboolean g_idle_prepare (gpointer source_data, GTimeVal *current_time, gint *timeout, gpointer user_data)
static gboolean g_idle_check (gpointer source_data, GTimeVal *current_time, gpointer user_data)
static gboolean g_idle_dispatch (gpointer source_data, GTimeVal *dispatch_time, gpointer user_data)
 G_LOCK_DEFINE_STATIC (main_loop)
static gint g_poll (GPollFD *fds, guint nfds, gint timeout)
guint g_source_add (gint priority, gboolean can_recurse, GSourceFuncs *funcs, gpointer source_data, gpointer user_data, GDestroyNotify notify)
gboolean g_source_remove (guint tag)
gboolean g_source_remove_by_user_data (gpointer user_data)
static gboolean g_source_find_source_data (GHook *hook, gpointer data)
gboolean g_source_remove_by_source_data (gpointer source_data)
static gboolean g_source_find_funcs_user_data (GHook *hook, gpointer data)
gboolean g_source_remove_by_funcs_user_data (GSourceFuncs *funcs, gpointer user_data)
void g_get_current_time (GTimeVal *result)
static void g_main_dispatch (GTimeVal *dispatch_time)
static gboolean g_main_iterate (gboolean block, gboolean dispatch)
gboolean g_main_pending (void)
gboolean g_main_iteration (gboolean block)
GMainLoopg_main_new (gboolean is_running)
void g_main_run (GMainLoop *loop)
void g_main_quit (GMainLoop *loop)
void g_main_destroy (GMainLoop *loop)
gboolean g_main_is_running (GMainLoop *loop)
void g_main_add_poll (GPollFD *fd, gint priority)
void g_main_remove_poll (GPollFD *fd)
void g_main_set_poll_func (GPollFunc func)
static void g_timeout_set_expiration (GTimeoutData *data, GTimeVal *current_time)
guint g_timeout_add_full (gint priority, guint interval, GSourceFunc function, gpointer data, GDestroyNotify notify)
guint g_timeout_add (guint32 interval, GSourceFunc function, gpointer data)
guint g_idle_add_full (gint priority, GSourceFunc function, gpointer data, GDestroyNotify notify)
guint g_idle_add (GSourceFunc function, gpointer data)
gboolean g_idle_remove_by_data (gpointer data)

Variables

static GSListpending_dispatches = NULL
static GHookList source_list = { 0 }
static gint in_check_or_prepare = 0
static GSourceFuncs timeout_funcs
static GSourceFuncs idle_funcs
static GPollRecpoll_records = NULL
static GPollRecpoll_free_list = NULL
static GMemChunkpoll_chunk
static guint n_poll_records = 0
static GPollFunc poll_func = g_poll


Define Documentation

#define SELECT_MASK   fd_set
 

Definition at line 344 of file gmain.c.


Typedef Documentation

typedef struct _GPollRec GPollRec
 

Definition at line 71 of file gmain.c.

typedef struct _GSource GSource
 

Definition at line 70 of file gmain.c.

typedef struct _GTimeoutData GTimeoutData
 

Definition at line 69 of file gmain.c.


Enumeration Type Documentation

enum GSourceFlags
 

Enumerator:
G_SOURCE_READY 
G_SOURCE_CAN_RECURSE 

Definition at line 73 of file gmain.c.


Function Documentation

void g_get_current_time GTimeVal result  ) 
 

Definition at line 589 of file gmain.c.

References g_return_if_fail, _GTimeVal::tv_sec, and _GTimeVal::tv_usec.

Referenced by g_cond_timed_wait_nspr_impl(), g_main_iterate(), g_timeout_add_full(), test_private_func(), and wait_thread().

00590 {
00591 #ifndef _MSC_VER
00592   struct timeval r;
00593   g_return_if_fail (result != NULL);
00594 
00595   /*this is required on alpha, there the timeval structs are int's
00596     not longs and a cast only would fail horribly*/
00597   gettimeofday (&r, NULL);
00598   result->tv_sec = r.tv_sec;
00599   result->tv_usec = r.tv_usec;
00600 #else
00601   /* Avoid calling time() except for the first time.
00602    * GetTickCount() should be pretty fast and low-level?
00603    * I could also use ftime() but it seems unnecessarily overheady.
00604    */
00605   static DWORD start_tick = 0;
00606   static time_t start_time;
00607   DWORD tick;
00608   time_t t;
00609 
00610   g_return_if_fail (result != NULL);
00611  
00612   if (start_tick == 0)
00613     {
00614       start_tick = GetTickCount ();
00615       time (&start_time);
00616     }
00617 
00618   tick = GetTickCount ();
00619 
00620   result->tv_sec = (tick - start_tick) / 1000 + start_time;
00621   result->tv_usec = ((tick - start_tick) % 1000) * 1000;
00622 #endif
00623 }

guint g_idle_add GSourceFunc  function,
gpointer  data
 

Definition at line 1382 of file gmain.c.

References g_idle_add_full(), and G_PRIORITY_DEFAULT_IDLE.

01384 {
01385   return g_idle_add_full (G_PRIORITY_DEFAULT_IDLE, function, data, NULL);
01386 }

guint g_idle_add_full gint  priority,
GSourceFunc  function,
gpointer  data,
GDestroyNotify  notify
 

Definition at line 1371 of file gmain.c.

References FALSE, g_return_val_if_fail, and g_source_add().

Referenced by g_idle_add().

01375 {
01376   g_return_val_if_fail (function != NULL, 0);
01377 
01378   return g_source_add (priority, FALSE, &idle_funcs, (gpointer) function, data, notify);
01379 }

static gboolean g_idle_check gpointer  source_data,
GTimeVal current_time,
gpointer  user_data
[static]
 

Definition at line 1353 of file gmain.c.

References TRUE.

01356 {
01357   return TRUE;
01358 }

static gboolean g_idle_dispatch gpointer  source_data,
GTimeVal dispatch_time,
gpointer  user_data
[static]
 

Definition at line 1361 of file gmain.c.

01364 {
01365   GSourceFunc func = (GSourceFunc) source_data;
01366 
01367   return func (user_data);
01368 }

static gboolean g_idle_prepare gpointer  source_data,
GTimeVal current_time,
gint timeout,
gpointer  user_data
[static]
 

Definition at line 1342 of file gmain.c.

References TRUE.

01346 {
01347   *timeout = 0;
01348 
01349   return TRUE;
01350 }

gboolean g_idle_remove_by_data gpointer  data  ) 
 

Definition at line 1389 of file gmain.c.

References g_source_remove_by_funcs_user_data().

01390 {
01391   return g_source_remove_by_funcs_user_data (&idle_funcs, data);
01392 }

G_LOCK_DEFINE_STATIC main_loop   ) 
 

void g_main_add_poll GPollFD fd,
gint  priority
 

Definition at line 1111 of file gmain.c.

References G_LOCK, g_main_add_poll_unlocked(), and G_UNLOCK.

Referenced by g_io_unix_add_watch(), g_io_win32_fd_add_watch(), g_io_win32_msg_add_watch(), and g_io_win32_sock_add_watch().

01113 {
01114   G_LOCK (main_loop);
01115   g_main_add_poll_unlocked (priority, fd);
01116   G_UNLOCK (main_loop);
01117 }

static void g_main_add_poll_unlocked gint  priority,
GPollFD fd
[static]
 

Definition at line 1121 of file gmain.c.

References _GPollRec::fd, G_ALLOC_ONLY, g_chunk_new, g_main_wakeup(), g_mem_chunk_create, n_poll_records, _GPollRec::next, poll_chunk, _GPollRec::priority, _GPollFD::revents, and TRUE.

Referenced by g_main_add_poll(), and g_main_poll().

01123 {
01124   GPollRec *lastrec, *pollrec, *newrec;
01125 
01126   if (!poll_chunk)
01127     poll_chunk = g_mem_chunk_create (GPollRec, 32, G_ALLOC_ONLY);
01128 
01129   if (poll_free_list)
01130     {
01131       newrec = poll_free_list;
01132       poll_free_list = newrec->next;
01133     }
01134   else
01135     newrec = g_chunk_new (GPollRec, poll_chunk);
01136 
01137   /* This file descriptor may be checked before we ever poll */
01138   fd->revents = 0;
01139   newrec->fd = fd;
01140   newrec->priority = priority;
01141 
01142   lastrec = NULL;
01143   pollrec = poll_records;
01144   while (pollrec && priority >= pollrec->priority)
01145     {
01146       lastrec = pollrec;
01147       pollrec = pollrec->next;
01148     }
01149   
01150   if (lastrec)
01151     lastrec->next = newrec;
01152   else
01153     poll_records = newrec;
01154 
01155   newrec->next = pollrec;
01156 
01157   n_poll_records++;
01158 
01159 #ifdef G_THREADS_ENABLED
01160   poll_changed = TRUE;
01161 
01162   /* Now wake up the main loop if it is waiting in the poll() */
01163   g_main_wakeup ();
01164 #endif
01165 }

void g_main_destroy GMainLoop loop  ) 
 

Definition at line 947 of file gmain.c.

References g_free(), and g_return_if_fail.

00948 {
00949   g_return_if_fail (loop != NULL);
00950 
00951   g_free (loop);
00952 }

static void g_main_dispatch GTimeVal dispatch_time  )  [static]
 

Definition at line 629 of file gmain.c.

References _GSList::data, g_hook_destroy_link(), G_HOOK_FLAG_IN_CALL, G_HOOK_IN_CALL, G_HOOK_IS_VALID, g_hook_unref(), G_LOCK, g_slist_free_1(), g_slist_remove_link(), and G_UNLOCK.

Referenced by g_main_iterate().

00630 {
00631   while (pending_dispatches != NULL)
00632     {
00633       gboolean need_destroy;
00634       GSource *source = pending_dispatches->data;
00635       GSList *tmp_list;
00636 
00637       tmp_list = pending_dispatches;
00638       pending_dispatches = g_slist_remove_link (pending_dispatches, pending_dispatches);
00639       g_slist_free_1 (tmp_list);
00640 
00641       if (G_HOOK_IS_VALID (source))
00642         {
00643           gboolean was_in_call;
00644           gpointer hook_data = source->hook.data;
00645           gpointer source_data = source->source_data;
00646           gboolean (*dispatch) (gpointer,
00647                                 GTimeVal *,
00648                                 gpointer);
00649 
00650           dispatch = ((GSourceFuncs *) source->hook.func)->dispatch;
00651           
00652           was_in_call = G_HOOK_IN_CALL (source);
00653           source->hook.flags |= G_HOOK_FLAG_IN_CALL;
00654 
00655           G_UNLOCK (main_loop);
00656           need_destroy = ! dispatch (source_data,
00657                                      dispatch_time,
00658                                      hook_data);
00659           G_LOCK (main_loop);
00660 
00661           if (!was_in_call)
00662             source->hook.flags &= ~G_HOOK_FLAG_IN_CALL;
00663           
00664           if (need_destroy && G_HOOK_IS_VALID (source))
00665             g_hook_destroy_link (&source_list, (GHook *) source);
00666         }
00667 
00668       g_hook_unref (&source_list, (GHook*) source);
00669     }
00670 }

gboolean g_main_is_running GMainLoop loop  ) 
 

Definition at line 955 of file gmain.c.

References FALSE, g_return_val_if_fail, and _GMainLoop::is_running.

00956 {
00957   g_return_val_if_fail (loop != NULL, FALSE);
00958 
00959   return loop->is_running;
00960 }

static gboolean g_main_iterate gboolean  block,
gboolean  dispatch
[static]
 

Definition at line 703 of file gmain.c.

References _GHook::data, FALSE, g_get_current_time(), g_hook_first_valid(), G_HOOK_IN_CALL, g_hook_next_valid(), g_hook_ref(), g_hook_unref(), G_LOCK, g_main_dispatch(), g_main_poll(), g_return_val_if_fail, g_slist_prepend(), g_slist_reverse(), G_SOURCE_CAN_RECURSE, G_SOURCE_READY, G_UNLOCK, g_warning(), _GSource::hook, in_check_or_prepare, MIN, _GSource::priority, _GSource::source_data, TRUE, and user_data.

Referenced by g_main_iteration(), g_main_pending(), and g_main_run().

00705 {
00706   GHook *hook;
00707   GTimeVal current_time  = { 0, 0 };
00708   gint n_ready = 0;
00709   gint current_priority = 0;
00710   gint timeout;
00711   gboolean retval = FALSE;
00712 
00713   g_return_val_if_fail (!block || dispatch, FALSE);
00714 
00715   g_get_current_time (&current_time);
00716 
00717   G_LOCK (main_loop);
00718 
00719 #ifdef G_THREADS_ENABLED
00720   if (poll_waiting)
00721     {
00722       g_warning("g_main_iterate(): main loop already active in another thread");
00723       G_UNLOCK (main_loop);
00724       return FALSE;
00725     }
00726 #endif
00727   
00728   /* If recursing, finish up current dispatch, before starting over */
00729   if (pending_dispatches)
00730     {
00731       if (dispatch)
00732         g_main_dispatch (&current_time);
00733       
00734       G_UNLOCK (main_loop);
00735 
00736       return TRUE;
00737     }
00738 
00739   /* Prepare all sources */
00740 
00741   timeout = block ? -1 : 0;
00742   
00743   hook = g_hook_first_valid (&source_list, TRUE);
00744   while (hook)
00745     {
00746       GSource *source = (GSource*) hook;
00747       gint source_timeout = -1;
00748 
00749       if ((n_ready > 0) && (source->priority > current_priority))
00750         {
00751           g_hook_unref (&source_list, hook);
00752           break;
00753         }
00754       if (G_HOOK_IN_CALL (hook) && !(hook->flags & G_SOURCE_CAN_RECURSE))
00755         {
00756           hook = g_hook_next_valid (&source_list, hook, TRUE);
00757           continue;
00758         }
00759 
00760       if (!(hook->flags & G_SOURCE_READY))
00761         {
00762           gboolean (*prepare)  (gpointer  source_data, 
00763                                 GTimeVal *current_time,
00764                                 gint     *timeout,
00765                                 gpointer  user_data);
00766 
00767           prepare = ((GSourceFuncs *) hook->func)->prepare;
00768           in_check_or_prepare++;
00769           G_UNLOCK (main_loop);
00770 
00771           if ((*prepare) (source->source_data, &current_time, &source_timeout, source->hook.data))
00772             hook->flags |= G_SOURCE_READY;
00773           
00774           G_LOCK (main_loop);
00775           in_check_or_prepare--;
00776         }
00777 
00778       if (hook->flags & G_SOURCE_READY)
00779         {
00780           if (!dispatch)
00781             {
00782               g_hook_unref (&source_list, hook);
00783               G_UNLOCK (main_loop);
00784 
00785               return TRUE;
00786             }
00787           else
00788             {
00789               n_ready++;
00790               current_priority = source->priority;
00791               timeout = 0;
00792             }
00793         }
00794       
00795       if (source_timeout >= 0)
00796         {
00797           if (timeout < 0)
00798             timeout = source_timeout;
00799           else
00800             timeout = MIN (timeout, source_timeout);
00801         }
00802 
00803       hook = g_hook_next_valid (&source_list, hook, TRUE);
00804     }
00805 
00806   /* poll(), if necessary */
00807 
00808   g_main_poll (timeout, n_ready > 0, current_priority);
00809 
00810   if (timeout != 0)
00811     g_get_current_time (&current_time);
00812   
00813   /* Check to see what sources need to be dispatched */
00814 
00815   n_ready = 0;
00816   
00817   hook = g_hook_first_valid (&source_list, TRUE);
00818   while (hook)
00819     {
00820       GSource *source = (GSource *)hook;
00821 
00822       if ((n_ready > 0) && (source->priority > current_priority))
00823         {
00824           g_hook_unref (&source_list, hook);
00825           break;
00826         }
00827       if (G_HOOK_IN_CALL (hook) && !(hook->flags & G_SOURCE_CAN_RECURSE))
00828         {
00829           hook = g_hook_next_valid (&source_list, hook, TRUE);
00830           continue;
00831         }
00832 
00833       if (!(hook->flags & G_SOURCE_READY))
00834         {
00835           gboolean (*check) (gpointer  source_data,
00836                              GTimeVal *current_time,
00837                              gpointer  user_data);
00838 
00839           check = ((GSourceFuncs *) hook->func)->check;
00840           in_check_or_prepare++;
00841           G_UNLOCK (main_loop);
00842           
00843           if ((*check) (source->source_data, &current_time, source->hook.data))
00844             hook->flags |= G_SOURCE_READY;
00845 
00846           G_LOCK (main_loop);
00847           in_check_or_prepare--;
00848         }
00849 
00850       if (hook->flags & G_SOURCE_READY)
00851         {
00852           if (dispatch)
00853             {
00854               hook->flags &= ~G_SOURCE_READY;
00855               g_hook_ref (&source_list, hook);
00856               pending_dispatches = g_slist_prepend (pending_dispatches, source);
00857               current_priority = source->priority;
00858               n_ready++;
00859             }
00860           else
00861             {
00862               g_hook_unref (&source_list, hook);
00863               G_UNLOCK (main_loop);
00864 
00865               return TRUE;
00866             }
00867         }
00868       
00869       hook = g_hook_next_valid (&source_list, hook, TRUE);
00870     }
00871  
00872   /* Now invoke the callbacks */
00873 
00874   if (pending_dispatches)
00875     {
00876       pending_dispatches = g_slist_reverse (pending_dispatches);
00877       g_main_dispatch (&current_time);
00878       retval = TRUE;
00879     }
00880 
00881   G_UNLOCK (main_loop);
00882 
00883   return retval;
00884 }

gboolean g_main_iteration gboolean  block  ) 
 

Definition at line 898 of file gmain.c.

References FALSE, g_main_iterate(), g_warning(), in_check_or_prepare, and TRUE.

00899 {
00900   if (in_check_or_prepare)
00901     {
00902       g_warning ("g_main_iteration(): called recursively from within a source's check() or "
00903                  "prepare() member or from a second thread, iteration not possible");
00904       return FALSE;
00905     }
00906   else
00907     return g_main_iterate (block, TRUE);
00908 }

GMainLoop* g_main_new gboolean  is_running  ) 
 

Definition at line 911 of file gmain.c.

References FALSE, g_new0, and _GMainLoop::is_running.

00912 {
00913   GMainLoop *loop;
00914 
00915   loop = g_new0 (GMainLoop, 1);
00916   loop->is_running = is_running != FALSE;
00917 
00918   return loop;
00919 }

gboolean g_main_pending void   ) 
 

Definition at line 889 of file gmain.c.

References FALSE, g_main_iterate(), and in_check_or_prepare.

00890 {
00891   return in_check_or_prepare ? FALSE : g_main_iterate (FALSE, FALSE);
00892 }

static void g_main_poll gint  timeout,
gboolean  use_priority,
gint  priority
[static]
 

Definition at line 964 of file gmain.c.

References _GPollFD::events, FALSE, fd, _GPollRec::fd, _GPollFD::fd, g_error(), g_free(), G_LOCK, g_main_add_poll_unlocked(), g_new, g_print(), g_strerror(), g_timer_destroy(), g_timer_elapsed(), g_timer_new(), G_UNLOCK, n_poll_records, _GPollRec::next, _GPollRec::priority, _GPollFD::revents, and TRUE.

Referenced by g_main_iterate().

00967 {
00968 #ifdef  G_MAIN_POLL_DEBUG
00969   GTimer *poll_timer;
00970 #endif
00971   GPollFD *fd_array;
00972   GPollRec *pollrec;
00973   gint i;
00974   gint npoll;
00975 
00976 #ifdef G_THREADS_ENABLED
00977 #ifndef NATIVE_WIN32
00978   if (wake_up_pipe[0] < 0)
00979     {
00980       if (pipe (wake_up_pipe) < 0)
00981         g_error ("Cannot create pipe main loop wake-up: %s\n",
00982                  g_strerror (errno));
00983 
00984       wake_up_rec.fd = wake_up_pipe[0];
00985       wake_up_rec.events = G_IO_IN;
00986       g_main_add_poll_unlocked (0, &wake_up_rec);
00987     }
00988 #else
00989   if (wake_up_semaphore == NULL)
00990     {
00991       if ((wake_up_semaphore = CreateSemaphore (NULL, 0, 100, NULL)) == NULL)
00992         g_error ("Cannot create wake-up semaphore: %d", GetLastError ());
00993       wake_up_rec.fd = (gint) wake_up_semaphore;
00994       wake_up_rec.events = G_IO_IN;
00995       g_main_add_poll_unlocked (0, &wake_up_rec);
00996     }
00997 #endif
00998 #endif
00999   fd_array = g_new (GPollFD, n_poll_records);
01000  
01001   pollrec = poll_records;
01002   i = 0;
01003   while (pollrec && (!use_priority || priority >= pollrec->priority))
01004     {
01005       if (pollrec->fd->events)
01006         {
01007           fd_array[i].fd = pollrec->fd->fd;
01008           /* In direct contradiction to the Unix98 spec, IRIX runs into
01009            * difficulty if you pass in POLLERR, POLLHUP or POLLNVAL
01010            * flags in the events field of the pollfd while it should
01011            * just ignoring them. So we mask them out here.
01012            */
01013           fd_array[i].events = pollrec->fd->events & ~(G_IO_ERR|G_IO_HUP|G_IO_NVAL);
01014           fd_array[i].revents = 0;
01015           i++;
01016         }
01017       
01018       pollrec = pollrec->next;
01019     }
01020 #ifdef G_THREADS_ENABLED
01021   poll_waiting = TRUE;
01022   poll_changed = FALSE;
01023 #endif
01024   
01025   npoll = i;
01026   if (npoll || timeout != 0)
01027     {
01028 #ifdef  G_MAIN_POLL_DEBUG
01029       g_print ("g_main_poll(%d) timeout: %d\r", npoll, timeout);
01030       poll_timer = g_timer_new ();
01031 #endif
01032       
01033       G_UNLOCK (main_loop);
01034       (*poll_func) (fd_array, npoll, timeout);
01035       G_LOCK (main_loop);
01036       
01037 #ifdef  G_MAIN_POLL_DEBUG
01038       g_print ("g_main_poll(%d) timeout: %d - elapsed %12.10f seconds",
01039                npoll,
01040                timeout,
01041                g_timer_elapsed (poll_timer, NULL));
01042       g_timer_destroy (poll_timer);
01043       pollrec = poll_records;
01044       i = 0;
01045       while (i < npoll)
01046         {
01047           if (pollrec->fd->events)
01048             {
01049               if (fd_array[i].revents)
01050                 {
01051                   g_print (" [%d:", fd_array[i].fd);
01052                   if (fd_array[i].revents & G_IO_IN)
01053                     g_print ("i");
01054                   if (fd_array[i].revents & G_IO_OUT)
01055                     g_print ("o");
01056                   if (fd_array[i].revents & G_IO_PRI)
01057                     g_print ("p");
01058                   if (fd_array[i].revents & G_IO_ERR)
01059                     g_print ("e");
01060                   if (fd_array[i].revents & G_IO_HUP)
01061                     g_print ("h");
01062                   if (fd_array[i].revents & G_IO_NVAL)
01063                     g_print ("n");
01064                   g_print ("]");
01065                 }
01066               i++;
01067             }
01068           pollrec = pollrec->next;
01069         }
01070       g_print ("\n");
01071 #endif
01072     } /* if (npoll || timeout != 0) */
01073   
01074 #ifdef G_THREADS_ENABLED
01075   if (!poll_waiting)
01076     {
01077 #ifndef NATIVE_WIN32
01078       gchar c;
01079       read (wake_up_pipe[0], &c, 1);
01080 #endif
01081     }
01082   else
01083     poll_waiting = FALSE;
01084 
01085   /* If the set of poll file descriptors changed, bail out
01086    * and let the main loop rerun
01087    */
01088   if (poll_changed)
01089     {
01090       g_free (fd_array);
01091       return;
01092     }
01093 #endif
01094 
01095   pollrec = poll_records;
01096   i = 0;
01097   while (i < npoll)
01098     {
01099       if (pollrec->fd->events)
01100         {
01101           pollrec->fd->revents = fd_array[i].revents;
01102           i++;
01103         }
01104       pollrec = pollrec->next;
01105     }
01106 
01107   g_free (fd_array);
01108 }

void g_main_quit GMainLoop loop  ) 
 

Definition at line 939 of file gmain.c.

References FALSE, g_return_if_fail, and _GMainLoop::is_running.

00940 {
00941   g_return_if_fail (loop != NULL);
00942 
00943   loop->is_running = FALSE;
00944 }

void g_main_remove_poll GPollFD fd  ) 
 

Definition at line 1168 of file gmain.c.

References _GPollRec::fd, G_LOCK, g_main_wakeup(), G_UNLOCK, n_poll_records, _GPollRec::next, and TRUE.

Referenced by g_io_unix_destroy(), and g_io_win32_destroy().

01169 {
01170   GPollRec *pollrec, *lastrec;
01171 
01172   G_LOCK (main_loop);
01173   
01174   lastrec = NULL;
01175   pollrec = poll_records;
01176 
01177   while (pollrec)
01178     {
01179       if (pollrec->fd == fd)
01180         {
01181           if (lastrec != NULL)
01182             lastrec->next = pollrec->next;
01183           else
01184             poll_records = pollrec->next;
01185 
01186           pollrec->next = poll_free_list;
01187           poll_free_list = pollrec;
01188 
01189           n_poll_records--;
01190           break;
01191         }
01192       lastrec = pollrec;
01193       pollrec = pollrec->next;
01194     }
01195 
01196 #ifdef G_THREADS_ENABLED
01197   poll_changed = TRUE;
01198   
01199   /* Now wake up the main loop if it is waiting in the poll() */
01200   g_main_wakeup ();
01201 #endif
01202 
01203   G_UNLOCK (main_loop);
01204 }

void g_main_run GMainLoop loop  ) 
 

Definition at line 922 of file gmain.c.

References g_main_iterate(), g_return_if_fail, g_warning(), in_check_or_prepare, _GMainLoop::is_running, and TRUE.

00923 {
00924   g_return_if_fail (loop != NULL);
00925 
00926   if (in_check_or_prepare)
00927     {
00928       g_warning ("g_main_run(): called recursively from within a source's check() or "
00929                  "prepare() member or from a second thread, iteration not possible");
00930       return;
00931     }
00932   
00933   loop->is_running = TRUE;
00934   while (loop->is_running)
00935     g_main_iterate (TRUE, TRUE);
00936 }

void g_main_set_poll_func GPollFunc  func  ) 
 

Definition at line 1207 of file gmain.c.

References g_poll().

01208 {
01209   if (func)
01210     poll_func = func;
01211   else
01212 #ifdef HAVE_POLL
01213     poll_func = (GPollFunc) poll;
01214 #else
01215     poll_func = (GPollFunc) g_poll;
01216 #endif
01217 }

static void g_main_wakeup void   )  [static]
 

Definition at line 1221 of file gmain.c.

References FALSE.

Referenced by g_main_add_poll_unlocked(), g_main_remove_poll(), and g_source_add().

01222 {
01223 #ifdef G_THREADS_ENABLED
01224   if (poll_waiting)
01225     {
01226       poll_waiting = FALSE;
01227 #ifndef NATIVE_WIN32
01228       write (wake_up_pipe[1], "A", 1);
01229 #else
01230       ReleaseSemaphore (wake_up_semaphore, 1, NULL);
01231 #endif
01232     }
01233 #endif
01234 }

static gint g_poll GPollFD fds,
guint  nfds,
gint  timeout
[static]
 

Definition at line 357 of file gmain.c.

References _GPollFD::events, _GPollFD::fd, _GPollFD::revents, and SELECT_MASK.

Referenced by g_main_set_poll_func().

00360 {
00361   struct timeval tv;
00362   SELECT_MASK rset, wset, xset;
00363   GPollFD *f;
00364   int ready;
00365   int maxfd = 0;
00366 
00367   FD_ZERO (&rset);
00368   FD_ZERO (&wset);
00369   FD_ZERO (&xset);
00370 
00371   for (f = fds; f < &fds[nfds]; ++f)
00372     if (f->fd >= 0)
00373       {
00374         if (f->events & G_IO_IN)
00375           FD_SET (f->fd, &rset);
00376         if (f->events & G_IO_OUT)
00377           FD_SET (f->fd, &wset);
00378         if (f->events & G_IO_PRI)
00379           FD_SET (f->fd, &xset);
00380         if (f->fd > maxfd && (f->events & (G_IO_IN|G_IO_OUT|G_IO_PRI)))
00381           maxfd = f->fd;
00382       }
00383 
00384   tv.tv_sec = timeout / 1000;
00385   tv.tv_usec = (timeout % 1000) * 1000;
00386 
00387   ready = select (maxfd + 1, &rset, &wset, &xset,
00388                   timeout == -1 ? NULL : &tv);
00389   if (ready > 0)
00390     for (f = fds; f < &fds[nfds]; ++f)
00391       {
00392         f->revents = 0;
00393         if (f->fd >= 0)
00394           {
00395             if (FD_ISSET (f->fd, &rset))
00396               f->revents |= G_IO_IN;
00397             if (FD_ISSET (f->fd, &wset))
00398               f->revents |= G_IO_OUT;
00399             if (FD_ISSET (f->fd, &xset))
00400               f->revents |= G_IO_PRI;
00401           }
00402       }
00403 
00404   return ready;
00405 }

guint g_source_add gint  priority,
gboolean  can_recurse,
GSourceFuncs funcs,
gpointer  source_data,
gpointer  user_data,
GDestroyNotify  notify
 

Definition at line 449 of file gmain.c.

References _GHook::data, _GHook::destroy, _GHook::flags, _GHook::func, g_hook_alloc(), G_HOOK_DEFERRED_DESTROY, g_hook_insert_sorted(), g_hook_list_init(), G_LOCK, g_main_wakeup(), G_SOURCE_CAN_RECURSE, g_source_compare(), g_source_destroy_func(), G_UNLOCK, _GSource::hook, _GHookList::hook_destroy, _GHookList::hook_free, _GHook::hook_id, _GHookList::is_setup, _GSource::priority, and _GSource::source_data.

Referenced by g_idle_add_full(), g_io_unix_add_watch(), g_io_win32_fd_add_watch(), g_io_win32_msg_add_watch(), g_io_win32_pipe_add_watch(), g_io_win32_sock_add_watch(), and g_timeout_add_full().

00455 {
00456   guint return_val;
00457   GSource *source;
00458 
00459   G_LOCK (main_loop);
00460 
00461   if (!source_list.is_setup)
00462     {
00463       g_hook_list_init (&source_list, sizeof (GSource));
00464 
00465       source_list.hook_destroy = G_HOOK_DEFERRED_DESTROY;
00466       source_list.hook_free = g_source_destroy_func;
00467     }
00468 
00469   source = (GSource*) g_hook_alloc (&