Upgrade libuv to ce5eb6d
authorBen Noordhuis <info@bnoordhuis.nl>
Wed, 20 Jul 2011 16:06:16 +0000 (18:06 +0200)
committerBen Noordhuis <info@bnoordhuis.nl>
Wed, 20 Jul 2011 16:06:16 +0000 (18:06 +0200)
13 files changed:
deps/uv/config-mingw.mk
deps/uv/config-unix.mk
deps/uv/src/uv-common.c
deps/uv/src/uv-unix.c
deps/uv/src/win/core.c
deps/uv/src/win/error.c
deps/uv/src/win/internal.h
deps/uv/src/win/pipe.c
deps/uv/src/win/timer.c
deps/uv/test/benchmark-sizes.c
deps/uv/test/test-bind-error.c
deps/uv/test/test-getsockname.c
deps/uv/test/test-hrtime.c

index 8081fce..abd244e 100644 (file)
@@ -59,7 +59,9 @@ src/uv-eio.o: src/uv-eio.c
 clean-platform:
        -rm -f src/ares/*.o
        -rm -f src/eio/*.o
+       -rm -f src/win/*.o
 
 distclean-platform:
        -rm -f src/ares/*.o
        -rm -f src/eio/*.o
+       -rm -f src/win/*.o
index 2b44dd6..1352682 100644 (file)
@@ -65,6 +65,8 @@ endif
 ifneq (,$(findstring CYGWIN,$(uname_S)))
 EV_CONFIG=config_cygwin.h
 EIO_CONFIG=config_cygwin.h
+# We drop the --std=c89, it hides CLOCK_MONOTONIC on cygwin
+CSTDFLAG = -D_GNU_SOURCE
 CPPFLAGS += -Isrc/ares/config_cygwin
 LINKFLAGS+=
 UV_OS_FILE=uv-cygwin.c
index d202128..b0c8a82 100644 (file)
@@ -114,13 +114,13 @@ struct sockaddr_in6 uv_ip6_addr(const char* ip, int port) {
 
 
 int uv_ip4_name(struct sockaddr_in* src, char* dst, size_t size) {
-  char* d = ares_inet_ntop(AF_INET, &src->sin_addr, dst, size);
+  const char* d = ares_inet_ntop(AF_INET, &src->sin_addr, dst, size);
   return d != dst;
 }
 
 
 int uv_ip6_name(struct sockaddr_in6* src, char* dst, size_t size) {
-  char* d = ares_inet_ntop(AF_INET6, &src->sin6_addr, dst, size);
+  const char* d = ares_inet_ntop(AF_INET6, &src->sin6_addr, dst, size);
   return d != dst;
 }
 
index 2ee2f86..842fe32 100644 (file)
  * IN THE SOFTWARE.
  */
 
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE /* O_CLOEXEC, accept4(), etc. */
+#endif
+
 #include "uv.h"
 #include "uv-common.h"
 #include "uv-eio.h"
 
-#define _GNU_SOURCE /* O_CLOEXEC */
-
 #include <stddef.h> /* NULL */
 #include <stdio.h> /* printf */
 #include <stdlib.h>
@@ -494,7 +496,7 @@ int uv_tcp_listen(uv_tcp_t* tcp, int backlog, uv_connection_cb cb) {
       return -1;
     }
 
