Rename the GUTILS_C_VAR macro to GLIB_VAR.
[platform/upstream/glib.git] / gmain.c
diff --git a/gmain.c b/gmain.c
index 20b1afb..155ccbd 100644 (file)
--- a/gmain.c
+++ b/gmain.c
 #endif /* HAVE_UNISTD_H */
 #include <errno.h>
 
-#ifdef NATIVE_WIN32
+#ifdef G_OS_WIN32
 #define STRICT
 #include <windows.h>
-#endif /* NATIVE_WIN32 */
+#endif /* G_OS_WIN32 */
 
-#ifdef GLIB_NATIVE_BEOS
+#ifdef G_OS_BEOS
 #include <net/socket.h>
-#endif /* GLIB_NATIVE_BEOS */
+#endif /* G_OS_BEOS */
 
 /* Types */
 
@@ -122,7 +122,7 @@ static gboolean g_timeout_check        (gpointer  source_data,
                                        GTimeVal *current_time,
                                        gpointer  user_data);
 static gboolean g_timeout_dispatch     (gpointer  source_data,
-                                       GTimeVal *current_time,
+                                       GTimeVal *dispatch_time,
                                        gpointer  user_data);
 static gboolean g_idle_prepare         (gpointer  source_data, 
                                        GTimeVal *current_time,
@@ -132,7 +132,7 @@ static gboolean g_idle_check           (gpointer  source_data,
                                        GTimeVal *current_time,
                                        gpointer  user_data);
 static gboolean g_idle_dispatch        (gpointer  source_data,
-                                       GTimeVal *current_time,
+                                       GTimeVal *dispatch_time,
                                        gpointer  user_data);
 
 /* Data */
@@ -168,13 +168,13 @@ static GMemChunk *poll_chunk;
 static guint n_poll_records = 0;
 
 #ifdef G_THREADS_ENABLED
-#ifndef NATIVE_WIN32
+#ifndef G_OS_WIN32
 /* this pipe is used to wake up the main loop when a source is added.
  */
 static gint wake_up_pipe[2] = { -1, -1 };
-#else /* NATIVE_WIN32 */
+#else /* G_OS_WIN32 */
 static HANDLE wake_up_semaphore = NULL;
-#endif /* NATIVE_WIN32 */
+#endif /* G_OS_WIN32 */
 static GPollFD wake_up_rec;
 static gboolean poll_waiting = FALSE;
 
@@ -189,7 +189,7 @@ extern gint poll (GPollFD *ufds, guint nfsd, gint timeout);
 #  endif  /* !sun */
 static GPollFunc poll_func = (GPollFunc) poll;
 #else  /* !HAVE_POLL */
-#ifdef NATIVE_WIN32
+#ifdef G_OS_WIN32
 
 static gint
 g_poll (GPollFD *fds, guint nfds, gint timeout)
@@ -327,7 +327,7 @@ g_poll (GPollFD *fds, guint nfds, gint timeout)
     return 1;
 }
 
-#else  /* !NATIVE_WIN32 */
+#else  /* !G_OS_WIN32 */
 
 /* The following implementation of poll() comes from the GNU C Library.
  * Copyright (C) 1994, 1996, 1997 Free Software Foundation, Inc.
@@ -339,9 +339,9 @@ g_poll (GPollFD *fds, guint nfds, gint timeout)
 #include <sys/select.h>
 #endif /* HAVE_SYS_SELECT_H */
 
-#ifdef GLIB_NATIVE_BEOS
+#ifdef G_OS_BEOS
 #undef NO_FD_SET
-#endif /* GLIB_NATIVE_BEOS */
+#endif /* G_OS_BEOS */
 
 #ifndef NO_FD_SET
 #  define SELECT_MASK fd_set
@@ -407,7 +407,7 @@ g_poll (GPollFD *fds,
   return ready;
 }
 
-#endif /* !NATIVE_WIN32 */
+#endif /* !G_OS_WIN32 */
 
 static GPollFunc poll_func = g_poll;
 #endif /* !HAVE_POLL */
