From 67ff8201d10af63dc93084b240fec69a3d190999 Mon Sep 17 00:00:00 2001
From: dprice <dprice@users.savannah.nongnu.org>
Date: Sun, 19 Jul 2009 04:07:30 +0000
Subject: [PATCH] Merge imperfectly synchronized time() & gettimeofday() fixes
 from production.

---
 ChangeLog     |  5 +++++
 NEWS          |  3 +++
 src/ChangeLog |  5 +++++
 src/subr.c    | 37 ++++++++++++++++++++++++-------------
 4 files changed, 37 insertions(+), 13 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 661fe2838..c47db80e4 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2009-07-18  Derek R. Price  <derek@ximbiot.com>
+
+	* NEWS: Note timestamp fix for systems with imperfectly synchronized
+	time() & gettimeofday() functions.
+
 2008-11-25  Larry Jones  <lawrence.jones@siemens.com>
 
 	* HACKING, NEWS: Note update to Autoconf 2.63.
diff --git a/NEWS b/NEWS
index 863030da5..2dbbdfb40 100644
--- a/NEWS
+++ b/NEWS
@@ -50,6 +50,9 @@ NEW FEATURES
 
 BUG FIXES
 
+* Time stamps are set correctly on systems where time() and gettimeofday()
+  return times with different values for the current second.
+
 * Changing keyword substitution mode no longer interferes with conflict
   tracking (fixes bug #17565).
 
diff --git a/src/ChangeLog b/src/ChangeLog
index c65df7808..0fbbb8625 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,8 @@
+2009-07-18  Derek R. Price  <derek@ximbiot.com>
+
+	* subr.c (sleep_past): Don't assume that time() called after
+	gettimeofday() must return a seconds value >= than gettimeofday() did.
+
 2008-12-02  Larry Jones  <lawrence.jones@siemens.com>
 
 	* commit.c: Remove defunct variable (got_message).
diff --git a/src/subr.c b/src/subr.c
index 2895f1e3a..914a8079c 100644
--- a/src/subr.c
+++ b/src/subr.c
@@ -906,27 +906,37 @@ sleep_past (time_t desttime)
     time_t t;
     long s;
     long us;
-
+/*    printf ("sleep requested until %d, current time it %d\n",
+	    desttime, time(&t));  */
     while (time (&t) <= desttime)
     {
 #ifdef HAVE_GETTIMEOFDAY
 	struct timeval tv;
 	gettimeofday (&tv, NULL);
-	if (tv.tv_sec > desttime)
-	    break;
-	s = desttime - tv.tv_sec;
-	if (tv.tv_usec > 0)
-	    us = 1000000 - tv.tv_usec;
+	if (tv.tv_sec <= desttime) {
+	    s = desttime - tv.tv_sec;
+	    if (tv.tv_usec > 0)
+		us = 1000000 - tv.tv_usec;
+	    else
+	    {
+		s++;
+		us = 0;
+	    }
+	}
 	else
+#endif
 	{
-	    s++;
-	    us = 0;
+	    /* On at least one Linux 2.6.24 system, time() lags behind
+	     * gettimeofday() by up to 10 msec, and file time stamps use
+	     * time().  For example, time() might return 1247677670 while
+	     * gettimeofday() returns 1247677671.000060, so we always sleep
+	     * at least 20ms and retry the test using time(), like we do when
+	     * gettimeofday() is not available.
+ 	     */
+	    /* default to 20 ms increments */
+	    us = 20000;
+	    s = desttime - t;
 	}
-#else
-	/* default to 20 ms increments */
-	s = desttime - t;
-	us = 20000;
-#endif
 
 	{
 	    struct timespec ts;
@@ -935,6 +945,7 @@ sleep_past (time_t desttime)
 	    (void)nanosleep (&ts, NULL);
 	}
     }
+    /* printf ("slept until %d\n", time(&t));  */
 }
 
 
-- 
GitLab