zookeeper-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From mic...@apache.org
Subject svn commit: r1672934 - in /zookeeper/trunk: CHANGES.txt src/c/Makefile.am src/c/configure.ac src/c/src/zookeeper.c src/c/tests/LibCMocks.cc src/c/tests/LibCSymTable.cc src/c/tests/LibCSymTable.h
Date Sat, 11 Apr 2015 21:40:22 GMT
Author: michim
Date: Sat Apr 11 21:40:22 2015
New Revision: 1672934

URL: http://svn.apache.org/r1672934
Log:
ZOOKEEPER-1626 Zookeeper C client should be tolerant of clock adjustments (Colin Patrick McCabe
via michim)

Modified:
    zookeeper/trunk/CHANGES.txt
    zookeeper/trunk/src/c/Makefile.am
    zookeeper/trunk/src/c/configure.ac
    zookeeper/trunk/src/c/src/zookeeper.c
    zookeeper/trunk/src/c/tests/LibCMocks.cc
    zookeeper/trunk/src/c/tests/LibCSymTable.cc
    zookeeper/trunk/src/c/tests/LibCSymTable.h

Modified: zookeeper/trunk/CHANGES.txt
URL: http://svn.apache.org/viewvc/zookeeper/trunk/CHANGES.txt?rev=1672934&r1=1672933&r2=1672934&view=diff
==============================================================================
--- zookeeper/trunk/CHANGES.txt (original)
+++ zookeeper/trunk/CHANGES.txt Sat Apr 11 21:40:22 2015
@@ -76,6 +76,9 @@ BUGFIXES:
   ZOOKEEPER-2029 Leader.LearnerCnxAcceptor should handle exceptions in run()
   (Rakesh R, Asad Saeed via hdeng)
 
+  ZOOKEEPER-1626 Zookeeper C client should be tolerant of clock adjustments
+  (Colin Patrick McCabe via michim)
+
 IMPROVEMENTS:
   ZOOKEEPER-1660 Documentation for Dynamic Reconfiguration (Reed Wanderman-Milne via shralex)
 
 

Modified: zookeeper/trunk/src/c/Makefile.am
URL: http://svn.apache.org/viewvc/zookeeper/trunk/src/c/Makefile.am?rev=1672934&r1=1672933&r2=1672934&view=diff
==============================================================================
--- zookeeper/trunk/src/c/Makefile.am (original)
+++ zookeeper/trunk/src/c/Makefile.am Sat Apr 11 21:40:22 2015
@@ -27,7 +27,7 @@ COMMON_SRC = src/zookeeper.c include/zoo
 EXPORT_SYMBOLS = '(zoo_|zookeeper_|zhandle|Z|format_log_message|log_message|logLevel|deallocate_|allocate_|zerror|is_unrecoverable)'
 noinst_LTLIBRARIES += libzkst.la
 libzkst_la_SOURCES =$(COMMON_SRC) src/st_adaptor.c
-libzkst_la_LIBADD = -lm
+libzkst_la_LIBADD = -lm $(CLOCK_GETTIME_LIBS)
 
 lib_LTLIBRARIES = libzookeeper_st.la
 libzookeeper_st_la_SOURCES =
@@ -39,7 +39,7 @@ if WANT_SYNCAPI
 noinst_LTLIBRARIES += libzkmt.la
 libzkmt_la_SOURCES =$(COMMON_SRC) src/mt_adaptor.c
 libzkmt_la_CFLAGS = -DTHREADED
-libzkmt_la_LIBADD = -lm
+libzkmt_la_LIBADD = -lm $(CLOCK_GETTIME_LIBS)
 
 lib_LTLIBRARIES += libzookeeper_mt.la
 libzookeeper_mt_la_SOURCES =

Modified: zookeeper/trunk/src/c/configure.ac
URL: http://svn.apache.org/viewvc/zookeeper/trunk/src/c/configure.ac?rev=1672934&r1=1672933&r2=1672934&view=diff
==============================================================================
--- zookeeper/trunk/src/c/configure.ac (original)
+++ zookeeper/trunk/src/c/configure.ac Sat Apr 11 21:40:22 2015
@@ -142,6 +142,14 @@ if test x"$ipv6" = xyes; then
   AC_SUBST(USEIPV6)
 fi
 
+# Determine which libraries we need to use clock_gettime
+saved_LIBS="$LIBS"
+LIBS=""
+AC_CHECK_LIB(rt, clock_gettime)
+CLOCK_GETTIME_LIBS=$LIBS
+AC_SUBST(CLOCK_GETTIME_LIBS)
+LIBS="$saved_LIBS"
+
 # Checks for library functions.
 AC_CHECK_FUNCS([getcwd gethostbyname gethostname getlogin getpwuid_r gettimeofday getuid
memmove memset poll socket strchr strdup strerror strtol])
 

