gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[GNUnet-SVN] [gnurl] 06/116: timediff: return timediff_t from the time d


From: gnunet
Subject: [GNUnet-SVN] [gnurl] 06/116: timediff: return timediff_t from the time diff functions
Date: Tue, 05 Dec 2017 14:50:36 +0100

This is an automated email from the git hooks/post-receive script.

ng0 pushed a commit to branch master
in repository gnurl.

commit b9d25f9a6b3ca791385b80a6a3c3fa5ae113e1e0
Author: Daniel Stenberg <address@hidden>
AuthorDate: Mon Oct 23 12:05:49 2017 +0200

    timediff: return timediff_t from the time diff functions
    
    ... to cater for systems with unsigned time_t variables.
    
    - Renamed the functions to curlx_timediff and Curl_timediff_us.
    
    - Added overflow protection for both of them in either direction for
      both 32 bit and 64 bit time_ts
    
    - Reprefixed the curlx_time functions to use Curl_*
    
    Reported-by: Peter Piekarski
    Fixes #2004
    Closes #2005
---
 lib/asyn-ares.c           |   2 +-
 lib/asyn-thread.c         |   3 +-
 lib/connect.c             |   8 ++--
 lib/easy.c                |  12 ++---
 lib/ftp.c                 |   2 +-
 lib/hostip.c              |   4 +-
 lib/multi.c               |  24 +++++-----
 lib/pingpong.c            |   4 +-
 lib/progress.c            |  18 ++++----
 lib/rand.c                |   2 +-
 lib/select.c              |   8 ++--
 lib/speedcheck.c          |   2 +-
 lib/telnet.c              |   4 +-
 lib/timeval.c             |  55 ++++++++++++-----------
 lib/timeval.h             |  27 +++++------
 lib/transfer.c            |   9 ++--
 lib/url.c                 |  14 +++---
 lib/vtls/openssl.c        |   8 ++--
 tests/server/Makefile.inc |   2 -
 tests/server/util.c       | 111 +++++++++++++++++++++++++++++++++++++++++++---
 tests/server/util.h       |   3 +-
 tests/unit/unit1323.c     |   2 +-
 22 files changed, 214 insertions(+), 110 deletions(-)

