Use monotonic time source if available.
authorYang Tse <yangsita@gmail.com>
Fri, 9 May 2008 16:30:24 +0000 (16:30 +0000)
committerYang Tse <yangsita@gmail.com>
Fri, 9 May 2008 16:30:24 +0000 (16:30 +0000)
CHANGES
Makefile.inc
Makefile.vc6
RELEASE-NOTES
ares__timeval.c [new file with mode: 0644]
ares_private.h
configure.ac
nameser.h
vc/areslib/areslib.dsp
windows_port.c

diff --git a/CHANGES b/CHANGES
index 0acc94c..3d44b19 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,5 +1,9 @@
   Changelog for the c-ares project
 
+* May 9 2008 (Yang Tse)
+
+- Use monotonic time source if available, for private function ares__tvnow()
+
 * May 7 2008 (Daniel Stenberg)
 
 - Sebastian made c-ares able to return all PTR-records when doing reverse
index 58a27bb..c524802 100644 (file)
@@ -6,7 +6,7 @@ ares_timeout.c ares_destroy.c ares_mkquery.c ares_version.c             \
 ares_expand_name.c ares_parse_a_reply.c windows_port.c                 \
 ares_expand_string.c ares_parse_ptr_reply.c ares_parse_aaaa_reply.c    \
 ares_getnameinfo.c inet_net_pton.c bitncmp.c inet_ntop.c               \
-ares_parse_ns_reply.c ares_llist.c
+ares_parse_ns_reply.c ares_llist.c ares__timeval.c
 
 HHEADERS = ares.h ares_private.h setup.h ares_dns.h ares_version.h          \
            nameser.h inet_net_pton.h inet_ntop.h ares_ipv6.h bitncmp.h      \
index 8bc8efb..cfa3fad 100644 (file)
@@ -62,6 +62,7 @@ OBJECTS = $(OBJ_DIR)\ares_fds.obj              \
           $(OBJ_DIR)\ares_init.obj             \
           $(OBJ_DIR)\ares_llist.obj            \
           $(OBJ_DIR)\ares_timeout.obj          \
+          $(OBJ_DIR)\ares__timeval.obj         \
           $(OBJ_DIR)\ares_destroy.obj          \
           $(OBJ_DIR)\ares_mkquery.obj          \
           $(OBJ_DIR)\ares_version.obj          \
@@ -122,7 +123,6 @@ $(DEF_FILE): $(OBJECTS) Makefile.VC6
        @echo   ares_inet_pton         >> $@
        @echo   ares_writev            >> $@
        @echo   ares_getnameinfo       >> $@
-       @echo   ares_gettimeofday      >> $@
        @echo   ares_parse_aaaa_reply  >> $@
 
 ahost.exe: $(OBJ_DIR) $(OBJ_DIR)\ahost.obj $(OBJ_DIR)\ares_getopt.obj cares_imp.lib
@@ -193,6 +193,9 @@ $(OBJ_DIR)\ares_init.obj: ares_init.c setup.h setup_once.h nameser.h ares.h    \
 $(OBJ_DIR)\ares_timeout.obj: ares_timeout.c setup.h setup_once.h ares.h        \
   ares_private.h ares_ipv6.h
 
+$(OBJ_DIR)\ares__timeval.obj: ares__timeval.c setup.h setup_once.h ares.h      \
+  ares_private.h ares_ipv6.h
+
 $(OBJ_DIR)\ares_destroy.obj: ares_destroy.c setup.h setup_once.h ares.h        \
   ares_private.h ares_ipv6.h
 
index 5387ae9..2d67041 100644 (file)
@@ -1,6 +1,7 @@
 This is what's new and changed in the c-ares 1.5.2 release:
 
  o improved parsing of resolver configuration files
+ o use monotonic time source if available
 
 Thanks go to these friendly people for their efforts and contributions:
 