-    if (uv__stream_open(tcp, fd)) {
+    if (uv__stream_open((uv_stream_t*)tcp, fd)) {
       close(fd);
       return -1;
     }
@@ -1751,7 +1753,7 @@ int uv_getaddrinfo(uv_getaddrinfo_t* handle,
 
 
 int uv_pipe_init(uv_pipe_t* handle) {
-  memset(handle, 0, sizeof handle);
+  memset(handle, 0, sizeof *handle);
 
   uv__handle_init((uv_handle_t*)handle, UV_NAMED_PIPE);
   uv_counters()->pipe_init++;
index 3200947..e2d5a32 100644 (file)
@@ -70,9 +70,6 @@ void uv_init() {
   /* Initialize winsock */
   uv_winsock_startup();
 
-  /* Initialize timers */
-  uv_timer_startup();
-
   /* Intialize event loop */
   uv_loop_init();
 }
index d7cf986..d44be2b 100644 (file)
@@ -107,6 +107,7 @@ uv_err_code uv_translate_sys_error(int sys_errno) {
     case ERROR_TOO_MANY_OPEN_FILES:         return UV_EMFILE;
     case WSAEMFILE:                         return UV_EMFILE;
     case ERROR_OUTOFMEMORY:                 return UV_ENOMEM;
+    case ERROR_NOT_SUPPORTED:               return UV_ENOTSUP;
     case ERROR_INSUFFICIENT_BUFFER:         return UV_EINVAL;
     case ERROR_INVALID_FLAGS:               return UV_EBADF;
     case ERROR_INVALID_PARAMETER:           return UV_EINVAL;
index 7c42a77..33783f6 100644 (file)
 /*
  * Timers
  */
-
 RB_HEAD(uv_timer_tree_s, uv_timer_s);
 
-void uv_timer_startup();
-
 void uv_timer_endgame(uv_timer_t* handle);
 
 DWORD uv_get_poll_timeout();
index f253d82..563c431 100644 (file)
@@ -107,7 +107,7 @@ int uv_pipe_bind(uv_pipe_t* handle, const char* name) {
   }
 
   /* Make our own copy of the pipe name */
-  handle->name = strdup(name);
+  handle->name = _strdup(name);
   if (!handle->name) {
     uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
   }
@@ -198,7 +198,7 @@ int uv_pipe_connect(uv_connect_t* req, uv_pipe_t* handle,
   if (pipeHandle == INVALID_HANDLE_VALUE) {
     if (GetLastError() == ERROR_PIPE_BUSY) {
       /* Wait for the server to make a pipe instance available. */
-      handle->name = strdup(name);
+      handle->name = _strdup(name);
       if (!handle->name) {
         uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
       }
index 6f74a2c..ea5e719 100644 (file)
 #include "internal.h"
 #include "tree.h"
 
+#undef NANOSEC
+#define NANOSEC 1000000000
+
 
 /* The resolution of the high-resolution clock. */
 static int64_t uv_ticks_per_msec_ = 0;
-
+static uint64_t uv_hrtime_frequency_ = 0;
+static char uv_hrtime_initialized_ = 0;
 
 
 void uv_update_time() {
-  LARGE_INTEGER counter;
+  DWORD ticks = GetTickCount();
 
-  if (!QueryPerformanceCounter(&counter))
-    uv_fatal_error(GetLastError(), "QueryPerformanceCounter");
+  /* The assumption is made that LARGE_INTEGER.QuadPart has the same type */
+  /* LOOP->time, which happens to be. Is there any way to assert this? */
+  LARGE_INTEGER* time = (LARGE_INTEGER*) &LOOP->time;
 
-  LOOP->time = counter.QuadPart / uv_ticks_per_msec_;
+  /* If the timer has wrapped, add 1 to it's high-order dword. */
+  /* uv_poll must make sure that the timer can never overflow more than */
+  /* once between two subsequent uv_update_time calls. */
+  if (ticks < time->LowPart) {
+    time->HighPart += 1;
+  }
+  time->LowPart = ticks;
 }
 
 
@@ -48,18 +59,39 @@ int64_t uv_now() {
 
 
 uint64_t uv_hrtime(void) {
-  assert(0 && "implement me");
-  return 0;
-}
+  LARGE_INTEGER counter;
 
+  /* When called for the first time, obtain the high-resolution clock */
+  /* frequency. */
+  if (!uv_hrtime_initialized_) {
+    uv_hrtime_initialized_ = 1;
 
-void uv_timer_startup() {
-  LARGE_INTEGER timer_frequency;
+    if (!QueryPerformanceFrequency(&counter)) {
+      uv_hrtime_frequency_ = 0;
+      uv_set_sys_error(GetLastError());
+      return 0;
+    }
+
+    uv_hrtime_frequency_ = counter.QuadPart;
+  }
+
+  /* If the performance frequency is zero, there's no support. */
+  if (!uv_hrtime_frequency_) {
+    uv_set_sys_error(ERROR_NOT_SUPPORTED);
+    return 0;
+  }
+
+  if (!QueryPerformanceCounter(&counter)) {
+    uv_set_sys_error(GetLastError());
+    return 0;
+  }
 
-  /* Initialize the event loop time */
-  if (!QueryPerformanceFrequency(&timer_frequency))
-    uv_fatal_error(GetLastError(), "QueryPerformanceFrequency");
-  uv_ticks_per_msec_ = timer_frequency.QuadPart / 1000;
+  /* Because we have no guarantee about the order of magniture of the */
+  /* performance counter frequency, and there may not be much headroom to */
+  /* multiply by NANOSEC without overflowing, we use 128-bit math instead. */
+  return ((uint64_t) counter.LowPart * NANOSEC / uv_hrtime_frequency_) +
+         (((uint64_t) counter.HighPart * NANOSEC / uv_hrtime_frequency_)
+         << 32);
 }
 
 
@@ -187,10 +219,15 @@ DWORD uv_get_poll_timeout() {
     uv_update_time();
 
     delta = timer->due - LOOP->time;
-    if (delta >= UINT_MAX) {
-      /* Can't have a timeout greater than UINT_MAX, and a timeout value of */
-      /* UINT_MAX means infinite, so that's no good either. */
-      return UINT_MAX - 1;
+    if (delta >= UINT_MAX >> 1) {
+      /* A timeout value of UINT_MAX means infinite, so that's no good. But */
+      /* more importantly, there's always the risk that GetTickCount wraps. */
+      /* uv_update_time can detect this, but we must make sure that the */
+      /* tick counter never overflows twice between two subsequent */
+      /* uv_update_time calls. We do this by never sleeping more than half */
+      /* the time it takes to wrap  the counter - which is huge overkill, */
+      /* but hey, it's not so bad to wake up every 25 days. */
+      return UINT_MAX >> 1;
     } else if (delta < 0) {
       /* Negative timeout values are not allowed */
       return 0;
index 9038645..ab60e96 100644 (file)
@@ -24,7 +24,9 @@
 
 
 BENCHMARK_IMPL(sizes) {
-  LOGF("uv_req_t: %u bytes\n", (unsigned int) sizeof(uv_req_t));
+  LOGF("uv_shutdown_t: %u bytes\n", (unsigned int) sizeof(uv_shutdown_t));
+  LOGF("uv_write_t: %u bytes\n", (unsigned int) sizeof(uv_write_t));
+  LOGF("uv_connect_t: %u bytes\n", (unsigned int) sizeof(uv_connect_t));
   LOGF("uv_tcp_t: %u bytes\n", (unsigned int) sizeof(uv_tcp_t));
   LOGF("uv_pipe_t: %u bytes\n", (unsigned int) sizeof(uv_pipe_t));
   LOGF("uv_prepare_t: %u bytes\n", (unsigned int) sizeof(uv_prepare_t));
index f3db848..834f4ff 100644 (file)
@@ -199,4 +199,6 @@ TEST_IMPL(listen_without_bind) {
   ASSERT(r == 0);
   r = uv_tcp_listen(&server, 128, NULL);
   ASSERT(r == 0);
+
+  return 0;
 }
index eeae468..6e4f643 100644 (file)
@@ -126,6 +126,7 @@ static int tcp_listener(int port) {
   struct sockaddr_in addr = uv_ip4_addr("0.0.0.0", port);
   struct sockaddr sockname;
   int namelen = sizeof(sockname);
+  char ip[20];
   int r;
 
   r = uv_tcp_init(&tcpServer);
@@ -152,7 +153,6 @@ static int tcp_listener(int port) {
   }
   ASSERT(r == 0);
 
-  char ip[20];
   r = uv_ip4_name((struct sockaddr_in*)&sockname, ip, 20);
   ASSERT(r == 0);
   ASSERT(ip[0] == '0');
index e1959b0..566e0d2 100644 (file)
@@ -22,9 +22,8 @@
 #include "uv.h"
 #include "task.h"
 
-
-#ifndef MICROSEC
-# define MICROSEC 1000000
+#ifndef MILLISEC
+# define MILLISEC 1000
 #endif
 
 #ifndef NANOSEC
 #endif
 
 
-
-/*
- * We expect the amount of time passed to be at least one us plus two system
- * calls. Therefore checking that at least a microsecond has elapsed is safe.
- */
 TEST_IMPL(hrtime) {
   uint64_t a, b, diff;
 
@@ -46,9 +40,12 @@ TEST_IMPL(hrtime) {
 
   diff = b - a;
 
-  printf("diff = %llu\n", (unsigned long long int)diff);
+  printf("diff = %llu\n", (unsigned long long int) diff);
 
-  ASSERT(diff >= NANOSEC / MICROSEC);
-  ASSERT(diff > MICROSEC);
+  /* The windows Sleep() function has only a resolution of 10-20 ms. */
+  /* Check that the difference between the two hrtime values is somewhat in */
+  /* the range we expect it to be. */
+  ASSERT(diff > (uint64_t) 80 * NANOSEC / MILLISEC);
+  ASSERT(diff < (uint64_t) 120 * NANOSEC / MILLISEC);
   return 0;
 }