From adcb31e53532708a15317f68f49871c45445f48e Mon Sep 17 00:00:00 2001 From: Owen Taylor Date: Thu, 27 Jan 2000 17:06:14 +0000 Subject: [PATCH] Bug #4156 - Changes vaguely modelled after Scott Gifford's patch Fri Jan 28 11:37:41 2000 Owen Taylor Bug #4156 - Changes vaguely modelled after Scott Gifford's patch * gtimer.c (g_timer_elapsed): Never report negative times - clip times to 0. * gmain.c (g_timeout_prepare): Guard against unexpected clock shifts by never setting a timeout of more than data->interval msecs. --- ChangeLog | 11 +++++++++ ChangeLog.pre-2-0 | 11 +++++++++ ChangeLog.pre-2-10 | 11 +++++++++ ChangeLog.pre-2-12 | 11 +++++++++ ChangeLog.pre-2-2 | 11 +++++++++ ChangeLog.pre-2-4 | 11 +++++++++ ChangeLog.pre-2-6 | 11 +++++++++ ChangeLog.pre-2-8 | 11 +++++++++ glib/gmain.c | 59 ++++++++++++++++++++++++++-------------------- glib/gtimer.c | 14 ++++++++--- gmain.c | 59 ++++++++++++++++++++++++++-------------------- gtimer.c | 14 ++++++++--- 12 files changed, 178 insertions(+), 56 deletions(-) diff --git a/ChangeLog b/ChangeLog index f65aa7317..513e96dc2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +Fri Jan 28 11:37:41 2000 Owen Taylor + + Bug #4156 - Changes vaguely modelled after Scott Gifford's patch + + * gtimer.c (g_timer_elapsed): Never report negative times - + clip times to 0. + + * gmain.c (g_timeout_prepare): Guard against unexpected + clock shifts by never setting a timeout of more than + data->interval msecs. + Wed Jan 26 05:29:11 2000 Tim Janik * glib.h: diff --git a/ChangeLog.pre-2-0 b/ChangeLog.pre-2-0 index f65aa7317..513e96dc2 100644 --- a/ChangeLog.pre-2-0 +++ b/ChangeLog.pre-2-0 @@ -1,3 +1,14 @@ +Fri Jan 28 11:37:41 2000 Owen Taylor + + Bug #4156 - Changes vaguely modelled after Scott Gifford's patch + + * gtimer.c (g_timer_elapsed): Never report negative times - + clip times to 0. + + * gmain.c (g_timeout_prepare): Guard against unexpected + clock shifts by never setting a timeout of more than + data->interval msecs. + Wed Jan 26 05:29:11 2000 Tim Janik * glib.h: diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10 index f65aa7317..513e96dc2 100644 --- a/ChangeLog.pre-2-10 +++ b/ChangeLog.pre-2-10 @@ -1,3 +1,14 @@ +Fri Jan 28 11:37:41 2000 Owen Taylor + + Bug #4156 - Changes vaguely modelled after Scott Gifford's patch + + * gtimer.c (g_timer_elapsed): Never report negative times - + clip times to 0. + + * gmain.c (g_timeout_prepare): Guard against unexpected + clock shifts by never setting a timeout of more than + data->interval msecs. + Wed Jan 26 05:29:11 2000 Tim Janik * glib.h: diff --git a/ChangeLog.pre-2-12 b/ChangeLog.pre-2-12 index f65aa7317..513e96dc2 100644 --- a/ChangeLog.pre-2-12 +++ b/ChangeLog.pre-2-12 @@ -1,3 +1,14 @@ +Fri Jan 28 11:37:41 2000 Owen Taylor + + Bug #4156 - Changes vaguely modelled after Scott Gifford's patch + + * gtimer.c (g_timer_elapsed): Never report negative times - + clip times to 0. + + * gmain.c (g_timeout_prepare): Guard against unexpected + clock shifts by never setting a timeout of more than + data->interval msecs. + Wed Jan 26 05:29:11 2000 Tim Janik * glib.h: diff --git a/ChangeLog.pre-2-2 b/ChangeLog.pre-2-2 index f65aa7317..513e96dc2 100644 --- a/ChangeLog.pre-2-2 +++ b/ChangeLog.pre-2-2 @@ -1,3 +1,14 @@ +Fri Jan 28 11:37:41 2000 Owen Taylor + + Bug #4156 - Changes vaguely modelled after Scott Gifford's patch + + * gtimer.c (g_timer_elapsed): Never report negative times - + clip times to 0. + + * gmain.c (g_timeout_prepare): Guard against unexpected + clock shifts by never setting a timeout of more than + data->interval msecs. + Wed Jan 26 05:29:11 2000 Tim Janik * glib.h: diff --git a/ChangeLog.pre-2-4 b/ChangeLog.pre-2-4 index f65aa7317..513e96dc2 100644 --- a/ChangeLog.pre-2-4 +++ b/ChangeLog.pre-2-4 @@ -1,3 +1,14 @@ +Fri Jan 28 11:37:41 2000 Owen Taylor + + Bug #4156 - Changes vaguely modelled after Scott Gifford's patch + + * gtimer.c (g_timer_elapsed): Never report negative times - + clip times to 0. + + * gmain.c (g_timeout_prepare): Guard against unexpected + clock shifts by never setting a timeout of more than + data->interval msecs. + Wed Jan 26 05:29:11 2000 Tim Janik * glib.h: diff --git a/ChangeLog.pre-2-6 b/ChangeLog.pre-2-6 index f65aa7317..513e96dc2 100644 --- a/ChangeLog.pre-2-6 +++ b/ChangeLog.pre-2-6 @@ -1,3 +1,14 @@ +Fri Jan 28 11:37:41 2000 Owen Taylor + + Bug #4156 - Changes vaguely modelled after Scott Gifford's patch + + * gtimer.c (g_timer_elapsed): Never report negative times - + clip times to 0. + + * gmain.c (g_timeout_prepare): Guard against unexpected + clock shifts by never setting a timeout of more than + data->interval msecs. + Wed Jan 26 05:29:11 2000 Tim Janik * glib.h: diff --git a/ChangeLog.pre-2-8 b/ChangeLog.pre-2-8 index f65aa7317..513e96dc2 100644 --- a/ChangeLog.pre-2-8 +++ b/ChangeLog.pre-2-8 @@ -1,3 +1,14 @@ +Fri Jan 28 11:37:41 2000 Owen Taylor + + Bug #4156 - Changes vaguely modelled after Scott Gifford's patch + + * gtimer.c (g_timer_elapsed): Never report negative times - + clip times to 0. + + * gmain.c (g_timeout_prepare): Guard against unexpected + clock shifts by never setting a timeout of more than + data->interval msecs. + Wed Jan 26 05:29:11 2000 Tim Janik * glib.h: diff --git a/glib/gmain.c b/glib/gmain.c index c2db24ce3..e4d714f0a 100644 --- a/glib/gmain.c +++ b/glib/gmain.c @@ -1233,6 +1233,22 @@ g_main_wakeup (void) /* Timeouts */ +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, @@ -1245,9 +1261,21 @@ g_timeout_prepare (gpointer 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; + 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; + } - return (msec <= 0); + *timeout = msec; + + return (msec == 0); } static gboolean @@ -1271,16 +1299,7 @@ g_timeout_dispatch (gpointer source_data, if (data->callback (user_data)) { - guint seconds = data->interval / 1000; - guint msecs = data->interval - seconds * 1000; - - data->expiration.tv_sec = dispatch_time->tv_sec + seconds; - data->expiration.tv_usec = dispatch_time->tv_usec + msecs * 1000; - if (data->expiration.tv_usec >= 1000000) - { - data->expiration.tv_usec -= 1000000; - data->expiration.tv_sec++; - } + g_timeout_set_expiration (data, dispatch_time); return TRUE; } else @@ -1294,24 +1313,14 @@ g_timeout_add_full (gint priority, 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); + g_get_current_time (¤t_time); - seconds = timeout_data->interval / 1000; - msecs = timeout_data->interval - seconds * 1000; - - 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); } diff --git a/glib/gtimer.c b/glib/gtimer.c index 854ec6714..f4b72edf6 100644 --- a/glib/gtimer.c +++ b/glib/gtimer.c @@ -184,9 +184,17 @@ g_timer_elapsed (GTimer *timer, elapsed.tv_sec = rtimer->end.tv_sec - rtimer->start.tv_sec; total = elapsed.tv_sec + ((gdouble) elapsed.tv_usec / 1e6); - - if (microseconds) - *microseconds = elapsed.tv_usec; + if (total < 0) + { + total = 0; + + if (microseconds) + *microseconds = 0; + } + else + if (microseconds) + *microseconds = elapsed.tv_usec; + #endif /* !NATIVE_WIN32 */ return total; diff --git a/gmain.c b/gmain.c index c2db24ce3..e4d714f0a 100644 --- a/gmain.c +++ b/gmain.c @@ -1233,6 +1233,22 @@ g_main_wakeup (void) /* Timeouts */ +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, @@ -1245,9 +1261,21 @@ g_timeout_prepare (gpointer 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; + 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; + } - return (msec <= 0); + *timeout = msec; + + return (msec == 0); } static gboolean @@ -1271,16 +1299,7 @@ g_timeout_dispatch (gpointer source_data, if (data->callback (user_data)) { - guint seconds = data->interval / 1000; - guint msecs = data->interval - seconds * 1000; - - data->expiration.tv_sec = dispatch_time->tv_sec + seconds; - data->expiration.tv_usec = dispatch_time->tv_usec + msecs * 1000; - if (data->expiration.tv_usec >= 1000000) - { - data->expiration.tv_usec -= 1000000; - data->expiration.tv_sec++; - } + g_timeout_set_expiration (data, dispatch_time); return TRUE; } else @@ -1294,24 +1313,14 @@ g_timeout_add_full (gint priority, 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); + g_get_current_time (¤t_time); - seconds = timeout_data->interval / 1000; - msecs = timeout_data->interval - seconds * 1000; - - 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); } diff --git a/gtimer.c b/gtimer.c index 854ec6714..f4b72edf6 100644 --- a/gtimer.c +++ b/gtimer.c @@ -184,9 +184,17 @@ g_timer_elapsed (GTimer *timer, elapsed.tv_sec = rtimer->end.tv_sec - rtimer->start.tv_sec; total = elapsed.tv_sec + ((gdouble) elapsed.tv_usec / 1e6); - - if (microseconds) - *microseconds = elapsed.tv_usec; + if (total < 0) + { + total = 0; + + if (microseconds) + *microseconds = 0; + } + else + if (microseconds) + *microseconds = elapsed.tv_usec; + #endif /* !NATIVE_WIN32 */ return total;