Use monotonic clock for _dbus_get_current_time() if it's available.
authorTom Hughes <tom.hughes@palm.com>
Sun, 13 Dec 2009 21:30:09 +0000 (13:30 -0800)
committerColin Walters <walters@verbum.org>
Tue, 2 Feb 2010 15:29:03 +0000 (10:29 -0500)
_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.

https://bugs.freedesktop.org/show_bug.cgi?id=25624

Signed-off-by: Colin Walters <walters@verbum.org>
dbus/dbus-sysdeps-unix.c

index 66bcf3cb8fc6651d646a8d595b5bccf2f31b5b37..ce3475a6ec76157decb559c5c6fccd48ed640798 100644 (file)
@@ -2036,7 +2036,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)
@@ -2047,12 +2048,22 @@ _dbus_get_current_time (long *tv_sec,
 {
   struct timeval t;
 
+#ifdef HAVE_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
 }
 
 /**