From ed745042e03c383f6ca4387e59078a5616b314e1 Mon Sep 17 00:00:00 2001 From: Tom Hughes Date: Sun, 13 Dec 2009 13:30:09 -0800 Subject: [PATCH] Use monotonic clock for _dbus_get_current_time() if it's available. _dbus_get_current_time() is used for timeouts, but uses gettimeofday(), which relies on the wall clock time, which can change. If the time is changed forwards or backwards, the timeouts are no longer valid, so the monotonic clock must be used. --- configure.in | 3 +++ dbus/dbus-sysdeps-unix.c | 13 ++++++++++++- 2 files changed, 15 insertions(+), 1 deletions(-) diff --git a/configure.in b/configure.in index 7ef6632..6000dc4 100644 --- a/configure.in +++ b/configure.in @@ -922,6 +922,9 @@ if test x$dbus_win = xyes ; then NETWORK_libs="-lws2_32" fi +# librt detection +AC_CHECK_LIB(rt, clock_gettime) + #### Set up final flags DBUS_CLIENT_CFLAGS= DBUS_CLIENT_LIBS="$THREAD_LIBS $NETWORK_libs" diff --git a/dbus/dbus-sysdeps-unix.c b/dbus/dbus-sysdeps-unix.c index eb6f963..c583b6e 100644 --- a/dbus/dbus-sysdeps-unix.c +++ b/dbus/dbus-sysdeps-unix.c @@ -2399,7 +2399,8 @@ _dbus_poll (DBusPollFD *fds, } /** - * Get current time, as in gettimeofday(). + * Get current time, as in gettimeofday(). Use the monotonic clock if + * available, to avoid problems when the system time changes. * * @param tv_sec return location for number of seconds * @param tv_usec return location for number of microseconds (thousandths) @@ -2410,12 +2411,22 @@ _dbus_get_current_time (long *tv_sec, { struct timeval t; +#if defined(_POSIX_TIMERS) && defined(_POSIX_MONOTONIC_CLOCK) + struct timespec ts; + clock_gettime(CLOCK_MONOTONIC, &ts); + + if (tv_sec) + *tv_sec = ts.tv_sec; + if (tv_usec) + *tv_usec = ts.tv_nsec / 1000; +#else gettimeofday (&t, NULL); if (tv_sec) *tv_sec = t.tv_sec; if (tv_usec) *tv_usec = t.tv_usec; +#endif } /** -- 1.5.4.3