#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 */
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,
GTimeVal *current_time,
gpointer user_data);
static gboolean g_idle_dispatch (gpointer source_data,
- GTimeVal *current_time,
+ GTimeVal *dispatch_time,
gpointer user_data);
/* Data */
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;
# 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)
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.
#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
return ready;
}
-#endif /* !NATIVE_WIN32 */
+#endif /* !G_OS_WIN32 */
static GPollFunc poll_func = g_poll;
#endif /* !HAVE_POLL */
void
g_get_current_time (GTimeVal *result)
{
-#ifndef NATIVE_WIN32
+#ifndef G_OS_WIN32
struct timeval r;
g_return_if_fail (result != NULL);
/* HOLDS: main_loop_lock */
static void
-g_main_dispatch (GTimeVal *current_time)
+g_main_dispatch (GTimeVal *dispatch_time)
{
while (pending_dispatches != NULL)
{
G_UNLOCK (main_loop);
need_destroy = ! dispatch (source_data,
- current_time,
+ dispatch_time,
hook_data);
G_LOCK (main_loop);
gboolean dispatch)
{
GHook *hook;
- GTimeVal current_time ={ 0, 0 };
+ GTimeVal current_time = { 0, 0 };
gint n_ready = 0;
gint current_priority = 0;
gint timeout;
g_main_poll (timeout, n_ready > 0, current_priority);
+ if (timeout != 0)
+ g_get_current_time (¤t_time);
+
/* Check to see what sources need to be dispatched */
n_ready = 0;
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)
#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
#ifdef G_THREADS_ENABLED
if (!poll_waiting)
{
-#ifndef NATIVE_WIN32
+#ifndef G_OS_WIN32
gchar c;
read (wake_up_pipe[0], &c, 1);
#endif
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;
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);
/* 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
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 (¤t_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, ¤t_time);
return g_source_add (priority, FALSE, &timeout_funcs, timeout_data, data, notify);
}
gint *timeout,
gpointer user_data)
{
- timeout = 0;
+ *timeout = 0;
+
return TRUE;
}
static gboolean
g_idle_dispatch (gpointer source_data,
- GTimeVal *current_time,
+ GTimeVal *dispatch_time,
gpointer user_data)
{
GSourceFunc func = source_data;