@@ -591,7 +591,7 @@ g_source_remove_by_funcs_user_data (GSourceFuncs *funcs,
 void
 g_get_current_time (GTimeVal *result)
 {
-#ifndef NATIVE_WIN32
+#ifndef G_OS_WIN32
   struct timeval r;
   g_return_if_fail (result != NULL);
 
@@ -629,7 +629,7 @@ g_get_current_time (GTimeVal *result)
 
 /* HOLDS: main_loop_lock */
 static void
-g_main_dispatch (GTimeVal *current_time)
+g_main_dispatch (GTimeVal *dispatch_time)
 {
   while (pending_dispatches != NULL)
     {
@@ -657,7 +657,7 @@ g_main_dispatch (GTimeVal *current_time)
 
          G_UNLOCK (main_loop);
          need_destroy = ! dispatch (source_data,
-                                    current_time,
+                                    dispatch_time,
                                     hook_data);
          G_LOCK (main_loop);
 
@@ -707,7 +707,7 @@ g_main_iterate (gboolean block,
                gboolean dispatch)
 {
   GHook *hook;
-  GTimeVal current_time  ={ 0, 0 };
+  GTimeVal current_time  = { 0, 0 };
   gint n_ready = 0;
   gint current_priority = 0;
   gint timeout;
@@ -810,6 +810,9 @@ g_main_iterate (gboolean block,
 
   g_main_poll (timeout, n_ready > 0, current_priority);
 
+  if (timeout != 0)
+    g_get_current_time (&current_time);
+  
   /* Check to see what sources need to be dispatched */
 
   n_ready = 0;
@@ -974,7 +977,7 @@ g_main_poll (gint     timeout,
   gint npoll;
 
 #ifdef G_THREADS_ENABLED
-#ifndef NATIVE_WIN32
+#ifndef G_OS_WIN32
   if (wake_up_pipe[0] < 0)
     {
       if (pipe (wake_up_pipe) < 0)
@@ -1031,7 +1034,9 @@ g_main_poll (gint     timeout,
 #endif
       
       G_UNLOCK (main_loop);
-      (*poll_func) (fd_array, npoll, timeout);
+      if ((*poll_func) (fd_array, npoll, timeout) < 0)
+       g_warning ("poll(2) failed due to: %s.",
+                  g_strerror (errno));
       G_LOCK (main_loop);
       
 #ifdef G_MAIN_POLL_DEBUG
@@ -1074,7 +1079,7 @@ g_main_poll (gint     timeout,
 #ifdef G_THREADS_ENABLED
   if (!poll_waiting)
     {
-#ifndef NATIVE_WIN32
+#ifndef G_OS_WIN32
       gchar c;
       read (wake_up_pipe[0], &c, 1);
 #endif
@@ -1181,6 +1186,10 @@ g_main_remove_poll (GPollFD *fd)
          else
            poll_records = pollrec->next;
 
+#ifdef ENABLE_GC_FRIENDLY
+         pollrec->fd = NULL;  
+#endif /* ENABLE_GC_FRIENDLY */
+
          pollrec->next = poll_free_list;
          poll_free_list = pollrec;
 
@@ -1222,7 +1231,7 @@ g_main_wakeup (void)
   if (poll_waiting)
     {
       poll_waiting = FALSE;
-#ifndef NATIVE_WIN32
+#ifndef G_OS_WIN32
       write (wake_up_pipe[1], "A", 1);
 #else
       ReleaseSemaphore (wake_up_semaphore, 1, NULL);
@@ -1233,21 +1242,49 @@ g_main_wakeup (void)
 
 /* Timeouts */
 
-static gboolean 
-g_timeout_prepare  (gpointer  source_data, 
+static void
+g_timeout_set_expiration (GTimeoutData *data,
+                         GTimeVal     *current_time)
+{
+  guint seconds = data->interval / 1000;
+  guint msecs = data->interval - seconds * 1000;
+
+  data->expiration.tv_sec = current_time->tv_sec + seconds;
+  data->expiration.tv_usec = current_time->tv_usec + msecs * 1000;
+  if (data->expiration.tv_usec >= 1000000)
+    {
+      data->expiration.tv_usec -= 1000000;
+      data->expiration.tv_sec++;
+    }
+}
+
+static gboolean
+g_timeout_prepare  (gpointer  source_data,
                    GTimeVal *current_time,
                    gint     *timeout,
                    gpointer  user_data)
 {
   glong msec;
   GTimeoutData *data = source_data;
-
-  msec = (data->expiration.tv_sec  - current_time->tv_sec) * 1000 +
-         (data->expiration.tv_usec - current_time->tv_usec) / 1000;
-
-  *timeout = (msec <= 0) ? 0 : msec;
-
-  return (msec <= 0);
+  
+  msec = ((data->expiration.tv_sec  - current_time->tv_sec) * 1000 +
+         (data->expiration.tv_usec - current_time->tv_usec) / 1000);
+  
+  if (msec < 0)
+    msec = 0;
+  else if (msec > data->interval)
+    {
+      /* The system time has been set backwards, so we
+       * reset the expiration time to now + data->interval;
+       * this at least avoids hanging for long periods of time.
+       */
+      g_timeout_set_expiration (data, current_time);
+      msec = data->interval;
+    }
+  
+  *timeout = msec;
+  
+  return msec == 0;
 }
 
 static gboolean 
@@ -1256,62 +1293,44 @@ g_timeout_check (gpointer  source_data,
                 gpointer  user_data)
 {
   GTimeoutData *data = source_data;
-
-  return (data->expiration.tv_sec < current_time->tv_sec) ||
-         ((data->expiration.tv_sec == current_time->tv_sec) &&
-         (data->expiration.tv_usec <= current_time->tv_usec));
+  
+  return ((data->expiration.tv_sec < current_time->tv_sec) ||
+         ((data->expiration.tv_sec == current_time->tv_sec) &&
+          (data->expiration.tv_usec <= current_time->tv_usec)));
 }
 
 static gboolean
-g_timeout_dispatch (gpointer source_data, 
-                   GTimeVal *current_time,
+g_timeout_dispatch (gpointer source_data,
+                   GTimeVal *dispatch_time,
                    gpointer user_data)
 {
   GTimeoutData *data = source_data;
 
   if (data->callback (user_data))
     {
-      guint seconds = data->interval / 1000;
-      guint msecs = data->interval - seconds * 1000;
+      g_timeout_set_expiration (data, dispatch_time);
 
-      data->expiration.tv_sec = current_time->tv_sec + seconds;
-      data->expiration.tv_usec = current_time->tv_usec + msecs * 1000;
-      if (data->expiration.tv_usec >= 1000000)
-       {
-         data->expiration.tv_usec -= 1000000;
-         data->expiration.tv_sec++;
-       }
       return TRUE;
     }
   else
     return FALSE;
 }
 
-guint 
+guint
 g_timeout_add_full (gint           priority,
-                   guint          interval, 
+                   guint          interval,
                    GSourceFunc    function,
                    gpointer       data,
                    GDestroyNotify notify)
 {
-  guint seconds;
-  guint msecs;
   GTimeoutData *timeout_data = g_new (GTimeoutData, 1);
+  GTimeVal current_time;
 
   timeout_data->interval = interval;
   timeout_data->callback = function;
-  g_get_current_time (&timeout_data->expiration);
-
-  seconds = timeout_data->interval / 1000;
-  msecs = timeout_data->interval - seconds * 1000;
+  g_get_current_time (&current_time);
 
-  timeout_data->expiration.tv_sec += seconds;
-  timeout_data->expiration.tv_usec += msecs * 1000;
-  if (timeout_data->expiration.tv_usec >= 1000000)
-    {
-      timeout_data->expiration.tv_usec -= 1000000;
-      timeout_data->expiration.tv_sec++;
-    }
+  g_timeout_set_expiration (timeout_data, &current_time);
 
   return g_source_add (priority, FALSE, &timeout_funcs, timeout_data, data, notify);
 }
@@ -1333,7 +1352,8 @@ g_idle_prepare  (gpointer  source_data,
                 gint     *timeout,
                 gpointer  user_data)
 {
-  timeout = 0;
+  *timeout = 0;
+
   return TRUE;
 }
 
@@ -1347,7 +1367,7 @@ g_idle_check    (gpointer  source_data,
 
 static gboolean
 g_idle_dispatch (gpointer source_data, 
-                GTimeVal *current_time,
+                GTimeVal *dispatch_time,
                 gpointer user_data)
 {
   GSourceFunc func = source_data;