diff --git a/lib/asyn-ares.c b/lib/asyn-ares.c
index 87e70b4d9..0fbf321b9 100644
--- a/lib/asyn-ares.c
+++ b/lib/asyn-ares.c
@@ -401,7 +401,7 @@ CURLcode Curl_resolver_wait_resolv(struct connectdata *conn,
       result = CURLE_ABORTED_BY_CALLBACK;
     else {
       struct curltime now2 = Curl_tvnow();
-      time_t timediff = Curl_tvdiff(now2, now); /* spent time */
+      timediff_t timediff = Curl_timediff(now2, now); /* spent time */
       if(timediff <= 0)
         timeout -= 1; /* always deduct at least 1 */
       else if(timediff > timeout)
diff --git a/lib/asyn-thread.c b/lib/asyn-thread.c
index a86772965..96babb728 100644
--- a/lib/asyn-thread.c
+++ b/lib/asyn-thread.c
@@ -535,7 +535,8 @@ CURLcode Curl_resolver_is_resolved(struct connectdata *conn,
   }
   else {
     /* poll for name lookup done with exponential backoff up to 250ms */
-    time_t elapsed = Curl_tvdiff(Curl_tvnow(), data->progress.t_startsingle);
+    timediff_t elapsed = Curl_timediff(Curl_tvnow(),
+                                       data->progress.t_startsingle);
     if(elapsed < 0)
       elapsed = 0;
 
diff --git a/lib/connect.c b/lib/connect.c
index b7d10af55..7bf82d14a 100755
--- a/lib/connect.c
+++ b/lib/connect.c
@@ -225,10 +225,10 @@ time_t Curl_timeleft(struct Curl_easy *data,
   /* subtract elapsed time */
   if(duringconnect)
     /* since this most recent connect started */
-    timeout_ms -= Curl_tvdiff(*nowp, data->progress.t_startsingle);
+    timeout_ms -= Curl_timediff(*nowp, data->progress.t_startsingle);
   else
     /* since the entire operation started */
-    timeout_ms -= Curl_tvdiff(*nowp, data->progress.t_startop);
+    timeout_ms -= Curl_timediff(*nowp, data->progress.t_startop);
   if(!timeout_ms)
     /* avoid returning 0 as that means no timeout! */
     return -1;
@@ -765,7 +765,7 @@ CURLcode Curl_is_connected(struct connectdata *conn,
 
     if(rc == 0) { /* no connection yet */
       error = 0;
-      if(curlx_tvdiff(now, conn->connecttime) >= conn->timeoutms_per_addr) {
+      if(Curl_timediff(now, conn->connecttime) >= conn->timeoutms_per_addr) {
         infof(data, "After %ldms connect time, move on!\n",
               conn->timeoutms_per_addr);
         error = ETIMEDOUT;
@@ -773,7 +773,7 @@ CURLcode Curl_is_connected(struct connectdata *conn,
 
       /* should we try another protocol family? */
       if(i == 0 && conn->tempaddr[1] == NULL &&
-         curlx_tvdiff(now, conn->connecttime) >= HAPPY_EYEBALLS_TIMEOUT) {
+         Curl_timediff(now, conn->connecttime) >= HAPPY_EYEBALLS_TIMEOUT) {
         trynextip(conn, sockindex, 1);
       }
     }
diff --git a/lib/easy.c b/lib/easy.c
index 5328f9c2d..212d6f3da 100644
--- a/lib/easy.c
+++ b/lib/easy.c
@@ -586,12 +586,12 @@ static CURLcode wait_or_timeout(struct Curl_multi *multi, 
struct events *ev)
     }
 
     /* get the time stamp to use to figure out how long poll takes */
-    before = curlx_tvnow();
+    before = Curl_tvnow();
 
     /* wait for activity or timeout */
     pollrc = Curl_poll(fds, numfds, (int)ev->ms);
 
-    after = curlx_tvnow();
+    after = Curl_tvnow();
 
     ev->msbump = FALSE; /* reset here */
 
@@ -619,7 +619,7 @@ static CURLcode wait_or_timeout(struct Curl_multi *multi, 
struct events *ev)
         /* If nothing updated the timeout, we decrease it by the spent time.
          * If it was updated, it has the new timeout time stored already.
          */
-        time_t timediff = curlx_tvdiff(after, before);
+        timediff_t timediff = Curl_timediff(after, before);
         if(timediff > 0) {
           if(timediff > ev->ms)
             ev->ms = 0;
@@ -680,17 +680,17 @@ static CURLcode easy_transfer(struct Curl_multi *multi)
     int still_running = 0;
     int rc;
 
-    before = curlx_tvnow();
+    before = Curl_tvnow();
     mcode = curl_multi_wait(multi, NULL, 0, 1000, &rc);
 
     if(!mcode) {
       if(!rc) {
-        struct curltime after = curlx_tvnow();
+        struct curltime after = Curl_tvnow();
 
         /* If it returns without any filedescriptor instantly, we need to
            avoid busy-looping during periods where it has nothing particular
            to wait for */
-        if(curlx_tvdiff(after, before) <= 10) {
+        if(Curl_timediff(after, before) <= 10) {
           without_fds++;
           if(without_fds > 2) {
             int sleep_ms = without_fds < 10 ? (1 << (without_fds - 1)) : 1000;
diff --git a/lib/ftp.c b/lib/ftp.c
index edcfd5f80..905728778 100644
--- a/lib/ftp.c
+++ b/lib/ftp.c
@@ -351,7 +351,7 @@ static time_t ftp_timeleft_accept(struct Curl_easy *data)
     timeout_ms = other;
   else {
     /* subtract elapsed time */
-    timeout_ms -= Curl_tvdiff(now, data->progress.t_acceptdata);
+    timeout_ms -= Curl_timediff(now, data->progress.t_acceptdata);
     if(!timeout_ms)
       /* avoid returning 0 as that means no timeout! */
       return -1;
diff --git a/lib/hostip.c b/lib/hostip.c
index 1a18a3ed7..1f988e9ac 100644
--- a/lib/hostip.c
+++ b/lib/hostip.c
@@ -688,8 +688,8 @@ clean_up:
      the time we spent until now! */
   if(prev_alarm) {
     /* there was an alarm() set before us, now put it back */
-    unsigned long elapsed_secs = (unsigned long) (Curl_tvdiff(Curl_tvnow(),
-                                   conn->created) / 1000);
+    timediff_t elapsed_secs = Curl_timediff(Curl_tvnow(),
+                                            conn->created) / 1000;
 
     /* the alarm period is counted in even number of seconds */
     unsigned long alarm_set = prev_alarm - elapsed_secs;
diff --git a/lib/multi.c b/lib/multi.c
index caceaf589..eb6a633a3 100644
--- a/lib/multi.c
+++ b/lib/multi.c
@@ -1380,23 +1380,23 @@ static CURLMcode multi_runsingle(struct Curl_multi 
*multi,
         /* Handle timed out */
         if(data->mstate == CURLM_STATE_WAITRESOLVE)
           failf(data, "Resolving timed out after %ld milliseconds",
-                Curl_tvdiff(now, data->progress.t_startsingle));
+                Curl_timediff(now, data->progress.t_startsingle));
         else if(data->mstate == CURLM_STATE_WAITCONNECT)
           failf(data, "Connection timed out after %ld milliseconds",
-                Curl_tvdiff(now, data->progress.t_startsingle));
+                Curl_timediff(now, data->progress.t_startsingle));
         else {
           k = &data->req;
           if(k->size != -1) {
             failf(data, "Operation timed out after %ld milliseconds with %"
                   CURL_FORMAT_CURL_OFF_T " out of %"
                   CURL_FORMAT_CURL_OFF_T " bytes received",
-                  Curl_tvdiff(now, data->progress.t_startsingle),
+                  Curl_timediff(now, data->progress.t_startsingle),
                   k->bytecount, k->size);
           }
           else {
             failf(data, "Operation timed out after %ld milliseconds with %"
                   CURL_FORMAT_CURL_OFF_T " bytes received",
-                  Curl_tvdiff(now, data->progress.t_startsingle),
+                  Curl_timediff(now, data->progress.t_startsingle),
                   k->bytecount);
           }
         }
@@ -2514,9 +2514,9 @@ static CURLMcode add_next_timeout(struct curltime now,
      timeout in *tv */
   for(e = list->head; e;) {
     struct curl_llist_element *n = e->next;
-    time_t diff;
+    timediff_t diff;
     node = (struct time_node *)e->ptr;
-    diff = curlx_tvdiff(node->time, now);
+    diff = Curl_timediff(node->time, now);
     if(diff <= 0)
       /* remove outdated entry */
       Curl_llist_remove(list, e, NULL);
@@ -2790,8 +2790,8 @@ static CURLMcode multi_timeout(struct Curl_multi *multi,
 
     if(Curl_splaycomparekeys(multi->timetree->key, now) > 0) {
       /* some time left before expiration */
-      *timeout_ms = (long)curlx_tvdiff(multi->timetree->key, now);
-      if(!*timeout_ms)
+      timediff_t diff = Curl_timediff(multi->timetree->key, now);
+      if(diff <= 0)
         /*
          * Since we only provide millisecond resolution on the returned value
          * and the diff might be less than one millisecond here, we don't
@@ -2800,6 +2800,10 @@ static CURLMcode multi_timeout(struct Curl_multi *multi,
          * millisecond! instead we return 1 until the time is ripe.
          */
         *timeout_ms = 1;
+      else
+        /* this should be safe even on 64 bit archs, as we don't use that
+           overly long timeouts */
+        *timeout_ms = (long)diff;
     }
     else
       /* 0 means immediately */
@@ -2906,7 +2910,7 @@ multi_addtimeout(struct Curl_easy *data,
     /* find the correct spot in the list */
     for(e = timeoutlist->head; e; e = e->next) {
       struct time_node *check = (struct time_node *)e->ptr;
-      time_t diff = curlx_tvdiff(check->time, node->time);
+      timediff_t diff = Curl_timediff(check->time, node->time);
       if(diff > 0)
         break;
       prev = e;
@@ -2965,7 +2969,7 @@ void Curl_expire(struct Curl_easy *data, time_t milli, 
expire_id id)
     /* This means that the struct is added as a node in the splay tree.
        Compare if the new time is earlier, and only remove-old/add-new if it
        is. */
-    time_t diff = curlx_tvdiff(set, *nowp);
+    timediff_t diff = Curl_timediff(set, *nowp);
 
     if(diff > 0) {
       /* The current splay tree entry is sooner than this new expiry time.
diff --git a/lib/pingpong.c b/lib/pingpong.c
index ef865ae54..278405f72 100644
--- a/lib/pingpong.c
+++ b/lib/pingpong.c
@@ -61,12 +61,12 @@ time_t Curl_pp_state_timeout(struct pingpong *pp)
   /* Without a requested timeout, we only wait 'response_time' seconds for the
      full response to arrive before we bail out */
   timeout_ms = response_time -
-    Curl_tvdiff(Curl_tvnow(), pp->response); /* spent time */
+    Curl_timediff(Curl_tvnow(), pp->response); /* spent time */
 
   if(data->set.timeout) {
     /* if timeout is requested, find out how much remaining time we have */
     timeout2_ms = data->set.timeout - /* timeout time */
-      Curl_tvdiff(Curl_tvnow(), conn->now); /* spent time */
+      Curl_timediff(Curl_tvnow(), conn->now); /* spent time */
 
     /* pick the lowest number */
     timeout_ms = CURLMIN(timeout_ms, timeout2_ms);
diff --git a/lib/progress.c b/lib/progress.c
index 00609d9ee..03ab43c1c 100644
--- a/lib/progress.c
+++ b/lib/progress.c
@@ -212,13 +212,13 @@ void Curl_pgrsTime(struct Curl_easy *data, timerid timer)
     /* this is the normal end-of-transfer thing */
     break;
   case TIMER_REDIRECT:
-    data->progress.t_redirect = Curl_tvdiff_us(now, data->progress.start);
+    data->progress.t_redirect = Curl_timediff_us(now, data->progress.start);
     break;
   }
   if(delta) {
-    time_t us = Curl_tvdiff_us(now, data->progress.t_startsingle);
-    if(!us)
-      us++; /* make sure at least one microsecond passed */
+    timediff_t us = Curl_timediff_us(now, data->progress.t_startsingle);
+    if(us < 1)
+      us = 1; /* make sure at least one microsecond passed */
     *delta += us;
   }
 }
@@ -274,7 +274,7 @@ long Curl_pgrsLimitWaitTime(curl_off_t cursize,
     return -1;
 
   minimum = (time_t) (CURL_OFF_T_C(1000) * size / limit);
-  actual = Curl_tvdiff(now, start);
+  actual = Curl_timediff(now, start);
 
   if(actual < minimum)
     /* this is a conversion on some systems (64bit time_t => 32bit long) */
@@ -373,7 +373,7 @@ int Curl_pgrsUpdate(struct connectdata *conn)
   now = Curl_tvnow(); /* what time is it */
 
   /* The time spent so far (from the start) */
-  data->progress.timespent = Curl_tvdiff_us(now, data->progress.start);
+  data->progress.timespent = Curl_timediff_us(now, data->progress.start);
   timespent = (curl_off_t)data->progress.timespent/1000000; /* seconds */
 
   /* The average download speed this far */
@@ -413,7 +413,7 @@ int Curl_pgrsUpdate(struct connectdata *conn)
 
     /* first of all, we don't do this if there's no counted seconds yet */
     if(countindex) {
-      time_t span_ms;
+      timediff_t span_ms;
 
       /* Get the index position to compare with the 'nowindex' position.
          Get the oldest entry possible. While we have less than CURR_TIME
@@ -422,8 +422,8 @@ int Curl_pgrsUpdate(struct connectdata *conn)
         data->progress.speeder_c%CURR_TIME:0;
 
       /* Figure out the exact time for the time span */
-      span_ms = Curl_tvdiff(now,
-                            data->progress.speeder_time[checkindex]);
+      span_ms = Curl_timediff(now,
+                              data->progress.speeder_time[checkindex]);
       if(0 == span_ms)
         span_ms = 1; /* at least one millisecond MUST have passed */
 
diff --git a/lib/rand.c b/lib/rand.c
index 2713a0aa3..2b08caf8c 100644
--- a/lib/rand.c
+++ b/lib/rand.c
@@ -86,7 +86,7 @@ static CURLcode randit(struct Curl_easy *data, unsigned int 
*rnd)
 #endif
 
   if(!seeded) {
-    struct curltime now = curlx_tvnow();
+    struct curltime now = Curl_tvnow();
     infof(data, "WARNING: Using weak random seed\n");
     randseed += (unsigned int)now.tv_usec + (unsigned int)now.tv_sec;
     randseed = randseed * 1103515245 + 12345;
diff --git a/lib/select.c b/lib/select.c
index f6fecaf51..e21fff1f0 100644
--- a/lib/select.c
+++ b/lib/select.c
@@ -51,7 +51,7 @@
 #include "warnless.h"
 
 /* Convenience local macros */
-#define ELAPSED_MS()  (int)curlx_tvdiff(curlx_tvnow(), initial_tv)
+#define ELAPSED_MS() (int)Curl_timediff(Curl_tvnow(), initial_tv)
 
 int Curl_ack_eintr = 0;
 #define ERROR_NOT_EINTR(error) (Curl_ack_eintr || error != EINTR)
@@ -96,7 +96,7 @@ int Curl_wait_ms(int timeout_ms)
   Sleep(timeout_ms);
 #else
   pending_ms = timeout_ms;
-  initial_tv = curlx_tvnow();
+  initial_tv = Curl_tvnow();
   do {
 #if defined(HAVE_POLL_FINE)
     r = poll(NULL, 0, pending_ms);
@@ -184,7 +184,7 @@ int Curl_socket_check(curl_socket_t readfd0, /* two sockets 
to read from */
 
   if(timeout_ms > 0) {
     pending_ms = (int)timeout_ms;
-    initial_tv = curlx_tvnow();
+    initial_tv = Curl_tvnow();
   }
 
 #ifdef HAVE_POLL_FINE
@@ -425,7 +425,7 @@ int Curl_poll(struct pollfd ufds[], unsigned int nfds, int 
timeout_ms)
 
   if(timeout_ms > 0) {
     pending_ms = timeout_ms;
-    initial_tv = curlx_tvnow();
+    initial_tv = Curl_tvnow();
   }
 
 #ifdef HAVE_POLL_FINE
diff --git a/lib/speedcheck.c b/lib/speedcheck.c
index fe669f11a..3aeea9111 100644
--- a/lib/speedcheck.c
+++ b/lib/speedcheck.c
@@ -46,7 +46,7 @@ CURLcode Curl_speedcheck(struct Curl_easy *data,
         data->state.keeps_speed = now;
       else {
         /* how long has it been under the limit */
-        time_t howlong = Curl_tvdiff(now, data->state.keeps_speed);
+        timediff_t howlong = Curl_timediff(now, data->state.keeps_speed);
 
         if(howlong >= data->set.low_speed_time * 1000) {
           /* too long */
diff --git a/lib/telnet.c b/lib/telnet.c
index a7bed3da1..a5f87d81d 100644
--- a/lib/telnet.c
+++ b/lib/telnet.c
@@ -1561,7 +1561,7 @@ static CURLcode telnet_do(struct connectdata *conn, bool 
*done)
 
     if(data->set.timeout) {
       now = Curl_tvnow();
-      if(Curl_tvdiff(now, conn->created) >= data->set.timeout) {
+      if(Curl_timediff(now, conn->created) >= data->set.timeout) {
         failf(data, "Time-out");
         result = CURLE_OPERATION_TIMEDOUT;
         keepon = FALSE;
@@ -1679,7 +1679,7 @@ static CURLcode telnet_do(struct connectdata *conn, bool 
*done)
 
     if(data->set.timeout) {
       now = Curl_tvnow();
-      if(Curl_tvdiff(now, conn->created) >= data->set.timeout) {
+      if(Curl_timediff(now, conn->created) >= data->set.timeout) {
         failf(data, "Time-out");
         result = CURLE_OPERATION_TIMEDOUT;
         keepon = FALSE;
diff --git a/lib/timeval.c b/lib/timeval.c
index d7207b3a2..6ed79ec60 100644
--- a/lib/timeval.c
+++ b/lib/timeval.c
@@ -24,7 +24,7 @@
 
 #if defined(WIN32) && !defined(MSDOS)
 
-struct curltime curlx_tvnow(void)
+struct curltime Curl_tvnow(void)
 {
   /*
   ** GetTickCount() is available on _all_ Windows versions from W95 up
@@ -48,7 +48,7 @@ struct curltime curlx_tvnow(void)
 
 #elif defined(HAVE_CLOCK_GETTIME_MONOTONIC)
 
-struct curltime curlx_tvnow(void)
+struct curltime Curl_tvnow(void)
 {
   /*
   ** clock_gettime() is granted to be increased monotonically when the
@@ -86,7 +86,7 @@ struct curltime curlx_tvnow(void)
 
 #elif defined(HAVE_GETTIMEOFDAY)
 
-struct curltime curlx_tvnow(void)
+struct curltime Curl_tvnow(void)
 {
   /*
   ** gettimeofday() is not granted to be increased monotonically, due to
@@ -103,7 +103,7 @@ struct curltime curlx_tvnow(void)
 
 #else
 
-struct curltime curlx_tvnow(void)
+struct curltime Curl_tvnow(void)
 {
   /*
   ** time() returns the value of time in seconds since the Epoch.
@@ -116,6 +116,14 @@ struct curltime curlx_tvnow(void)
 
 #endif
 
+#if SIZEOF_TIME_T < 8
+#define TIME_MAX INT_MAX
+#define TIME_MIN INT_MIN
+#else
+#define TIME_MAX 9223372036854775807LL
+#define TIME_MIN -9223372036854775807LL
+#endif
+
 /*
  * Make sure that the first argument is the more recent time, as otherwise
  * we'll get a weird negative time-diff back...
@@ -125,17 +133,15 @@ struct curltime curlx_tvnow(void)
  *
  * @unittest: 1323
  */
-time_t curlx_tvdiff(struct curltime newer, struct curltime older)
+timediff_t Curl_timediff(struct curltime newer, struct curltime older)
 {
-#if SIZEOF_TIME_T < 8
-  /* for 32bit time_t systems, add a precaution to avoid overflow for really
-     big time differences */
-  time_t diff = newer.tv_sec-older.tv_sec;
-  if(diff >= (0x7fffffff/1000))
-    return 0x7fffffff;
-#endif
-  return (newer.tv_sec-older.tv_sec)*1000+
-    (int)(newer.tv_usec-older.tv_usec)/1000;
+  timediff_t diff = newer.tv_sec-older.tv_sec;
+  if(diff >= (TIME_MAX/1000))
+    return TIME_MAX;
+  else if(diff <= (TIME_MIN/1000))
+    return TIME_MIN;
+  return (timediff_t)(newer.tv_sec-older.tv_sec)*1000+
+    (timediff_t)(newer.tv_usec-older.tv_usec)/1000;
 }
 
 /*
@@ -145,18 +151,13 @@ time_t curlx_tvdiff(struct curltime newer, struct 
curltime older)
  * Returns: the time difference in number of microseconds. For too large diffs
  * it returns max value.
  */
-time_t Curl_tvdiff_us(struct curltime newer, struct curltime older)
+timediff_t Curl_timediff_us(struct curltime newer, struct curltime older)
 {
-  time_t diff = newer.tv_sec-older.tv_sec;
-#if SIZEOF_TIME_T < 8
-  /* for 32bit time_t systems */
-  if(diff >= (0x7fffffff/1000000))
-    return 0x7fffffff;
-#else
-  /* for 64bit time_t systems */
-  if(diff >= (0x7fffffffffffffffLL/1000000))
-    return 0x7fffffffffffffffLL;
-#endif
-  return (newer.tv_sec-older.tv_sec)*1000000+
-    (int)(newer.tv_usec-older.tv_usec);
+  timediff_t diff = newer.tv_sec-older.tv_sec;
+  if(diff >= (TIME_MAX/1000000))
+    return TIME_MAX;
+  else if(diff <= (TIME_MIN/1000000))
+    return TIME_MIN;
+  return (timediff_t)(newer.tv_sec-older.tv_sec)*1000000+
+    (timediff_t)(newer.tv_usec-older.tv_usec);
 }
diff --git a/lib/timeval.h b/lib/timeval.h
index 1ee4b3044..b2f0e0d97 100644
--- a/lib/timeval.h
+++ b/lib/timeval.h
@@ -22,19 +22,21 @@
  *
  ***************************************************************************/
 
-/*
- * CAUTION: this header is designed to work when included by the app-side
- * as well as the library. Do not mix with library internals!
- */
-
 #include "curl_setup.h"
 
+#if SIZEOF_TIME_T < 8
+typedef int timediff_t;
+#else
+typedef ssize_t timediff_t;
+#endif
+
+
 struct curltime {
-  time_t       tv_sec;     /* seconds */
-  unsigned int tv_usec;    /* microseconds */
+  time_t tv_sec; /* seconds */
+  int tv_usec;   /* microseconds */
 };
 
-struct curltime curlx_tvnow(void);
+struct curltime Curl_tvnow(void);
 
 /*
  * Make sure that the first argument (t1) is the more recent time and t2 is
@@ -42,7 +44,7 @@ struct curltime curlx_tvnow(void);
  *
  * Returns: the time difference in number of milliseconds.
  */
-time_t curlx_tvdiff(struct curltime t1, struct curltime t2);
+timediff_t Curl_timediff(struct curltime t1, struct curltime t2);
 
 /*
  * Make sure that the first argument (t1) is the more recent time and t2 is
@@ -50,12 +52,7 @@ time_t curlx_tvdiff(struct curltime t1, struct curltime t2);
  *
  * Returns: the time difference in number of microseconds.
  */
-time_t Curl_tvdiff_us(struct curltime newer, struct curltime older);
-
-/* These two defines below exist to provide the older API for library
-   internals only. */
-#define Curl_tvnow() curlx_tvnow()
-#define Curl_tvdiff(x,y) curlx_tvdiff(x,y)
+timediff_t Curl_timediff_us(struct curltime newer, struct curltime older);
 
 #endif /* HEADER_CURL_TIMEVAL_H */
 
diff --git a/lib/transfer.c b/lib/transfer.c
index 8e66d0d80..4bdbd5e18 100644
--- a/lib/transfer.c
+++ b/lib/transfer.c
@@ -1174,7 +1174,7 @@ CURLcode Curl_readwrite(struct connectdata *conn,
 
       */
 
-      time_t ms = Curl_tvdiff(k->now, k->start100);
+      timediff_t ms = Curl_timediff(k->now, k->start100);
       if(ms >= data->set.expect_100_timeout) {
         /* we've waited long enough, continue anyway */
         k->exp100 = EXP100_SEND_DATA;
@@ -1198,13 +1198,14 @@ CURLcode Curl_readwrite(struct connectdata *conn,
         failf(data, "Operation timed out after %ld milliseconds with %"
               CURL_FORMAT_CURL_OFF_T " out of %"
               CURL_FORMAT_CURL_OFF_T " bytes received",
-              Curl_tvdiff(k->now, data->progress.t_startsingle), k->bytecount,
-              k->size);
+              Curl_timediff(k->now, data->progress.t_startsingle),
+              k->bytecount, k->size);
       }
       else {
         failf(data, "Operation timed out after %ld milliseconds with %"
               CURL_FORMAT_CURL_OFF_T " bytes received",
-              Curl_tvdiff(k->now, data->progress.t_startsingle), k->bytecount);
+              Curl_timediff(k->now, data->progress.t_startsingle),
+              k->bytecount);
       }
       return CURLE_OPERATION_TIMEDOUT;
     }
diff --git a/lib/url.c b/lib/url.c
index 76c09c72a..594160898 100644
--- a/lib/url.c
+++ b/lib/url.c
@@ -3459,8 +3459,8 @@ Curl_oldest_idle_connection(struct Curl_easy *data)
   struct curl_hash_iterator iter;
   struct curl_llist_element *curr;
   struct curl_hash_element *he;
-  time_t highscore =- 1;
-  time_t score;
+  timediff_t highscore =- 1;
+  timediff_t score;
   struct curltime now;
   struct connectdata *conn_candidate = NULL;
   struct connectbundle *bundle;
@@ -3481,7 +3481,7 @@ Curl_oldest_idle_connection(struct Curl_easy *data)
 
       if(!conn->inuse) {
         /* Set higher score for the age passed since the connection was used */
-        score = Curl_tvdiff(now, conn->now);
+        score = Curl_timediff(now, conn->now);
 
         if(score > highscore) {
           highscore = score;
@@ -3522,8 +3522,8 @@ find_oldest_idle_connection_in_bundle(struct Curl_easy 
*data,
                                       struct connectbundle *bundle)
 {
   struct curl_llist_element *curr;
-  time_t highscore = -1;
-  time_t score;
+  timediff_t highscore = -1;
+  timediff_t score;
   struct curltime now;
   struct connectdata *conn_candidate = NULL;
   struct connectdata *conn;
@@ -3538,7 +3538,7 @@ find_oldest_idle_connection_in_bundle(struct Curl_easy 
*data,
 
     if(!conn->inuse) {
       /* Set higher score for the age passed since the connection was used */
-      score = Curl_tvdiff(now, conn->now);
+      score = Curl_timediff(now, conn->now);
 
       if(score > highscore) {
         highscore = score;
@@ -3613,7 +3613,7 @@ static int call_disconnect_if_dead(struct connectdata 
*conn,
 static void prune_dead_connections(struct Curl_easy *data)
 {
   struct curltime now = Curl_tvnow();
-  time_t elapsed = Curl_tvdiff(now, data->state.conn_cache->last_cleanup);
+  time_t elapsed = Curl_timediff(now, data->state.conn_cache->last_cleanup);
 
   if(elapsed >= 1000L) {
     Curl_conncache_foreach(data->state.conn_cache, data,
diff --git a/lib/vtls/openssl.c b/lib/vtls/openssl.c
index f94415222..96374dc10 100644
--- a/lib/vtls/openssl.c
+++ b/lib/vtls/openssl.c
@@ -446,14 +446,14 @@ static CURLcode Curl_ossl_seed(struct Curl_easy *data)
     size_t len = sizeof(randb);
     size_t i, i_max;
     for(i = 0, i_max = len / sizeof(struct curltime); i < i_max; ++i) {
-      struct curltime tv = curlx_tvnow();
+      struct curltime tv = Curl_tvnow();
       Curl_wait_ms(1);
       tv.tv_sec *= i + 1;
       tv.tv_usec *= (unsigned int)i + 2;
-      tv.tv_sec ^= ((curlx_tvnow().tv_sec + curlx_tvnow().tv_usec) *
+      tv.tv_sec ^= ((Curl_tvnow().tv_sec + Curl_tvnow().tv_usec) *
                     (i + 3)) << 8;
-      tv.tv_usec ^= (unsigned int) ((curlx_tvnow().tv_sec +
-                                     curlx_tvnow().tv_usec) *
+      tv.tv_usec ^= (unsigned int) ((Curl_tvnow().tv_sec +
+                                     Curl_tvnow().tv_usec) *
                                     (i + 4)) << 16;
       memcpy(&randb[i * sizeof(struct curltime)], &tv,
              sizeof(struct curltime));
diff --git a/tests/server/Makefile.inc b/tests/server/Makefile.inc
index c3ea664b6..208aa0fc8 100644
--- a/tests/server/Makefile.inc
+++ b/tests/server/Makefile.inc
@@ -4,14 +4,12 @@ CURLX_SRCS = \
  ../../lib/mprintf.c \
  ../../lib/nonblock.c \
  ../../lib/strtoofft.c \
- ../../lib/timeval.c \
  ../../lib/warnless.c
 
 CURLX_HDRS = \
  ../../lib/curlx.h \
  ../../lib/nonblock.h \
  ../../lib/strtoofft.h \
- ../../lib/timeval.h \
  ../../lib/warnless.h
 
 USEFUL = \
diff --git a/tests/server/util.c b/tests/server/util.c
index 1bbd89a3c..fdbd71f0f 100644
--- a/tests/server/util.c
+++ b/tests/server/util.c
@@ -67,6 +67,8 @@ const struct in6_addr in6addr_any = {{ IN6ADDR_ANY_INIT }};
 #endif /* w32api < 3.6 */
 #endif /* ENABLE_IPV6 && __MINGW32__*/
 
+static struct timeval tvnow(void);
+
 /* This function returns a pointer to STATIC memory. It converts the given
  * binary lump to a hex formatted string usable for output in logs or
  * whatever.
@@ -100,7 +102,7 @@ void logmsg(const char *msg, ...)
   char buffer[2048 + 1];
   FILE *logfp;
   int error;
-  struct curltime tv;
+  struct timeval tv;
   time_t sec;
   struct tm *now;
   char timebuf[20];
@@ -112,7 +114,7 @@ void logmsg(const char *msg, ...)
     return;
   }
 
-  tv = curlx_tvnow();
+  tv = tvnow();
   if(!known_offset) {
     epoch_offset = time(NULL) - tv.tv_sec;
     known_offset = 1;
@@ -213,7 +215,7 @@ int wait_ms(int timeout_ms)
 #ifndef HAVE_POLL_FINE
   struct timeval pending_tv;
 #endif
-  struct curltime initial_tv;
+  struct timeval initial_tv;
   int pending_ms;
   int error;
 #endif
@@ -231,7 +233,7 @@ int wait_ms(int timeout_ms)
   Sleep(timeout_ms);
 #else
   pending_ms = timeout_ms;
-  initial_tv = curlx_tvnow();
+  initial_tv = tvnow();
   do {
 #if defined(HAVE_POLL_FINE)
     r = poll(NULL, 0, pending_ms);
@@ -245,7 +247,7 @@ int wait_ms(int timeout_ms)
     error = errno;
     if(error && (error != EINTR))
       break;
-    pending_ms = timeout_ms - (int)curlx_tvdiff(curlx_tvnow(), initial_tv);
+    pending_ms = timeout_ms - (int)timediff(tvnow(), initial_tv);
     if(pending_ms <= 0)
       break;
   } while(r == -1);
@@ -397,3 +399,102 @@ int strncasecompare(const char *first, const char 
*second, size_t max)
 
   return raw_toupper(*first) == raw_toupper(*second);
 }
+
+#if defined(WIN32) && !defined(MSDOS)
+
+static struct timeval tvnow(void)
+{
+  /*
+  ** GetTickCount() is available on _all_ Windows versions from W95 up
+  ** to nowadays. Returns milliseconds elapsed since last system boot,
+  ** increases monotonically and wraps once 49.7 days have elapsed.
+  **
+  ** GetTickCount64() is available on Windows version from Windows Vista
+  ** and Windows Server 2008 up to nowadays. The resolution of the
+  ** function is limited to the resolution of the system timer, which
+  ** is typically in the range of 10 milliseconds to 16 milliseconds.
+  */
+  struct timeval now;
+#if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0600)
+  ULONGLONG milliseconds = GetTickCount64();
+#else
+  DWORD milliseconds = GetTickCount();
+#endif
+  now.tv_sec = (long)(milliseconds / 1000);
+  now.tv_usec = (milliseconds % 1000) * 1000;
+  return now;
+}
+
+#elif defined(HAVE_CLOCK_GETTIME_MONOTONIC)
+
+static struct timeval tvnow(void)
+{
+  /*
+  ** clock_gettime() is granted to be increased monotonically when the
+  ** monotonic clock is queried. Time starting point is unspecified, it
+  ** could be the system start-up time, the Epoch, or something else,
+  ** in any case the time starting point does not change once that the
+  ** system has started up.
+  */
+  struct timeval now;
+  struct timespec tsnow;
+  if(0 == clock_gettime(CLOCK_MONOTONIC, &tsnow)) {
+    now.tv_sec = tsnow.tv_sec;
+    now.tv_usec = tsnow.tv_nsec / 1000;
+  }
+  /*
+  ** Even when the configure process has truly detected monotonic clock
+  ** availability, it might happen that it is not actually available at
+  ** run-time. When this occurs simply fallback to other time source.
+  */
+#ifdef HAVE_GETTIMEOFDAY
+  else
+    (void)gettimeofday(&now, NULL);
+#else
+  else {
+    now.tv_sec = (long)time(NULL);
+    now.tv_usec = 0;
+  }
+#endif
+  return now;
+}
+
+#elif defined(HAVE_GETTIMEOFDAY)
+
+static struct timeval tvnow(void)
+{
+  /*
+  ** gettimeofday() is not granted to be increased monotonically, due to
+  ** clock drifting and external source time synchronization it can jump
+  ** forward or backward in time.
+  */
+  struct timeval now;
+  (void)gettimeofday(&now, NULL);
+  return now;
+}
+
+#else
+
+static struct timeval tvnow(void)
+{
+  /*
+  ** time() returns the value of time in seconds since the Epoch.
+  */
+  struct timeval now;
+  now.tv_sec = (long)time(NULL);
+  now.tv_usec = 0;
+  return now;
+}
+
+#endif
+
+long timediff(struct timeval newer, struct timeval older)
+{
+  timediff_t diff = newer.tv_sec-older.tv_sec;
+  if(diff >= (LONG_MAX/1000))
+    return LONG_MAX;
+  else if(diff <= (LONG_MIN/1000))
+    return LONG_MIN;
+  return (long)(newer.tv_sec-older.tv_sec)*1000+
+    (long)(newer.tv_usec-older.tv_usec)/1000;
+}
diff --git a/tests/server/util.h b/tests/server/util.h
index a2a56badd..7b4ec1626 100644
--- a/tests/server/util.h
+++ b/tests/server/util.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <address@hidden>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -25,6 +25,7 @@
 
 char *data_to_hex(char *data, size_t len);
 void logmsg(const char *msg, ...);
+long timediff(struct timeval newer, struct timeval older);
 
 #define TEST_DATA_PATH "%s/data/test%ld"
 
diff --git a/tests/unit/unit1323.c b/tests/unit/unit1323.c
index 7bb4cca40..1adb27494 100644
--- a/tests/unit/unit1323.c
+++ b/tests/unit/unit1323.c
@@ -50,7 +50,7 @@ UNITTEST_START
   size_t i;
 
   for(i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) {
-    time_t result = curlx_tvdiff(tests[i].first, tests[i].second);
+    timediff_t result = Curl_timediff(tests[i].first, tests[i].second);
     if(result != tests[i].result) {
       printf("%d.%06u to %d.%06u got %d, but expected %d\n",
              tests[i].first.tv_sec,

-- 
To stop receiving notification emails like this one, please contact
address@hidden



reply via email to

[Prev in Thread] Current Thread [Next in Thread]