Modified: zookeeper/trunk/src/c/src/zookeeper.c
URL: http://svn.apache.org/viewvc/zookeeper/trunk/src/c/src/zookeeper.c?rev=1672934&r1=1672933&r2=1672934&view=diff
==============================================================================
--- zookeeper/trunk/src/c/src/zookeeper.c (original)
+++ zookeeper/trunk/src/c/src/zookeeper.c Sat Apr 11 21:40:22 2015
@@ -40,6 +40,7 @@
 #include <assert.h>
 #include <stdarg.h>
 #include <limits.h>
+#include <unistd.h> // needed for _POSIX_MONOTONIC_CLOCK
 
 #ifndef _WIN32
 #include <sys/time.h>
@@ -252,6 +253,43 @@ static sendsize_t zookeeper_send(socket_
     return send(s, buf, len, SEND_FLAGS);
 }
 
+/**
+ * Get the system time.
+ *
+ * If the monotonic clock is available, we use that.  The monotonic clock does
+ * not change when the wall-clock time is adjusted by NTP or the system
+ * administrator.  The monotonic clock returns a value which is monotonically
+ * increasing.
+ *
+ * If POSIX monotonic clocks are not available, we fall back on the wall-clock.
+ *
+ * @param tv         (out param) The time.
+ */
+void get_system_time(struct timeval *tv)
+{
+  int ret;
+
+#ifdef CLOCK_MONOTONIC_RAW
+  // On Linux, CLOCK_MONOTONIC is affected by ntp slew but CLOCK_MONOTONIC_RAW
+  // is not.  We want the non-slewed (constant rate) CLOCK_MONOTONIC_RAW if it
+  // is available.
+  struct timespec ts = { 0 };
+  ret = clock_gettime(CLOCK_MONOTONIC_RAW, &ts);
+  tv->tv_sec = ts.tv_sec;
+  tv->tv_usec = ts.tv_nsec / 1000;
+#elif _POSIX_MONOTONIC_CLOCK
+  struct timespec ts = { 0 };
+  ret = clock_gettime(CLOCK_MONOTONIC, &ts);
+  tv->tv_sec = ts.tv_sec;
+  tv->tv_usec = ts.tv_nsec / 1000;
+#else
+  ret = gettimeofday(tv, NULL);
+#endif
+  if (ret) {
+    abort();
+  }
+}
+
 const void *zoo_get_context(zhandle_t *zh)
 {
     return zh->context;
@@ -1931,7 +1969,7 @@ static struct timeval get_timeval(int in
 
     rc = serialize_RequestHeader(oa, "header", &h);
     enter_critical(zh);
-    gettimeofday(&zh->last_ping, 0);
+    get_system_time(&zh->last_ping);
     rc = rc < 0 ? rc : add_void_completion(zh, h.xid, 0, 0);
     rc = rc < 0 ? rc : queue_buffer_bytes(&zh->to_send, get_buffer(oa),
             get_buffer_len(oa));
@@ -2069,7 +2107,7 @@ int zookeeper_interest(zhandle_t *zh, so
         return ZBADARGUMENTS;
     if (is_unrecoverable(zh))
         return ZINVALIDSTATE;
-    gettimeofday(&now, 0);
+    get_system_time(&now);
     if(zh->next_deadline.tv_sec!=0 || zh->next_deadline.tv_usec!=0){
         int time_left = calculate_interval(&zh->next_deadline, &now);
         int max_exceed = zh->recv_timeout / 10 > 200 ? 200 :
@@ -2279,7 +2317,7 @@ static int check_events(zhandle_t *zh, i
                 "failed while receiving a server response");
         }
         if (rc > 0) {
-            gettimeofday(&zh->last_recv, 0);
+            get_system_time(&zh->last_recv);
             if (zh->input_buffer != &zh->primer_buffer) {
                 queue_buffer(&zh->to_process, zh->input_buffer, 0);
             } else  {
@@ -2733,7 +2771,7 @@ static void isSocketReadable(zhandle_t*
     }
 #endif
     else{
-        gettimeofday(&zh->socket_readable,0);
+        get_system_time(&zh->socket_readable);
     }
 }
 
@@ -2745,7 +2783,7 @@ static void checkResponseLatency(zhandle
     if(zh->socket_readable.tv_sec==0)
         return;
 
-    gettimeofday(&now,0);
+    get_system_time(&now);
     delay=calculate_interval(&zh->socket_readable, &now);
     if(delay>20)
         LOG_DEBUG(LOGCALLBACK(zh), "The following server response has spent at least %dms
sitting in the client socket recv buffer",delay);
@@ -2851,7 +2889,7 @@ int zookeeper_process(zhandle_t *zh, int
                 if(hdr.xid == PING_XID){
                     int elapsed = 0;
                     struct timeval now;
-                    gettimeofday(&now, 0);
+                    get_system_time(&now);
                     elapsed = calculate_interval(&zh->last_ping, &now);
                     LOG_DEBUG(LOGCALLBACK(zh), "Got ping response in %d ms", elapsed);
 
@@ -4071,7 +4109,7 @@ int flush_send_queue(zhandle_t*zh, int t
     fd_set pollSet;
     struct timeval wait;
 #endif
-    gettimeofday(&started,0);
+    get_system_time(&started);
     // we can't use dequeue_buffer() here because if (non-blocking) send_buffer()
     // returns EWOULDBLOCK we'd have to put the buffer back on the queue.
     // we use a recursive lock instead and only dequeue the buffer if a send was
@@ -4084,7 +4122,7 @@ int flush_send_queue(zhandle_t*zh, int t
 #endif
             int elapsed;
             struct timeval now;
-            gettimeofday(&now,0);
+            get_system_time(&now);
             elapsed=calculate_interval(&started,&now);
             if (elapsed>timeout) {
                 rc = ZOPERATIONTIMEOUT;
@@ -4123,7 +4161,7 @@ int flush_send_queue(zhandle_t*zh, int t
         // if the buffer has been sent successfully, remove it from the queue
         if (rc > 0)
             remove_buffer(&zh->to_send);
-        gettimeofday(&zh->last_send, 0);
+        get_system_time(&zh->last_send);
         rc = ZOK;
     }
     unlock_buffer_list(&zh->to_send);

Modified: zookeeper/trunk/src/c/tests/LibCMocks.cc
URL: http://svn.apache.org/viewvc/zookeeper/trunk/src/c/tests/LibCMocks.cc?rev=1672934&r1=1672933&r2=1672934&view=diff
==============================================================================
--- zookeeper/trunk/src/c/tests/LibCMocks.cc (original)
+++ zookeeper/trunk/src/c/tests/LibCMocks.cc Sat Apr 11 21:40:22 2015
@@ -19,6 +19,7 @@
 #include <cstdlib>
 #include <cstdarg>
 #include <iostream>
+#include <unistd.h> // needed for _POSIX_MONOTONIC_CLOCK
 #include <stdarg.h>
 
 #include "Util.h"
@@ -331,3 +332,16 @@ int gettimeofday(struct timeval *tp, GET
 
 Mock_gettimeofday* Mock_gettimeofday::mock_=0;
 
+// *****************************************************************************
+#ifdef _POSIX_MONOTONIC_CLOCK
+// clock_gettime
+int clock_gettime(clockid_t id, struct timespec *tp) {
+    if (!Mock_gettimeofday::mock_)
+        return LIBC_SYMBOLS.clock_gettime(id,tp);
+    struct timeval tv = { 0 };
+    int res = Mock_gettimeofday::mock_->call(&tv, NULL);
+    tp->tv_sec = tv.tv_sec;
+    tp->tv_nsec = tv.tv_usec * 1000;
+    return res;
+}
+#endif

Modified: zookeeper/trunk/src/c/tests/LibCSymTable.cc
URL: http://svn.apache.org/viewvc/zookeeper/trunk/src/c/tests/LibCSymTable.cc?rev=1672934&r1=1672933&r2=1672934&view=diff
==============================================================================
--- zookeeper/trunk/src/c/tests/LibCSymTable.cc (original)
+++ zookeeper/trunk/src/c/tests/LibCSymTable.cc Sat Apr 11 21:40:22 2015
@@ -17,6 +17,7 @@
  */
 
 #include "LibCSymTable.h" 
+#include <unistd.h> // needed for _POSIX_MONOTONIC_CLOCK
 
 #define LOAD_SYM(sym) \
     sym=(sym##_sig)dlsym(handle,#sym); \
@@ -51,6 +52,9 @@ LibCSymTable::LibCSymTable()
     LOAD_SYM(select);
     LOAD_SYM(poll);
     LOAD_SYM(gettimeofday);
+#ifdef _POSIX_MONOTONIC_CLOCK
+    LOAD_SYM(clock_gettime);
+#endif
 #ifdef THREADED
     LOAD_SYM(pthread_create);
     LOAD_SYM(pthread_detach);

Modified: zookeeper/trunk/src/c/tests/LibCSymTable.h
URL: http://svn.apache.org/viewvc/zookeeper/trunk/src/c/tests/LibCSymTable.h?rev=1672934&r1=1672933&r2=1672934&view=diff
==============================================================================
--- zookeeper/trunk/src/c/tests/LibCSymTable.h (original)
+++ zookeeper/trunk/src/c/tests/LibCSymTable.h Sat Apr 11 21:40:22 2015
@@ -26,6 +26,7 @@
 #include <dlfcn.h>
 #include <cassert>
 #include <poll.h>
+#include <unistd.h> // needed for _POSIX_MONOTONIC_CLOCK
 
 #ifdef THREADED
 #include <pthread.h>
@@ -80,6 +81,9 @@ struct LibCSymTable
     DECLARE_SYM(int,select,(int,fd_set*,fd_set*,fd_set*,struct timeval*));
     DECLARE_SYM(int,poll,(struct pollfd*,POLL_NFDS_TYPE,int));
     DECLARE_SYM(int,gettimeofday,(struct timeval*,GETTIMEOFDAY_ARG2_TYPE));
+#ifdef _POSIX_MONOTONIC_CLOCK
+    DECLARE_SYM(int,clock_gettime,(clockid_t clk_id, struct timespec*));
+#endif
 #ifdef THREADED
     DECLARE_SYM(int,pthread_create,(pthread_t *, const pthread_attr_t *,
                 void *(*)(void *), void *));



Mime
View raw message