diff --git a/ares__timeval.c b/ares__timeval.c
new file mode 100644 (file)
index 0000000..0d8bbfa
--- /dev/null
@@ -0,0 +1,95 @@
+/* $Id$ */
+
+/* Copyright (C) 2008 by Daniel Stenberg et al
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose and without fee is hereby granted, provided
+ * that the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of M.I.T. not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  M.I.T. makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ */
+
+#include "setup.h"
+#include "ares.h"
+#include "ares_private.h"
+
+#if defined(WIN32) && !defined(MSDOS)
+
+struct timeval ares__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.
+  */
+  struct timeval now;
+  DWORD milliseconds = GetTickCount();
+  now.tv_sec = milliseconds / 1000;
+  now.tv_usec = (milliseconds % 1000) * 1000;
+  return now;
+}
+
+#elif defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC)
+
+struct timeval ares__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;
+  (void)clock_gettime(CLOCK_MONOTONIC, &tsnow)
+  now.tv_sec = tsnow.tv_sec;
+  now.tv_usec = tsnow.tv_nsec / 1000;
+  return now;
+}
+
+#elif defined(HAVE_GETTIMEOFDAY)
+
+struct timeval ares__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
+
+struct timeval ares__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
+
+/*
+ * Make sure that the first argument is the more recent time, as otherwise
+ * we'll get a weird negative time-diff back...
+ *
+ * Returns: the time difference in number of milliseconds.
+ */
+long ares__tvdiff(struct timeval newer, struct timeval older)
+{
+  return (newer.tv_sec-older.tv_sec)*1000+
+    (newer.tv_usec-older.tv_usec)/1000;
+}
+
index d5ffbb3..9354e63 100644 (file)
@@ -266,6 +266,8 @@ int ares__get_hostent(FILE *fp, int family, struct hostent **host);
 int ares__read_line(FILE *fp, char **buf, int *bufsize);
 void ares__free_query(struct query *query);
 short ares__generate_new_id(rc4_key* key);
+struct timeval ares__tvnow(void);
+long ares__tvdiff(struct timeval t1, struct timeval t2);
 
 #define ARES_SWAP_BYTE(a,b) \
   { unsigned char swapByte = *(a);  *(a) = *(b);  *(b) = swapByte; }
index 4315f5c..a7af5a1 100644 (file)
@@ -384,6 +384,7 @@ AC_CHECK_HEADERS(
        errno.h \
        strings.h \
        stdbool.h \
+       time.h \
        arpa/nameser.h \
        arpa/nameser_compat.h \
        arpa/inet.h,
@@ -643,6 +644,7 @@ AC_CHECK_MEMBER(struct addrinfo.ai_flags,
 
 AC_CHECK_FUNCS( bitncmp \
                 gettimeofday \
+                clock_gettime \
                 if_indextoname,
 dnl if found
 [],
index 1549414..dc8c86e 100644 (file)
--- a/nameser.h
+++ b/nameser.h
@@ -29,13 +29,6 @@ struct iovec
 int ares_writev (SOCKET s, const struct iovec *vector, size_t count);
 #define writev(s,vect,count)  ares_writev(s,vect,count)
 
-#ifndef HAVE_GETTIMEOFDAY
-struct timezone { int dummy; };
-#endif
-
-int ares_gettimeofday(struct timeval *tv, struct timezone *tz);
-#define gettimeofday(tv,tz) ares_gettimeofday(tv,tz)
-
 #endif  /* !NETWARE */
 
 #define NS_CMPRSFLGS  0xc0
index 940dce0..71d64f8 100644 (file)
@@ -97,6 +97,10 @@ SOURCE=..\..\ares__read_line.c
 # End Source File\r
 # Begin Source File\r
 \r
+SOURCE=..\..\ares__timeval.c\r
+# End Source File\r
+# Begin Source File\r
+\r
 SOURCE=..\..\ares_cancel.c\r
 # End Source File\r
 # Begin Source File\r
index 02bb4cb..7ea6579 100644 (file)
@@ -55,37 +55,6 @@ ares_strcasecmp(const char *a, const char *b)
 }
 #endif
 
-/*
- * Number of micro-seconds between the beginning of the Windows epoch
- * (Jan. 1, 1601) and the Unix epoch (Jan. 1, 1970).
- */
-#if defined(_MSC_VER) || defined(__WATCOMC__)
-#define EPOCH_FILETIME 11644473600000000Ui64
-#else
-#define EPOCH_FILETIME 11644473600000000ULL
-#endif
-
-int
-ares_gettimeofday(struct timeval *tv, struct timezone *tz)
-{
-    FILETIME        ft;
-    LARGE_INTEGER   li;
-    __int64         t;
-
-    if (tv)
-    {
-        GetSystemTimeAsFileTime(&ft);
-        li.LowPart  = ft.dwLowDateTime;
-        li.HighPart = ft.dwHighDateTime;
-        t  = li.QuadPart / 10;   /* In micro-second intervals */
-        t -= EPOCH_FILETIME;     /* Offset to the Epoch time */
-        tv->tv_sec  = (long)(t / 1000000);
-        tv->tv_usec = (long)(t % 1000000);
-    }
-    (void) tz;
-    return 0;
-}
-
 int
 ares_writev (ares_socket_t s, const struct iovec *vector, size_t count)
 {