deps: upgrade libuv to 9aab5d4
authorBen Noordhuis <info@bnoordhuis.nl>
Fri, 11 Jan 2013 12:49:45 +0000 (13:49 +0100)
committerBen Noordhuis <info@bnoordhuis.nl>
Fri, 11 Jan 2013 13:00:19 +0000 (14:00 +0100)
65 files changed:
deps/uv/Makefile
deps/uv/checksparse.sh [new file with mode: 0755]
deps/uv/config-unix.mk
deps/uv/include/uv-private/uv-sunos.h
deps/uv/include/uv.h
deps/uv/src/fs-poll.c
deps/uv/src/unix/aix.c
deps/uv/src/unix/async.c
deps/uv/src/unix/core.c
deps/uv/src/unix/cygwin.c
deps/uv/src/unix/darwin.c
deps/uv/src/unix/freebsd.c
deps/uv/src/unix/fs.c
deps/uv/src/unix/getaddrinfo.c
deps/uv/src/unix/internal.h
deps/uv/src/unix/kqueue.c
deps/uv/src/unix/linux/linux-core.c
deps/uv/src/unix/linux/syscalls.c
deps/uv/src/unix/loop-watcher.c
deps/uv/src/unix/loop.c
deps/uv/src/unix/netbsd.c
deps/uv/src/unix/openbsd.c
deps/uv/src/unix/process.c
deps/uv/src/unix/signal.c
deps/uv/src/unix/stream.c
deps/uv/src/unix/sunos.c
deps/uv/src/unix/thread.c
deps/uv/src/unix/threadpool.c
deps/uv/src/unix/tty.c
deps/uv/src/unix/udp.c
deps/uv/src/win/core.c
deps/uv/src/win/loop-watcher.c
deps/uv/src/win/tty.c
deps/uv/test/benchmark-getaddrinfo.c
deps/uv/test/benchmark-list.h
deps/uv/test/benchmark-million-async.c [new file with mode: 0644]
deps/uv/test/benchmark-ping-pongs.c
deps/uv/test/benchmark-pump.c
deps/uv/test/benchmark-spawn.c
deps/uv/test/dns-server.c
deps/uv/test/runner-unix.c
deps/uv/test/runner.c
deps/uv/test/runner.h
deps/uv/test/task.h
deps/uv/test/test-async.c
deps/uv/test/test-condvar-consumer-producer.c [deleted file]
deps/uv/test/test-connection-fail.c
deps/uv/test/test-delayed-accept.c
deps/uv/test/test-embed.c
deps/uv/test/test-fs-event.c
deps/uv/test/test-fs.c
deps/uv/test/test-getsockname.c
deps/uv/test/test-ipc.c
deps/uv/test/test-list.h
deps/uv/test/test-multiple-listen.c
deps/uv/test/test-ping-pong.c
deps/uv/test/test-poll.c
deps/uv/test/test-ref.c
deps/uv/test/test-run-nowait.c [new file with mode: 0644]
deps/uv/test/test-run-once.c
deps/uv/test/test-shutdown-eof.c
deps/uv/test/test-spawn.c
deps/uv/test/test-stdio-over-pipes.c
deps/uv/test/test-threadpool-cancel.c
deps/uv/uv.gyp

index 4012b6e..ef2b352 100644 (file)
@@ -62,7 +62,7 @@ bench: test/run-benchmarks$(E)
        $<
 
 clean: clean-platform
-       $(RM) -f src/*.o *.a test/run-tests$(E) test/run-benchmarks$(E)
+       $(RM) -f *.a *.so test/run-tests$(E) test/run-benchmarks$(E)
 
 distclean: distclean-platform
-       $(RM) -f src/*.o *.a test/run-tests$(E) test/run-benchmarks$(E)
+       $(RM) -f *.a *.so test/run-tests$(E) test/run-benchmarks$(E)
diff --git a/deps/uv/checksparse.sh b/deps/uv/checksparse.sh
new file mode 100755 (executable)
index 0000000..3a19d16
--- /dev/null
@@ -0,0 +1,230 @@
+#!/bin/sh
+
+# Copyright (c) 2013, Ben Noordhuis <info@bnoordhuis.nl>
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+SPARSE=${SPARSE:-sparse}
+
+SPARSE_FLAGS=${SPARSE_FLAGS:-"
+-D__POSIX__
+-Wsparse-all
+-Wno-do-while
+-Wno-transparent-union
+-Iinclude
+-Iinclude/uv-private
+-Isrc
+"}
+
+SOURCES="
+include/uv-private/ngx-queue.h
+include/uv-private/tree.h
+include/uv-private/uv-unix.h
+include/uv.h
+src/fs-poll.c
+src/inet.c
+src/unix/async.c
+src/unix/core.c
+src/unix/dl.c
+src/unix/error.c
+src/unix/fs.c
+src/unix/getaddrinfo.c
+src/unix/internal.h
+src/unix/loop-watcher.c
+src/unix/loop.c
+src/unix/pipe.c
+src/unix/poll.c
+src/unix/process.c
+src/unix/signal.c
+src/unix/stream.c
+src/unix/tcp.c
+src/unix/thread.c
+src/unix/threadpool.c
+src/unix/timer.c
+src/unix/tty.c
+src/unix/udp.c
+src/uv-common.c
+src/uv-common.h
+"
+
+TESTS="
+test/benchmark-async-pummel.c
+test/benchmark-async.c
+test/benchmark-fs-stat.c
+test/benchmark-getaddrinfo.c
+test/benchmark-loop-count.c
+test/benchmark-million-async.c
+test/benchmark-million-timers.c
+test/benchmark-multi-accept.c
+test/benchmark-ping-pongs.c
+test/benchmark-pound.c
+test/benchmark-pump.c
+test/benchmark-sizes.c
+test/benchmark-spawn.c
+test/benchmark-tcp-write-batch.c
+test/benchmark-thread.c
+test/benchmark-udp-pummel.c
+test/blackhole-server.c
+test/dns-server.c
+test/echo-server.c
+test/run-benchmarks.c
+test/run-tests.c
+test/runner-unix.c
+test/runner-unix.h
+test/runner.c
+test/runner.h
+test/task.h
+test/test-active.c
+test/test-async.c
+test/test-barrier.c
+test/test-callback-order.c
+test/test-callback-stack.c
+test/test-condvar.c
+test/test-connection-fail.c
+test/test-cwd-and-chdir.c
+test/test-delayed-accept.c
+test/test-dlerror.c
+test/test-embed.c
+test/test-error.c
+test/test-fail-always.c
+test/test-fs-event.c
+test/test-fs-poll.c
+test/test-fs.c
+test/test-get-currentexe.c
+test/test-get-loadavg.c
+test/test-get-memory.c
+test/test-getaddrinfo.c
+test/test-getsockname.c
+test/test-hrtime.c
+test/test-idle.c
+test/test-ipc-send-recv.c
+test/test-ipc.c
+test/test-loop-handles.c
+test/test-multiple-listen.c
+test/test-mutexes.c
+test/test-pass-always.c
+test/test-ping-pong.c
+test/test-pipe-bind-error.c
+test/test-pipe-connect-error.c
+test/test-platform-output.c
+test/test-poll-close.c
+test/test-poll.c
+test/test-process-title.c
+test/test-ref.c
+test/test-run-nowait.c
+test/test-run-once.c
+test/test-semaphore.c
+test/test-shutdown-close.c
+test/test-shutdown-eof.c
+test/test-signal-multiple-loops.c
+test/test-signal.c
+test/test-spawn.c
+test/test-stdio-over-pipes.c
+test/test-tcp-bind-error.c
+test/test-tcp-bind6-error.c
+test/test-tcp-close-while-connecting.c
+test/test-tcp-close.c
+test/test-tcp-connect-error-after-write.c
+test/test-tcp-connect-error.c
+test/test-tcp-connect-timeout.c
+test/test-tcp-connect6-error.c
+test/test-tcp-flags.c
+test/test-tcp-open.c
+test/test-tcp-read-stop.c
+test/test-tcp-shutdown-after-write.c
+test/test-tcp-unexpected-read.c
+test/test-tcp-write-error.c
+test/test-tcp-write-to-half-open-connection.c
+test/test-tcp-writealot.c
+test/test-thread.c
+test/test-threadpool-cancel.c
+test/test-threadpool.c
+test/test-timer-again.c
+test/test-timer.c
+test/test-tty.c
+test/test-udp-dgram-too-big.c
+test/test-udp-ipv6.c
+test/test-udp-multicast-join.c
+test/test-udp-multicast-ttl.c
+test/test-udp-open.c
+test/test-udp-options.c
+test/test-udp-send-and-recv.c
+test/test-util.c
+test/test-walk-handles.c
+"
+
+case `uname -s` in
+AIX)
+  SPARSE_FLAGS="$SPARSE_FLAGS -D_AIX=1"
+  SOURCES="$SOURCES
+           src/unix/aix.c"
+  ;;
+Darwin)
+  SPARSE_FLAGS="$SPARSE_FLAGS -D__APPLE__=1"
+  SOURCES="$SOURCES
+           include/uv-private/uv-bsd.h
+           src/unix/darwin.c
+           src/unix/kqueue.c
+           src/unix/fsevents.c"
+  ;;
+DragonFly)
+  SPARSE_FLAGS="$SPARSE_FLAGS -D__DragonFly__=1"
+  SOURCES="$SOURCES
+           include/uv-private/uv-bsd.h
+           src/unix/kqueue.c
+           src/unix/freebsd.c"
+  ;;
+FreeBSD)
+  SPARSE_FLAGS="$SPARSE_FLAGS -D__FreeBSD__=1"
+  SOURCES="$SOURCES
+           include/uv-private/uv-bsd.h
+           src/unix/kqueue.c
+           src/unix/freebsd.c"
+  ;;
+Linux)
+  SPARSE_FLAGS="$SPARSE_FLAGS -D__linux__=1"
+  SOURCES="$SOURCES
+           include/uv-private/uv-linux.h
+           src/unix/linux/inotify.c
+           src/unix/linux/linux-core.c
+           src/unix/linux/syscalls.c
+           src/unix/linux/syscalls.h"
+  ;;
+NetBSD)
+  SPARSE_FLAGS="$SPARSE_FLAGS -D__NetBSD__=1"
+  SOURCES="$SOURCES
+           include/uv-private/uv-bsd.h
+           src/unix/kqueue.c
+           src/unix/netbsd.c"
+  ;;
+OpenBSD)
+  SPARSE_FLAGS="$SPARSE_FLAGS -D__OpenBSD__=1"
+  SOURCES="$SOURCES
+           include/uv-private/uv-bsd.h
+           src/unix/kqueue.c
+           src/unix/openbsd.c"
+  ;;
+SunOS)
+  SPARSE_FLAGS="$SPARSE_FLAGS -D__sun=1"
+  SOURCES="$SOURCES
+           include/uv-private/uv-sunos.h
+           src/unix/sunos.c"
+  ;;
+esac
+
+for ARCH in __i386__ __x86_64__ __arm__; do
+  $SPARSE $SPARSE_FLAGS -D$ARCH=1 $SOURCES
+done
+
+# Tests are architecture independent.
+$SPARSE $SPARSE_FLAGS -Itest $TESTS
index 37828f2..66c74ee 100644 (file)
@@ -123,6 +123,13 @@ else
 RUNNER_LDFLAGS += -pthread
 endif
 
+OBJDIR := out
+ifeq ($(MAKECMDGOALS), test)
+       OBJDIR := $(OBJDIR)/test
+endif
+
+OBJS := $(addprefix $(OBJDIR)/,$(OBJS))
+
 libuv.a: $(OBJS)
        $(AR) rcs $@ $^
 
@@ -130,18 +137,18 @@ libuv.$(SOEXT):   override CFLAGS += -fPIC
 libuv.$(SOEXT):        $(OBJS)
        $(CC) -shared -o $@ $^ $(LDFLAGS)
 
-src/%.o: src/%.c include/uv.h include/uv-private/uv-unix.h
+$(OBJDIR)/src/unix/%.o: src/unix/%.c include/uv.h include/uv-private/uv-unix.h src/unix/internal.h
+       @mkdir -p $(dir $@)
        $(CC) $(CSTDFLAG) $(CPPFLAGS) $(CFLAGS) -c $< -o $@
 
-src/unix/%.o: src/unix/%.c include/uv.h include/uv-private/uv-unix.h src/unix/internal.h
+$(OBJDIR)/src/%.o: src/%.c include/uv.h include/uv-private/uv-unix.h
+       @mkdir -p $(dir $@)
        $(CC) $(CSTDFLAG) $(CPPFLAGS) $(CFLAGS) -c $< -o $@
 
 clean-platform:
-       -rm -f src/unix/*.o
-       -rm -f src/unix/linux/*.o
-       -rm -rf test/run-tests.dSYM run-benchmarks.dSYM
+       -rm -rf $(OBJDIR)
+       -rm -f libuv.a libuv.$(SOEXT) test/run-{tests,benchmarks}.dSYM
 
 distclean-platform:
-       -rm -f src/unix/*.o
-       -rm -f src/unix/linux/*.o
-       -rm -rf test/run-tests.dSYM run-benchmarks.dSYM
+       -rm -rf $(OBJDIR)
+       -rm -f libuv.a libuv.$(SOEXT) test/run-{tests,benchmarks}.dSYM
index 9d55e23..0421664 100644 (file)
 #include <sys/port.h>
 #include <port.h>
 
-#if defined(PORT_SOURCE_FILE)
-
-# define UV_PLATFORM_LOOP_FIELDS                                              \
+/* For the sake of convenience and reduced #ifdef-ery in src/unix/sunos.c,
+ * add the fs_event fields even when this version of SunOS doesn't support
+ * file watching.
+ */
+#define UV_PLATFORM_LOOP_FIELDS                                               \
   uv__io_t fs_event_watcher;                                                  \
   int fs_fd;                                                                  \
 
+#if defined(PORT_SOURCE_FILE)
+
 # define UV_PLATFORM_FS_EVENT_FIELDS                                          \
   file_obj_t fo;                                                              \
   int fd;                                                                     \
index 57ce8ae..692a21c 100644 (file)
@@ -221,6 +221,13 @@ typedef struct uv_cpu_info_s uv_cpu_info_t;
 typedef struct uv_interface_address_s uv_interface_address_t;
 
 
+typedef enum {
+  UV_RUN_DEFAULT = 0,
+  UV_RUN_ONCE,
+  UV_RUN_NOWAIT
+} uv_run_mode;
+
+
 /*
  * This function must be called before any other functions in libuv.
  *
@@ -244,12 +251,18 @@ UV_EXTERN uv_loop_t* uv_default_loop(void);
 UV_EXTERN int uv_run(uv_loop_t*);
 
 /*
- * Poll for new events once. Note that this function blocks if there are no
- * pending events. Returns zero when done (no active handles or requests left),
- * or non-zero if more events are expected (meaning you should call
- * uv_run_once() again sometime in the future).
+ * This function runs the event loop. It will act differently depending on the
+ * specified mode:
+ *  - UV_RUN_DEFAULT: Runs the event loop until the reference count drops to
+ *    zero. Always returns zero.
+ *  - UV_RUN_ONCE: Poll for new events once. Note that this function blocks if
+ *    there are no pending events. Returns zero when done (no active handles
+ *    or requests left), or non-zero if more events are expected (meaning you
+ *    should run the event loop again sometime in the future).
+ *  - UV_RUN_NOWAIT: Poll for new events once but don't block if there are no
+ *    pending events.
  */
-UV_EXTERN int uv_run_once(uv_loop_t*);
+UV_EXTERN int uv_run2(uv_loop_t*, uv_run_mode mode);
 
 /*
  * Manually modify the event loop's reference count. Useful if the user wants
@@ -265,7 +278,7 @@ UV_EXTERN int64_t uv_now(uv_loop_t*);
  * Get backend file descriptor. Only kqueue, epoll and event ports are
  * supported.
  *
- * This can be used in conjuction with uv_run_once() to poll in one thread and
+ * This can be used in conjunction with uv_run_once() to poll in one thread and
  * run the event loop's event callbacks in another.
  *
  * Useful for embedding libuv's event loop in another event loop.
@@ -1653,8 +1666,10 @@ UV_EXTERN int uv_fs_poll_stop(uv_fs_poll_t* handle);
  * ultra efficient so don't go creating a million event loops with a million
  * signal watchers.
  *
- * TODO(bnoordhuis) As of 2012-08-10 only the default event loop supports
- *                  signals. That will be fixed.
+ * Note to Linux users: SIGRT0 and SIGRT1 (signals 32 and 33) are used by the
+ * NPTL pthreads library to manage threads. Installing watchers for those
+ * signals will lead to unpredictable behavior and is strongly discouraged.
+ * Future versions of libuv may simply reject them.
  *
  * Some signal support is available on Windows:
  *
@@ -1688,11 +1703,12 @@ struct uv_signal_s {
   UV_SIGNAL_PRIVATE_FIELDS
 };
 
-/* These functions are no-ops on Windows. */
 UV_EXTERN int uv_signal_init(uv_loop_t* loop, uv_signal_t* handle);
+
 UV_EXTERN int uv_signal_start(uv_signal_t* handle,
                               uv_signal_cb signal_cb,
                               int signum);
+
 UV_EXTERN int uv_signal_stop(uv_signal_t* handle);
 
 
@@ -1782,7 +1798,7 @@ UV_EXTERN extern uint64_t uv_hrtime(void);
 /*
  * Disables inheritance for file descriptors / handles that this process
  * inherited from its parent. The effect is that child processes spawned by
- * this proces don't accidently inherit these handles.
+ * this process don't accidentally inherit these handles.
  *
  * It is recommended to call this function as early in your program as possible,
  * before the inherited file descriptors can be closed or duplicated.
@@ -1802,7 +1818,7 @@ UV_EXTERN void uv_disable_stdio_inheritance(void);
 UV_EXTERN int uv_dlopen(const char* filename, uv_lib_t* lib);
 
 /*
- * Close the shared libary.
+ * Close the shared library.
  */
 UV_EXTERN void uv_dlclose(uv_lib_t* lib);
 
index b5b344b..8d736ca 100644 (file)
@@ -190,15 +190,15 @@ static void timer_close_cb(uv_handle_t* handle) {
 
 
 static int statbuf_eq(const uv_statbuf_t* a, const uv_statbuf_t* b) {
-#ifdef _WIN32
+#if defined(_WIN32)
   return a->st_mtime == b->st_mtime
       && a->st_size == b->st_size
       && a->st_mode == b->st_mode;
 #else
 
   /* Jump through a few hoops to get sub-second granularity on Linux. */
-# if __linux__
-#  if __USE_MISC /* _BSD_SOURCE || _SVID_SOURCE */
+# if defined(__linux__)
+#  if defined(__USE_MISC) /* _BSD_SOURCE || _SVID_SOURCE */
   if (a->st_ctim.tv_nsec != b->st_ctim.tv_nsec) return 0;
   if (a->st_mtim.tv_nsec != b->st_mtim.tv_nsec) return 0;
 #  else
@@ -208,7 +208,7 @@ static int statbuf_eq(const uv_statbuf_t* a, const uv_statbuf_t* b) {
 # endif
 
   /* Jump through different hoops on OS X. */
-# if __APPLE__
+# if defined(__APPLE__)
 #  if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE)
   if (a->st_ctimespec.tv_nsec != b->st_ctimespec.tv_nsec) return 0;
   if (a->st_mtimespec.tv_nsec != b->st_mtimespec.tv_nsec) return 0;
@@ -234,7 +234,7 @@ static int statbuf_eq(const uv_statbuf_t* a, const uv_statbuf_t* b) {
 }
 
 
-#ifdef _WIN32
+#if defined(_WIN32)
 
 #include "win/internal.h"
 #include "win/handle-inl.h"
index 5637e87..5ea33bb 100644 (file)
@@ -45,7 +45,7 @@
 #include <sys/proc.h>
 #include <sys/procfs.h>
 
-uint64_t uv_hrtime() {
+uint64_t uv__hrtime(void) {
   uint64_t G = 1000000000;
   timebasestruct_t t;
   read_wall_time(&t, TIMEBASE_SZ);
index d45aa54..322167c 100644 (file)
@@ -44,13 +44,13 @@ static int uv__async_make_pending(volatile sig_atomic_t* ptr) {
    * on x86, it's about 4x faster. It probably makes zero difference in the
    * grand scheme of things but I'm OCD enough not to let this one pass.
    */
-#if __i386__ || __x86_64__
+#if defined(__i386__) || defined(__x86_64__)
   {
     unsigned int val = 1;
     __asm__ __volatile__("xchgl %0, %1" : "+r" (val) : "m" (*ptr));
     return val != 0;
   }
-#elif __GNUC__ > 4 || __GNUC__ == 4 && __GNUC_MINOR__ >= 1 /* gcc >= 4.1 */
+#elif defined(__GNUC__) && (__GNUC__ > 4 || __GNUC__ == 4 && __GNUC_MINOR__ > 0)
   return __sync_val_compare_and_swap(ptr, 0, 1) != 0;
 #else
   *ptr = 1;
index b0686ce..b4cb948 100644 (file)
@@ -66,6 +66,11 @@ static uv_loop_t default_loop_struct;
 static uv_loop_t* default_loop_ptr;
 
 
+uint64_t uv_hrtime(void) {
+  return uv__hrtime();
+}
+
+
 void uv_close(uv_handle_t* handle, uv_close_cb close_cb) {
   assert(!(handle->flags & (UV_CLOSING | UV_CLOSED)));
 
@@ -267,32 +272,42 @@ int uv_backend_timeout(const uv_loop_t* loop) {
 }
 
 
-static int uv__run(uv_loop_t* loop) {
-  uv_update_time(loop);
-  uv__run_timers(loop);
-  uv__run_idle(loop);
-  uv__run_prepare(loop);
-  uv__run_pending(loop);
-  uv__io_poll(loop, uv_backend_timeout(loop));
-  uv__run_check(loop);
-  uv__run_closing_handles(loop);
-  return uv__has_active_handles(loop) || uv__has_active_reqs(loop);
+static int uv__loop_alive(uv_loop_t* loop) {
+  return uv__has_active_handles(loop) ||
+         uv__has_active_reqs(loop) ||
+         loop->closing_handles != NULL;
 }
 
 
-int uv_run(uv_loop_t* loop) {
-  while (uv__run(loop));
-  return 0;
+int uv_run2(uv_loop_t* loop, uv_run_mode mode) {
+  int r;
+
+  if (!uv__loop_alive(loop))
+    return 0;
+
+  do {
+    uv__update_time(loop);
+    uv__run_timers(loop);
+    uv__run_idle(loop);
+    uv__run_prepare(loop);
+    uv__run_pending(loop);
+    uv__io_poll(loop, (mode & UV_RUN_NOWAIT ? 0 : uv_backend_timeout(loop)));
+    uv__run_check(loop);
+    uv__run_closing_handles(loop);
+    r = uv__loop_alive(loop);
+  } while (r && !(mode & (UV_RUN_ONCE | UV_RUN_NOWAIT)));
+
+  return r;
 }
 
 
-int uv_run_once(uv_loop_t* loop) {
-  return uv__run(loop);
+int uv_run(uv_loop_t* loop) {
+  return uv_run2(loop, UV_RUN_DEFAULT);
 }
 
 
 void uv_update_time(uv_loop_t* loop) {
-  loop->time = uv_hrtime() / 1000000;
+  uv__update_time(loop);
 }
 
 
@@ -348,7 +363,7 @@ int uv__accept(int sockfd) {
   assert(sockfd >= 0);
 
   while (1) {
-#if __linux__
+#if defined(__linux__)
     static int no_accept4;
 
     if (no_accept4)
@@ -429,6 +444,10 @@ int uv__nonblock(int fd, int set) {
   if (r == -1)
     return -1;
 
+  /* Bail out now if already set/clear. */
+  if (!!(r & O_NONBLOCK) == !!set)
+    return 0;
+
   if (set)
     flags = r | O_NONBLOCK;
   else
@@ -453,6 +472,10 @@ int uv__cloexec(int fd, int set) {
   if (r == -1)
     return -1;
 
+  /* Bail out now if already set/clear. */
+  if (!!(r & FD_CLOEXEC) == !!set)
+    return 0;
+
   if (set)
     flags = r | FD_CLOEXEC;
   else
@@ -486,24 +509,6 @@ int uv__dup(int fd) {
 }
 
 
-/* TODO move to uv-common.c? */
-size_t uv__strlcpy(char* dst, const char* src, size_t size) {
-  const char *org;
-
-  if (size == 0) {
-    return 0;
-  }
-
-  org = src;
-  while (--size && *src) {
-    *dst++ = *src++;
-  }
-  *dst = '\0';
-
-  return src - org;
-}
-
-
 uv_err_t uv_cwd(char* buffer, size_t size) {
   if (!buffer || !size) {
     return uv__new_artificial_error(UV_EINVAL);
index 8c0797e..9746454 100644 (file)
@@ -19,7 +19,7 @@
  */
 
 #include "uv.h"
-#include "../uv-common.h"
+#include "internal.h"
 
 #include <assert.h>
 #include <stdint.h>
@@ -41,12 +41,13 @@ void uv__platform_loop_delete(uv_loop_t* loop) {
 }
 
 
-uint64_t uv_hrtime() {
+uint64_t uv__hrtime(void) {
   struct timespec ts;
   clock_gettime(CLOCK_MONOTONIC, &ts);
   return (((uint64_t) ts.tv_sec) * NANOSEC + ts.tv_nsec);
 }
 
+
 void uv_loadavg(double avg[3]) {
   /* Unsupported as of cygwin 1.7.7 */
   avg[0] = avg[1] = avg[2] = 0;
index f40efb2..b5cba86 100644 (file)
@@ -176,7 +176,7 @@ void uv__cf_loop_signal(uv_loop_t* loop, cf_loop_signal_cb cb, void* arg) {
 }
 
 
-uint64_t uv_hrtime(void) {
+uint64_t uv__hrtime(void) {
     mach_timebase_info_data_t info;
 
     if (mach_timebase_info(&info) != KERN_SUCCESS)
index 4a32f6e..44b1ef3 100644 (file)
@@ -63,7 +63,7 @@ void uv__platform_loop_delete(uv_loop_t* loop) {
 }
 
 
-uint64_t uv_hrtime(void) {
+uint64_t uv__hrtime(void) {
   struct timespec ts;
   clock_gettime(CLOCK_MONOTONIC, &ts);
   return (((uint64_t) ts.tv_sec) * NANOSEC + ts.tv_nsec);
index 6c6faf5..f01c83b 100644 (file)
@@ -381,6 +381,7 @@ static ssize_t uv__fs_sendfile(uv_fs_t* req) {
         errno == EIO ||
         errno == ENOTSOCK ||
         errno == EXDEV) {
+      errno = 0;
       return uv__fs_sendfile_emul(req);
     }
 
@@ -412,6 +413,7 @@ static ssize_t uv__fs_sendfile(uv_fs_t* req) {
         errno == EIO ||
         errno == ENOTSOCK ||
         errno == EXDEV) {
+      errno = 0;
       return uv__fs_sendfile_emul(req);
     }
 
index 7f14729..283d295 100644 (file)
@@ -40,7 +40,7 @@ static void uv__getaddrinfo_work(struct uv__work* w) {
 static void uv__getaddrinfo_done(struct uv__work* w, int status) {
   uv_getaddrinfo_t* req = container_of(w, uv_getaddrinfo_t, work_req);
   struct addrinfo *res = req->res;
-#if __sun
+#if defined(__sun)
   size_t hostlen;
 
   if (req->hostname)
@@ -69,13 +69,13 @@ static void uv__getaddrinfo_done(struct uv__work* w, int status) {
 
   if (req->retcode == 0) {
     /* OK */
-#if EAI_NODATA /* FreeBSD deprecated EAI_NODATA */
+#if defined(EAI_NODATA) /* FreeBSD deprecated EAI_NODATA */
   } else if (req->retcode == EAI_NONAME || req->retcode == EAI_NODATA) {
 #else
   } else if (req->retcode == EAI_NONAME) {
 #endif
     uv__set_sys_error(req->loop, ENOENT); /* FIXME compatibility hack */
-#if __sun
+#if defined(__sun)
   } else if (req->retcode == EAI_MEMORY && hostlen >= MAXHOSTNAMELEN) {
     uv__set_sys_error(req->loop, ENOENT);
 #endif
index 786897d..2c61f91 100644 (file)
 # define inline __inline
 #endif
 
-#undef HAVE_PORTS_FS
-
-#if __linux__
+#if defined(__linux__)
 # include "linux/syscalls.h"
 #endif /* __linux__ */
 
 #if defined(__sun)
 # include <sys/port.h>
 # include <port.h>
-# ifdef PORT_SOURCE_FILE
-#  define HAVE_PORTS_FS 1
-# endif
 # define futimes(fd, tv) futimesat(fd, (void*)0, tv)
 #endif /* __sun */
 
@@ -110,14 +105,6 @@ enum {
   UV_TCP_SINGLE_ACCEPT = 0x400  /* Only accept() when idle. */
 };
 
-__attribute__((unused))
-static void uv__req_init(uv_loop_t* loop, uv_req_t* req, uv_req_type type) {
-  req->type = type;
-  uv__req_register(loop, req);
-}
-#define uv__req_init(loop, req, type) \
-  uv__req_init((loop), (uv_req_t*)(req), (type))
-
 /* core */
 void uv__handle_init(uv_loop_t* loop, uv_handle_t* handle, uv_handle_type type);
 int uv__nonblock(int fd, int set);
@@ -169,7 +156,7 @@ int uv__next_timeout(const uv_loop_t* loop);
 /* signal */
 void uv__signal_close(uv_signal_t* handle);
 void uv__signal_global_once_init(void);
-void uv__signal_loop_cleanup();
+void uv__signal_loop_cleanup(uv_loop_t* loop);
 
 /* thread pool */
 void uv__work_submit(uv_loop_t* loop,
@@ -179,6 +166,7 @@ void uv__work_submit(uv_loop_t* loop,
 void uv__work_done(uv_async_t* handle, int status);
 
 /* platform specific */
+uint64_t uv__hrtime(void);
 int uv__kqueue_init(uv_loop_t* loop);
 int uv__platform_loop_init(uv_loop_t* loop, int default_loop);
 void uv__platform_loop_delete(uv_loop_t* loop);
@@ -242,4 +230,17 @@ static const int kFSEventStreamEventFlagItemIsSymlink = 0x00040000;
 
 #endif /* defined(__APPLE__) */
 
+__attribute__((unused))
+static void uv__req_init(uv_loop_t* loop, uv_req_t* req, uv_req_type type) {
+  req->type = type;
+  uv__req_register(loop, req);
+}
+#define uv__req_init(loop, req, type) \
+  uv__req_init((loop), (uv_req_t*)(req), (type))
+
+__attribute__((unused))
+static void uv__update_time(uv_loop_t* loop) {
+  loop->time = uv__hrtime() / 1000000;
+}
+
 #endif /* UV_UNIX_INTERNAL_H_ */
index af9078e..2ab0854 100644 (file)
@@ -141,6 +141,12 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
                   ARRAY_SIZE(events),
                   timeout == -1 ? NULL : &spec);
 
+    /* Update loop->time unconditionally. It's tempting to skip the update when
+     * timeout == 0 (i.e. non-blocking poll) but there is no guarantee that the
+     * operating system didn't reschedule our process while in the syscall.
+     */
+    SAVE_ERRNO(uv__update_time(loop));
+
     if (nfds == 0) {
       assert(timeout != -1);
       return;
@@ -244,10 +250,7 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
 update_timeout:
     assert(timeout > 0);
 
-    diff = uv_hrtime() / 1000000;
-    assert(diff >= base);
-    diff -= base;
-
+    diff = loop->time - base;
     if (diff >= (uint64_t) timeout)
       return;
 
index 95df667..b591314 100644 (file)
@@ -57,7 +57,6 @@
 # define CLOCK_BOOTTIME 7
 #endif
 
-static char buf[MAXPATHLEN + 1];
 static void* args_mem;
 
 static struct {
@@ -182,6 +181,12 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
                           ARRAY_SIZE(events),
                           timeout);
 
+    /* Update loop->time unconditionally. It's tempting to skip the update when
+     * timeout == 0 (i.e. non-blocking poll) but there is no guarantee that the
+     * operating system didn't reschedule our process while in the syscall.
+     */
+    SAVE_ERRNO(uv__update_time(loop));
+
     if (nfds == 0) {
       assert(timeout != -1);
       return;
@@ -243,10 +248,7 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
 update_timeout:
     assert(timeout > 0);
 
-    diff = uv_hrtime() / 1000000;
-    assert(diff >= base);
-    diff -= base;
-
+    diff = loop->time - base;
     if (diff >= (uint64_t) timeout)
       return;
 
@@ -255,7 +257,7 @@ update_timeout:
 }
 
 
-uint64_t uv_hrtime() {
+uint64_t uv__hrtime(void) {
   struct timespec ts;
   clock_gettime(CLOCK_MONOTONIC, &ts);
   return (((uint64_t) ts.tv_sec) * NANOSEC + ts.tv_nsec);
@@ -379,6 +381,7 @@ uv_err_t uv_resident_set_memory(size_t* rss) {
   size_t page_size = getpagesize();
   char *cbuf;
   int foundExeEnd;
+  char buf[PATH_MAX + 1];
 
   f = fopen("/proc/self/stat", "r");
   if (!f) return uv__new_sys_error(errno);
@@ -547,11 +550,13 @@ static void read_models(unsigned int numcpus, uv_cpu_info_t* ci) {
   static const char model_marker[] = "";
   static const char speed_marker[] = "";
 #endif
+  static const char bogus_model[] = "unknown";
   unsigned int model_idx;
   unsigned int speed_idx;
   char buf[1024];
   char* model;
   FILE* fp;
+  char* inferred_model;
 
   fp = fopen("/proc/cpuinfo", "r");
   if (fp == NULL)
@@ -580,6 +585,26 @@ static void read_models(unsigned int numcpus, uv_cpu_info_t* ci) {
     }
   }
   fclose(fp);
+
+  /* Now we want to make sure that all the models contain *something*:
+   * it's not safe to leave them as null.
+   */
+  if (model_idx == 0) {
+    /* No models at all: fake up the first one. */
+    ci[0].model = strndup(bogus_model, sizeof(bogus_model) - 1);
+    model_idx = 1;
+  }
+
+  /* Not enough models, but we do have at least one.  So we'll just
+   * copy the rest down: it might be better to indicate somehow that
+   * the remaining ones have been guessed.
+   */
+  inferred_model = ci[model_idx - 1].model;
+
+  while (model_idx < numcpus) {
+    ci[model_idx].model = strndup(inferred_model, strlen(inferred_model));
+    model_idx++;
+  }
 }
 
 
index 6536215..1f0174a 100644 (file)
 #include <sys/types.h>
 #include <errno.h>
 
-#if __i386__
+#if defined(__i386__)
 # ifndef __NR_socketcall
 #  define __NR_socketcall 102
 # endif
 #endif
 
-#if __arm__
-# if __thumb__ || __ARM_EABI__
+#if defined(__arm__)
+# if defined(__thumb__) || defined(__ARM_EABI__)
 #  define UV_SYSCALL_BASE 0
 # else
 #  define UV_SYSCALL_BASE 0x900000
 #endif /* __arm__ */
 
 #ifndef __NR_accept4
-# if __x86_64__
+# if defined(__x86_64__)
 #  define __NR_accept4 288
-# elif __i386__
+# elif defined(__i386__)
    /* Nothing. Handled through socketcall(). */
-# elif __arm__
+# elif defined(__arm__)
 #  define __NR_accept4 (UV_SYSCALL_BASE + 366)
 # endif
 #endif /* __NR_accept4 */
 
 #ifndef __NR_eventfd
-# if __x86_64__
+# if defined(__x86_64__)
 #  define __NR_eventfd 284
-# elif __i386__
+# elif defined(__i386__)
 #  define __NR_eventfd 323
-# elif __arm__
+# elif defined(__arm__)
 #  define __NR_eventfd (UV_SYSCALL_BASE + 351)
 # endif
 #endif /* __NR_eventfd */
 
 #ifndef __NR_eventfd2
-# if __x86_64__
+# if defined(__x86_64__)
 #  define __NR_eventfd2 290
-# elif __i386__
+# elif defined(__i386__)
 #  define __NR_eventfd2 328
-# elif __arm__
+# elif defined(__arm__)
 #  define __NR_eventfd2 (UV_SYSCALL_BASE + 356)
 # endif
 #endif /* __NR_eventfd2 */
 
 #ifndef __NR_epoll_create
-# if __x86_64__
+# if defined(__x86_64__)
 #  define __NR_epoll_create 213
-# elif __i386__
+# elif defined(__i386__)
 #  define __NR_epoll_create 254
-# elif __arm__
+# elif defined(__arm__)
 #  define __NR_epoll_create (UV_SYSCALL_BASE + 250)
 # endif
 #endif /* __NR_epoll_create */
 
 #ifndef __NR_epoll_create1
-# if __x86_64__
+# if defined(__x86_64__)
 #  define __NR_epoll_create1 291
-# elif __i386__
+# elif defined(__i386__)
 #  define __NR_epoll_create1 329
-# elif __arm__
+# elif defined(__arm__)
 #  define __NR_epoll_create1 (UV_SYSCALL_BASE + 357)
 # endif
 #endif /* __NR_epoll_create1 */
 
 #ifndef __NR_epoll_ctl
-# if __x86_64__
+# if defined(__x86_64__)
 #  define __NR_epoll_ctl 233 /* used to be 214 */
-# elif __i386__
+# elif defined(__i386__)
 #  define __NR_epoll_ctl 255
-# elif __arm__
+# elif defined(__arm__)
 #  define __NR_epoll_ctl (UV_SYSCALL_BASE + 251)
 # endif
 #endif /* __NR_epoll_ctl */
 
 #ifndef __NR_epoll_wait
-# if __x86_64__
+# if defined(__x86_64__)
 #  define __NR_epoll_wait 232 /* used to be 215 */
-# elif __i386__
+# elif defined(__i386__)
 #  define __NR_epoll_wait 256
-# elif __arm__
+# elif defined(__arm__)
 #  define __NR_epoll_wait (UV_SYSCALL_BASE + 252)
 # endif
 #endif /* __NR_epoll_wait */
 
 #ifndef __NR_epoll_pwait
-# if __x86_64__
+# if defined(__x86_64__)
 #  define __NR_epoll_pwait 281
-# elif __i386__
+# elif defined(__i386__)
 #  define __NR_epoll_pwait 319
-# elif __arm__
+# elif defined(__arm__)
 #  define __NR_epoll_pwait (UV_SYSCALL_BASE + 346)
 # endif
 #endif /* __NR_epoll_pwait */
 
 #ifndef __NR_inotify_init
-# if __x86_64__
+# if defined(__x86_64__)
 #  define __NR_inotify_init 253
-# elif __i386__
+# elif defined(__i386__)
 #  define __NR_inotify_init 291
-# elif __arm__
+# elif defined(__arm__)
 #  define __NR_inotify_init (UV_SYSCALL_BASE + 316)
 # endif
 #endif /* __NR_inotify_init */
 
 #ifndef __NR_inotify_init1
-# if __x86_64__
+# if defined(__x86_64__)
 #  define __NR_inotify_init1 294
-# elif __i386__
+# elif defined(__i386__)
 #  define __NR_inotify_init1 332
-# elif __arm__
+# elif defined(__arm__)
 #  define __NR_inotify_init1 (UV_SYSCALL_BASE + 360)
 # endif
 #endif /* __NR_inotify_init1 */
 
 #ifndef __NR_inotify_add_watch
-# if __x86_64__
+# if defined(__x86_64__)
 #  define __NR_inotify_add_watch 254
-# elif __i386__
+# elif defined(__i386__)
 #  define __NR_inotify_add_watch 292
-# elif __arm__
+# elif defined(__arm__)
 #  define __NR_inotify_add_watch (UV_SYSCALL_BASE + 317)
 # endif
 #endif /* __NR_inotify_add_watch */
 
 #ifndef __NR_inotify_rm_watch
-# if __x86_64__
+# if defined(__x86_64__)
 #  define __NR_inotify_rm_watch 255
-# elif __i386__
+# elif defined(__i386__)
 #  define __NR_inotify_rm_watch 293
-# elif __arm__
+# elif defined(__arm__)
 #  define __NR_inotify_rm_watch (UV_SYSCALL_BASE + 318)
 # endif
 #endif /* __NR_inotify_rm_watch */
 
 #ifndef __NR_pipe2
-# if __x86_64__
+# if defined(__x86_64__)
 #  define __NR_pipe2 293
-# elif __i386__
+# elif defined(__i386__)
 #  define __NR_pipe2 331
-# elif __arm__
+# elif defined(__arm__)
 #  define __NR_pipe2 (UV_SYSCALL_BASE + 359)
 # endif
 #endif /* __NR_pipe2 */
 
 #ifndef __NR_recvmmsg
-# if __x86_64__
+# if defined(__x86_64__)
 #  define __NR_recvmmsg 299
-# elif __i386__
+# elif defined(__i386__)
 #  define __NR_recvmmsg 337
-# elif __arm__
+# elif defined(__arm__)
 #  define __NR_recvmmsg (UV_SYSCALL_BASE + 365)
 # endif
 #endif /* __NR_recvmsg */
 
 #ifndef __NR_sendmmsg
-# if __x86_64__
+# if defined(__x86_64__)
 #  define __NR_sendmmsg 307
-# elif __i386__
+# elif defined(__i386__)
 #  define __NR_sendmmsg 345
-# elif __arm__
+# elif defined(__arm__)
 #  define __NR_sendmmsg (UV_SYSCALL_BASE + 374)
 # endif
 #endif /* __NR_sendmmsg */
 
 #ifndef __NR_utimensat
-# if __x86_64__
+# if defined(__x86_64__)
 #  define __NR_utimensat 280
-# elif __i386__
+# elif defined(__i386__)
 #  define __NR_utimensat 320
-# elif __arm__
+# elif defined(__arm__)
 #  define __NR_utimensat (UV_SYSCALL_BASE + 348)
 # endif
 #endif /* __NR_utimensat */
 
 
 int uv__accept4(int fd, struct sockaddr* addr, socklen_t* addrlen, int flags) {
-#if __i386__
+#if defined(__i386__)
   unsigned long args[4];
   int r;
 
@@ -221,7 +221,7 @@ int uv__accept4(int fd, struct sockaddr* addr, socklen_t* addrlen, int flags) {
         errno = ENOSYS;
 
   return r;
-#elif __NR_accept4
+#elif defined(__NR_accept4)
   return syscall(__NR_accept4, fd, addr, addrlen, flags);
 #else
   return errno = ENOSYS, -1;
@@ -230,7 +230,7 @@ int uv__accept4(int fd, struct sockaddr* addr, socklen_t* addrlen, int flags) {
 
 
 int uv__eventfd(unsigned int count) {
-#if __NR_eventfd
+#if defined(__NR_eventfd)
   return syscall(__NR_eventfd, count);
 #else
   return errno = ENOSYS, -1;
@@ -239,7 +239,7 @@ int uv__eventfd(unsigned int count) {
 
 
 int uv__eventfd2(unsigned int count, int flags) {
-#if __NR_eventfd2
+#if defined(__NR_eventfd2)
   return syscall(__NR_eventfd2, count, flags);
 #else
   return errno = ENOSYS, -1;
@@ -248,7 +248,7 @@ int uv__eventfd2(unsigned int count, int flags) {
 
 
 int uv__epoll_create(int size) {
-#if __NR_epoll_create
+#if defined(__NR_epoll_create)
   return syscall(__NR_epoll_create, size);
 #else
   return errno = ENOSYS, -1;
@@ -257,7 +257,7 @@ int uv__epoll_create(int size) {
 
 
 int uv__epoll_create1(int flags) {
-#if __NR_epoll_create1
+#if defined(__NR_epoll_create1)
   return syscall(__NR_epoll_create1, flags);
 #else
   return errno = ENOSYS, -1;
@@ -266,7 +266,7 @@ int uv__epoll_create1(int flags) {
 
 
 int uv__epoll_ctl(int epfd, int op, int fd, struct uv__epoll_event* events) {
-#if __NR_epoll_ctl
+#if defined(__NR_epoll_ctl)
   return syscall(__NR_epoll_ctl, epfd, op, fd, events);
 #else
   return errno = ENOSYS, -1;
@@ -278,7 +278,7 @@ int uv__epoll_wait(int epfd,
                    struct uv__epoll_event* events,
                    int nevents,
                    int timeout) {
-#if __NR_epoll_wait
+#if defined(__NR_epoll_wait)
   return syscall(__NR_epoll_wait, epfd, events, nevents, timeout);
 #else
   return errno = ENOSYS, -1;
@@ -291,7 +291,7 @@ int uv__epoll_pwait(int epfd,
                     int nevents,
                     int timeout,
                     const sigset_t* sigmask) {
-#if __NR_epoll_pwait
+#if defined(__NR_epoll_pwait)
   return syscall(__NR_epoll_pwait,
                  epfd,
                  events,
@@ -306,7 +306,7 @@ int uv__epoll_pwait(int epfd,
 
 
 int uv__inotify_init(void) {
-#if __NR_inotify_init
+#if defined(__NR_inotify_init)
   return syscall(__NR_inotify_init);
 #else
   return errno = ENOSYS, -1;
@@ -315,7 +315,7 @@ int uv__inotify_init(void) {
 
 
 int uv__inotify_init1(int flags) {
-#if __NR_inotify_init1
+#if defined(__NR_inotify_init1)
   return syscall(__NR_inotify_init1, flags);
 #else
   return errno = ENOSYS, -1;
@@ -324,7 +324,7 @@ int uv__inotify_init1(int flags) {
 
 
 int uv__inotify_add_watch(int fd, const char* path, __u32 mask) {
-#if __NR_inotify_add_watch
+#if defined(__NR_inotify_add_watch)
   return syscall(__NR_inotify_add_watch, fd, path, mask);
 #else
   return errno = ENOSYS, -1;
@@ -333,7 +333,7 @@ int uv__inotify_add_watch(int fd, const char* path, __u32 mask) {
 
 
 int uv__inotify_rm_watch(int fd, __s32 wd) {
-#if __NR_inotify_rm_watch
+#if defined(__NR_inotify_rm_watch)
   return syscall(__NR_inotify_rm_watch, fd, wd);
 #else
   return errno = ENOSYS, -1;
@@ -342,7 +342,7 @@ int uv__inotify_rm_watch(int fd, __s32 wd) {
 
 
 int uv__pipe2(int pipefd[2], int flags) {
-#if __NR_pipe2
+#if defined(__NR_pipe2)
   return syscall(__NR_pipe2, pipefd, flags);
 #else
   return errno = ENOSYS, -1;
@@ -354,7 +354,7 @@ int uv__sendmmsg(int fd,
                  struct uv__mmsghdr* mmsg,
                  unsigned int vlen,
                  unsigned int flags) {
-#if __NR_sendmmsg
+#if defined(__NR_sendmmsg)
   return syscall(__NR_sendmmsg, fd, mmsg, vlen, flags);
 #else
   return errno = ENOSYS, -1;
@@ -367,7 +367,7 @@ int uv__recvmmsg(int fd,
                  unsigned int vlen,
                  unsigned int flags,
                  struct timespec* timeout) {
-#if __NR_recvmmsg
+#if defined(__NR_recvmmsg)
   return syscall(__NR_recvmmsg, fd, mmsg, vlen, flags, timeout);
 #else
   return errno = ENOSYS, -1;
@@ -380,7 +380,7 @@ int uv__utimesat(int dirfd,
                  const struct timespec times[2],
                  int flags)
 {
-#if __NR_utimensat
+#if defined(__NR_utimensat)
   return syscall(__NR_utimensat, dirfd, path, times, flags);
 #else
   return errno = ENOSYS, -1;
index 9d1414b..a07569e 100644 (file)
@@ -31,6 +31,8 @@
                                                                               \
   int uv_##name##_start(uv_##name##_t* handle, uv_##name##_cb cb) {           \
     if (uv__is_active(handle)) return 0;                                      \
+    if (cb == NULL)                                                           \
+      return uv__set_artificial_error(handle->loop, UV_EINVAL);               \
     ngx_queue_insert_head(&handle->loop->name##_handles, &handle->queue);     \
     handle->name##_cb = cb;                                                   \
     uv__handle_start(handle);                                                 \
@@ -49,7 +51,7 @@
     ngx_queue_t* q;                                                           \
     ngx_queue_foreach(q, &loop->name##_handles) {                             \
       h = ngx_queue_data(q, uv_##name##_t, queue);                            \
-      if (h->name##_cb) h->name##_cb(h, 0);                                   \
+      h->name##_cb(h, 0);                                                     \
     }                                                                         \
   }                                                                           \
                                                                               \
index e63f12a..5672abe 100644 (file)
@@ -49,7 +49,7 @@ int uv__loop_init(uv_loop_t* loop, int default_loop) {
   ngx_queue_init(&loop->watcher_queue);
 
   loop->closing_handles = NULL;
-  loop->time = uv_hrtime() / 1000000;
+  loop->time = uv__hrtime() / 1000000;
   loop->async_pipefd[0] = -1;
   loop->async_pipefd[1] = -1;
   loop->signal_pipefd[0] = -1;
index d9fb426..0fbcf10 100644 (file)
@@ -56,7 +56,7 @@ void uv__platform_loop_delete(uv_loop_t* loop) {
 }
 
 
-uint64_t uv_hrtime(void) {
+uint64_t uv__hrtime(void) {
   struct timespec ts;
   clock_gettime(CLOCK_MONOTONIC, &ts);
   return (((uint64_t) ts.tv_sec) * NANOSEC + ts.tv_nsec);
index 88f20b0..4dfcd76 100644 (file)
@@ -52,7 +52,7 @@ void uv__platform_loop_delete(uv_loop_t* loop) {
 }
 
 
-uint64_t uv_hrtime(void) {
+uint64_t uv__hrtime(void) {
   struct timespec ts;
   clock_gettime(CLOCK_MONOTONIC, &ts);
   return (((uint64_t) ts.tv_sec) * NANOSEC + ts.tv_nsec);
index c4df81a..4c5714f 100644 (file)
@@ -112,7 +112,7 @@ static void uv__chld(uv_signal_t* handle, int signum) {
 
 
 int uv__make_socketpair(int fds[2], int flags) {
-#if __linux__
+#if defined(__linux__)
   static int no_cloexec;
 
   if (no_cloexec)
@@ -148,7 +148,7 @@ skip:
 
 
 int uv__make_pipe(int fds[2], int flags) {
-#if __linux__
+#if defined(__linux__)
   static int no_pipe2;
 
   if (no_pipe2)
@@ -185,77 +185,69 @@ skip:
  * zero on success.
  */
 static int uv__process_init_stdio(uv_stdio_container_t* container, int fds[2]) {
-  int fd = -1;
-  switch (container->flags & (UV_IGNORE | UV_CREATE_PIPE | UV_INHERIT_FD |
-                              UV_INHERIT_STREAM)) {
-    case UV_IGNORE:
-      return 0;
-    case UV_CREATE_PIPE:
-      assert(container->data.stream != NULL);
-
-      if (container->data.stream->type != UV_NAMED_PIPE) {
-        errno = EINVAL;
-        return -1;
-      }
+  int mask;
+  int fd;
 
-      return uv__make_socketpair(fds, 0);
-    case UV_INHERIT_FD:
-    case UV_INHERIT_STREAM:
-      if (container->flags & UV_INHERIT_FD) {
-        fd = container->data.fd;
-      } else {
-        fd = uv__stream_fd(container->data.stream);
-      }
+  mask = UV_IGNORE | UV_CREATE_PIPE | UV_INHERIT_FD | UV_INHERIT_STREAM;
 
-      if (fd == -1) {
-        errno = EINVAL;
-        return -1;
-      }
+  switch (container->flags & mask) {
+  case UV_IGNORE:
+    return 0;
+
+  case UV_CREATE_PIPE:
+    assert(container->data.stream != NULL);
+    if (container->data.stream->type != UV_NAMED_PIPE) {
+      errno = EINVAL;
+      return -1;
+    }
+    return uv__make_socketpair(fds, 0);
 
-      fds[1] = fd;
+  case UV_INHERIT_FD:
+  case UV_INHERIT_STREAM:
+    if (container->flags & UV_INHERIT_FD)
+      fd = container->data.fd;
+    else
+      fd = uv__stream_fd(container->data.stream);
 
-      return 0;
-    default:
-      assert(0 && "Unexpected flags");
+    if (fd == -1) {
+      errno = EINVAL;
       return -1;
-  }
-}
+    }
 
+    fds[1] = fd;
+    return 0;
 
-static int uv__process_stdio_flags(uv_stdio_container_t* container,
-                                   int writable) {
-  if (container->data.stream->type == UV_NAMED_PIPE &&
-      ((uv_pipe_t*)container->data.stream)->ipc) {
-    return UV_STREAM_READABLE | UV_STREAM_WRITABLE;
-  } else if (writable) {
-    return UV_STREAM_WRITABLE;
-  } else {
-    return UV_STREAM_READABLE;
+  default:
+    assert(0 && "Unexpected flags");
+    return -1;
   }
 }
 
 
 static int uv__process_open_stream(uv_stdio_container_t* container,
-                                   int fds[2],
+                                   int pipefds[2],
                                    int writable) {
-  int child_fd;
   int flags;
-  int fd;
-
-  fd = fds[0];
-  child_fd = fds[1];
 
-  /* No need to create stream */
-  if (!(container->flags & UV_CREATE_PIPE) || fd < 0)
+  if (!(container->flags & UV_CREATE_PIPE) || pipefds[0] < 0)
     return 0;
 
-  assert(child_fd >= 0);
-  close(child_fd);
+  if (close(pipefds[1]))
+    if (errno != EINTR && errno != EINPROGRESS)
+      abort();
 
-  uv__nonblock(fd, 1);
-  flags = uv__process_stdio_flags(container, writable);
+  pipefds[1] = -1;
+  uv__nonblock(pipefds[0], 1);
 
-  return uv__stream_open((uv_stream_t*)container->data.stream, fd, flags);
+  if (container->data.stream->type == UV_NAMED_PIPE &&
+      ((uv_pipe_t*)container->data.stream)->ipc)
+    flags = UV_STREAM_READABLE | UV_STREAM_WRITABLE;
+  else if (writable)
+    flags = UV_STREAM_WRITABLE;
+  else
+    flags = UV_STREAM_READABLE;
+
+  return uv__stream_open(container->data.stream, pipefds[0], flags);
 }
 
 
@@ -391,14 +383,6 @@ int uv_spawn(uv_loop_t* loop,
     if (uv__process_init_stdio(options.stdio + i, pipes[i]))
       goto error;
 
-  /* swap stdin file descriptors, it's the only writable stream */
-  {
-    int* p = pipes[0];
-    int t = p[0];
-    p[0] = p[1];
-    p[1] = t;
-  }
-
   /* This pipe is used by the parent to wait until
    * the child has called `execve()`. We need this
    * to avoid the following race condition:
index 359f45e..d3ab603 100644 (file)
@@ -54,7 +54,7 @@ RB_GENERATE_STATIC(uv__signal_tree_s,
                    uv__signal_compare)
 
 
-static void uv__signal_global_init() {
+static void uv__signal_global_init(void) {
   if (uv__make_pipe(uv__signal_lock_pipefd, 0))
     abort();
 
@@ -69,7 +69,7 @@ void uv__signal_global_once_init(void) {
 
 
 
-static int uv__signal_lock() {
+static int uv__signal_lock(void) {
   int r;
   char data;
 
@@ -81,7 +81,7 @@ static int uv__signal_lock() {
 }
 
 
-static int uv__signal_unlock() {
+static int uv__signal_unlock(void) {
   int r;
   char data = 42;
 
@@ -133,7 +133,7 @@ inline static uv_signal_t* uv__signal_first_handle(int signum) {
 }
 
 
-void uv__signal_handler(int signum) {
+static void uv__signal_handler(int signum) {
   uv__signal_msg_t msg;
   uv_signal_t* handle;
 
index a3193a9..77d74ea 100644 (file)
@@ -128,10 +128,10 @@ void uv__stream_init(uv_loop_t* loop,
 void uv__stream_osx_select(void* arg) {
   uv_stream_t* stream;
   uv__stream_select_t* s;
-  fd_set read;
-  fd_set write;
-  fd_set error;
-  struct timeval timeout;
+  char buf[1024];
+  fd_set sread;
+  fd_set swrite;
+  fd_set serror;
   int events;
   int fd;
   int r;
@@ -152,20 +152,19 @@ void uv__stream_osx_select(void* arg) {
       break;
 
     /* Watch fd using select(2) */
-    FD_ZERO(&read);
-    FD_ZERO(&write);
-    FD_ZERO(&error);
+    FD_ZERO(&sread);
+    FD_ZERO(&swrite);
+    FD_ZERO(&serror);
 
     if (uv_is_readable(stream))
-      FD_SET(fd, &read);
+      FD_SET(fd, &sread);
     if (uv_is_writable(stream))
-      FD_SET(fd, &write);
-    FD_SET(fd, &error);
-    FD_SET(s->int_fd, &read);
+      FD_SET(fd, &swrite);
+    FD_SET(fd, &serror);
+    FD_SET(s->int_fd, &sread);
 
-    timeout.tv_sec = 0;
-    timeout.tv_usec = 250000; /* 250 ms timeout */
-    r = select(max_fd + 1, &read, &write, &error, &timeout);
+    /* Wait indefinitely for fd events */
+    r = select(max_fd + 1, &sread, &swrite, &serror, NULL);
     if (r == -1) {
       if (errno == EINTR)
         continue;
@@ -178,13 +177,33 @@ void uv__stream_osx_select(void* arg) {
     if (r == 0)
       continue;
 
+    /* Empty socketpair's buffer in case of interruption */
+    if (FD_ISSET(s->int_fd, &sread))
+      while (1) {
+        r = read(s->int_fd, buf, sizeof(buf));
+
+        if (r == sizeof(buf))
+          continue;
+
+        if (r != -1)
+          break;
+
+        if (errno == EAGAIN || errno == EWOULDBLOCK)
+          break;
+
+        if (errno == EINTR)
+          continue;
+
+        abort();
+      }
+
     /* Handle events */
     events = 0;
-    if (FD_ISSET(fd, &read))
+    if (FD_ISSET(fd, &sread))
       events |= UV__POLLIN;
-    if (FD_ISSET(fd, &write))
+    if (FD_ISSET(fd, &swrite))
       events |= UV__POLLOUT;
-    if (FD_ISSET(fd, &error))
+    if (FD_ISSET(fd, &serror))
       events |= UV__POLLERR;
 
     uv_mutex_lock(&s->mutex);
@@ -599,30 +618,10 @@ int uv_listen(uv_stream_t* stream, int backlog, uv_connection_cb cb) {
 }
 
 
-uv_write_t* uv_write_queue_head(uv_stream_t* stream) {
-  ngx_queue_t* q;
-  uv_write_t* req;
-
-  if (ngx_queue_empty(&stream->write_queue)) {
-    return NULL;
-  }
-
-  q = ngx_queue_head(&stream->write_queue);
-  if (!q) {
-    return NULL;
-  }
-
-  req = ngx_queue_data(q, struct uv_write_s, queue);
-  assert(req);
-
-  return req;
-}
-
-
 static void uv__drain(uv_stream_t* stream) {
   uv_shutdown_t* req;
 
-  assert(!uv_write_queue_head(stream));
+  assert(ngx_queue_empty(&stream->write_queue));
   assert(stream->write_queue_size == 0);
 
   uv__io_stop(stream->loop, &stream->io_watcher, UV__POLLOUT);
@@ -683,33 +682,24 @@ static void uv__write_req_finish(uv_write_t* req) {
 }
 
 
-/* On success returns NULL. On error returns a pointer to the write request
- * which had the error.
- */
 static void uv__write(uv_stream_t* stream) {
-  uv_write_t* req;
   struct iovec* iov;
+  ngx_queue_t* q;
+  uv_write_t* req;
   int iovcnt;
   ssize_t n;
 
-  if (stream->flags & UV_CLOSING) {
-    /* Handle was closed this tick. We've received a stale
-     * 'is writable' callback from the event loop, ignore.
-     */
-    return;
-  }
-
 start:
 
   assert(uv__stream_fd(stream) >= 0);
 
-  /* Get the request at the head of the queue. */
-  req = uv_write_queue_head(stream);
-  if (!req) {
+  if (ngx_queue_empty(&stream->write_queue)) {
     assert(stream->write_queue_size == 0);
     return;
   }
 
+  q = ngx_queue_head(&stream->write_queue);
+  req = ngx_queue_data(q, uv_write_t, queue);
   assert(req->handle == stream);
 
   /*
@@ -860,9 +850,8 @@ static void uv__write_callbacks(uv_stream_t* stream) {
   assert(ngx_queue_empty(&stream->write_completed_queue));
 
   /* Write queue drained. */
-  if (!uv_write_queue_head(stream)) {
+  if (ngx_queue_empty(&stream->write_queue))
     uv__drain(stream);
-  }
 }
 
 
@@ -1221,8 +1210,10 @@ int uv_write(uv_write_t* req, uv_stream_t* stream, uv_buf_t bufs[], int bufcnt,
 }
 
 
-int uv__read_start_common(uv_stream_t* stream, uv_alloc_cb alloc_cb,
-    uv_read_cb read_cb, uv_read2_cb read2_cb) {
+static int uv__read_start_common(uv_stream_t* stream,
+                                 uv_alloc_cb alloc_cb,
+                                 uv_read_cb read_cb,
+                                 uv_read2_cb read2_cb) {
   assert(stream->type == UV_TCP || stream->type == UV_NAMED_PIPE ||
       stream->type == UV_TTY);
 
index 48b1fca..3fbb50c 100644 (file)
 #include <kstat.h>
 #include <fcntl.h>
 
-#if HAVE_PORTS_FS
-# include <sys/port.h>
-# include <port.h>
-
-# define PORT_FIRED 0x69
-# define PORT_UNUSED 0x0
-# define PORT_LOADED 0x99
-# define PORT_DELETED -1
-#endif
+#include <sys/port.h>
+#include <port.h>
+
+#define PORT_FIRED 0x69
+#define PORT_UNUSED 0x0
+#define PORT_LOADED 0x99
+#define PORT_DELETED -1
 
 #if (!defined(_LP64)) && (_FILE_OFFSET_BITS - 0 == 64)
 #define PROCFS_FILE_OFFSET_BITS_HACK 1
@@ -152,6 +150,12 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
         abort();
     }
 
+    /* Update loop->time unconditionally. It's tempting to skip the update when
+     * timeout == 0 (i.e. non-blocking poll) but there is no guarantee that the
+     * operating system didn't reschedule our process while in the syscall.
+     */
+    SAVE_ERRNO(uv__update_time(loop));
+
     if (events[0].portev_source == 0) {
       if (timeout == 0)
         return;
@@ -213,10 +217,7 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
 update_timeout:
     assert(timeout > 0);
 
-    diff = uv_hrtime() / 1000000;
-    assert(diff >= base);
-    diff -= base;
-
+    diff = loop->time - base;
     if (diff >= (uint64_t) timeout)
       return;
 
@@ -225,8 +226,8 @@ update_timeout:
 }
 
 
-uint64_t uv_hrtime() {
-  return (gethrtime());
+uint64_t uv__hrtime(void) {
+  return gethrtime();
 }
 
 
@@ -272,7 +273,8 @@ void uv_loadavg(double avg[3]) {
 }
 
 
-#if HAVE_PORTS_FS
+#if defined(PORT_SOURCE_FILE)
+
 static void uv__fs_event_rearm(uv_fs_event_t *handle) {
   if (handle->fd == -1)
     return;
@@ -386,7 +388,7 @@ void uv__fs_event_close(uv_fs_event_t* handle) {
   uv__handle_stop(handle);
 }
 
-#else /* !HAVE_PORTS_FS */
+#else /* !defined(PORT_SOURCE_FILE) */
 
 int uv_fs_event_init(uv_loop_t* loop,
                      uv_fs_event_t* handle,
@@ -402,7 +404,7 @@ void uv__fs_event_close(uv_fs_event_t* handle) {
   UNREACHABLE();
 }
 
-#endif /* HAVE_PORTS_FS */
+#endif /* defined(PORT_SOURCE_FILE) */
 
 
 char** uv_setup_args(int argc, char** argv) {
index 0583cb4..4fd5d2f 100644 (file)
@@ -354,7 +354,7 @@ int uv_cond_timedwait(uv_cond_t* cond, uv_mutex_t* mutex, uint64_t timeout) {
   struct timespec ts;
   uint64_t abstime;
 
-  abstime = uv_hrtime() + timeout;
+  abstime = uv__hrtime() + timeout;
   ts.tv_sec = abstime / NANOSEC;
   ts.tv_nsec = abstime % NANOSEC;
   r = pthread_cond_timedwait(cond, mutex, &ts);
index ee42820..b071e4a 100644 (file)
@@ -139,7 +139,7 @@ void uv__work_submit(uv_loop_t* loop,
 }
 
 
-int uv__work_cancel(uv_loop_t* loop, uv_req_t* req, struct uv__work* w) {
+static int uv__work_cancel(uv_loop_t* loop, uv_req_t* req, struct uv__work* w) {
   int cancelled;
 
   uv_mutex_lock(&mutex);
@@ -158,6 +158,7 @@ int uv__work_cancel(uv_loop_t* loop, uv_req_t* req, struct uv__work* w) {
   w->work = uv__cancelled;
   uv_mutex_lock(&loop->wq_mutex);
   ngx_queue_insert_tail(&loop->wq, &w->wq);
+  uv_async_send(&loop->wq_async);
   uv_mutex_unlock(&loop->wq_mutex);
 
   return 0;
index faf9471..49efee7 100644 (file)
@@ -140,7 +140,7 @@ uv_handle_type uv_guess_handle(uv_file file) {
 }
 
 
-void uv_tty_reset_mode() {
+void uv_tty_reset_mode(void) {
   if (orig_termios_fd >= 0) {
     tcsetattr(orig_termios_fd, TCSANOW, &orig_termios);
   }
index 4b242f6..f79b09c 100644 (file)
@@ -556,7 +556,7 @@ int uv_udp_set_membership(uv_udp_t* handle, const char* multicast_addr,
 
 
 static int uv__setsockopt_maybe_char(uv_udp_t* handle, int option, int val) {
-#if __sun
+#if defined(__sun)
   char arg = val;
 #else
   int arg = val;
index 3df3399..0876fed 100644 (file)
@@ -252,57 +252,47 @@ static void uv_poll_ex(uv_loop_t* loop, int block) {
      !ngx_queue_empty(&(loop)->active_reqs) ||                                \
      (loop)->endgame_handles != NULL)
 
-#define UV_LOOP_ONCE(loop, poll)                                              \
-  do {                                                                        \
-    uv_update_time((loop));                                                   \
-    uv_process_timers((loop));                                                \
-                                                                              \
-    /* Call idle callbacks if nothing to do. */                               \
-    if ((loop)->pending_reqs_tail == NULL &&                                  \
-        (loop)->endgame_handles == NULL) {                                    \
-      uv_idle_invoke((loop));                                                 \
-    }                                                                         \
-                                                                              \
-    uv_process_reqs((loop));                                                  \
-    uv_process_endgames((loop));                                              \
-                                                                              \
-    if (!UV_LOOP_ALIVE((loop))) {                                             \
-      break;                                                                  \
-    }                                                                         \
-                                                                              \
-    uv_prepare_invoke((loop));                                                \
-                                                                              \
-    poll((loop), (loop)->idle_handles == NULL &&                              \
-                 (loop)->pending_reqs_tail == NULL &&                         \
-                 (loop)->endgame_handles == NULL &&                           \
-                 UV_LOOP_ALIVE((loop)));                                      \
-                                                                              \
-    uv_check_invoke((loop));                                                  \
-  } while (0);
-
-#define UV_LOOP(loop, poll)                                                   \
-  while (UV_LOOP_ALIVE((loop))) {                                             \
-    UV_LOOP_ONCE(loop, poll)                                                  \
-  }
+int uv_run2(uv_loop_t *loop, uv_run_mode mode) {
+  int r;
+  void (*poll)(uv_loop_t* loop, int block);
+
+  if (pGetQueuedCompletionStatusEx)
+    poll = &uv_poll_ex;
+  else
+    poll = &uv_poll;
+
+  r = UV_LOOP_ALIVE(loop);
+  while (r) {
+    uv_update_time(loop);
+    uv_process_timers(loop);
+
+    /* Call idle callbacks if nothing to do. */
+    if (loop->pending_reqs_tail == NULL &&
+        loop->endgame_handles == NULL) {
+      uv_idle_invoke(loop);
+    }
 
+    uv_process_reqs(loop);
+    uv_process_endgames(loop);
 
-int uv_run_once(uv_loop_t* loop) {
-  if (pGetQueuedCompletionStatusEx) {
-    UV_LOOP_ONCE(loop, uv_poll_ex);
-  } else {
-    UV_LOOP_ONCE(loop, uv_poll);
+    uv_prepare_invoke(loop);
+
+    (*poll)(loop, loop->idle_handles == NULL &&
+                  loop->pending_reqs_tail == NULL &&
+                  loop->endgame_handles == NULL &&
+                  UV_LOOP_ALIVE(loop) &&
+                  !(mode & UV_RUN_NOWAIT));
+
+    uv_check_invoke(loop);
+    r = UV_LOOP_ALIVE(loop);
+
+    if (mode & (UV_RUN_ONCE | UV_RUN_NOWAIT))
+      break;
   }
-  return UV_LOOP_ALIVE(loop);
+  return r;
 }
 
 
 int uv_run(uv_loop_t* loop) {
-  if (pGetQueuedCompletionStatusEx) {
-    UV_LOOP(loop, uv_poll_ex);
-  } else {
-    UV_LOOP(loop, uv_poll);
-  }
-
-  assert(!UV_LOOP_ALIVE((loop)));
-  return 0;
+  return uv_run2(loop, UV_RUN_DEFAULT);
 }
index 9fff631..65080ff 100644 (file)
@@ -52,6 +52,9 @@ void uv_loop_watcher_endgame(uv_loop_t* loop, uv_handle_t* handle) {
     if (handle->flags & UV_HANDLE_ACTIVE)                                     \
       return 0;                                                               \
                                                                               \
+    if (cb == NULL)                                                           \
+      return uv__set_artificial_error(handle->loop, UV_EINVAL);               \
+                                                                              \
     old_head = loop->name##_handles;                                          \
                                                                               \
     handle->name##_next = old_head;                                           \
index adb66a6..92f4604 100644 (file)
@@ -1865,7 +1865,7 @@ void uv_process_tty_connect_req(uv_loop_t* loop, uv_tty_t* handle,
 }
 
 
-void uv_tty_reset_mode() {
+void uv_tty_reset_mode(void) {
   /* Not necessary to do anything. */
   ;
 }
index 8ee0c50..4a57b44 100644 (file)
@@ -26,7 +26,7 @@
 #define CONCURRENT_CALLS 10
 #define TOTAL_CALLS 10000
 
-const char* name = "localhost";
+static const char* name = "localhost";
 
 static uv_loop_t* loop;
 
index ed6d141..1e84307 100644 (file)
@@ -73,6 +73,7 @@ BENCHMARK_DECLARE (async_pummel_4)
 BENCHMARK_DECLARE (async_pummel_8)
 BENCHMARK_DECLARE (spawn)
 BENCHMARK_DECLARE (thread_create)
+BENCHMARK_DECLARE (million_async)
 BENCHMARK_DECLARE (million_timers)
 HELPER_DECLARE    (tcp4_blackhole_server)
 HELPER_DECLARE    (tcp_pump_server)
@@ -157,5 +158,6 @@ TASK_LIST_START
 
   BENCHMARK_ENTRY  (spawn)
   BENCHMARK_ENTRY  (thread_create)
+  BENCHMARK_ENTRY  (million_async)
   BENCHMARK_ENTRY  (million_timers)
 TASK_LIST_END
diff --git a/deps/uv/test/benchmark-million-async.c b/deps/uv/test/benchmark-million-async.c
new file mode 100644 (file)
index 0000000..e03a713
--- /dev/null
@@ -0,0 +1,112 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include "task.h"
+#include "uv.h"
+
+struct async_container {
+  unsigned async_events;
+  unsigned handles_seen;
+  uv_async_t async_handles[1024 * 1024];
+};
+
+static volatile int done;
+static uv_thread_t thread_id;
+static struct async_container* container;
+
+
+static unsigned fastrand(void) {
+  static unsigned g = 0;
+  g = g * 214013 + 2531011;
+  return g;
+}
+
+
+static void thread_cb(void* arg) {
+  unsigned i;
+
+  while (done == 0) {
+    i = fastrand() % ARRAY_SIZE(container->async_handles);
+    uv_async_send(container->async_handles + i);
+  }
+}
+
+
+static void async_cb(uv_async_t* handle, int status) {
+  container->async_events++;
+  handle->data = handle;
+}
+
+
+static void timer_cb(uv_timer_t* handle, int status) {
+  unsigned i;
+
+  done = 1;
+  ASSERT(0 == uv_thread_join(&thread_id));
+
+  for (i = 0; i < ARRAY_SIZE(container->async_handles); i++) {
+    uv_async_t* handle = container->async_handles + i;
+
+    if (handle->data != NULL)
+      container->handles_seen++;
+
+    uv_close((uv_handle_t*) handle, NULL);
+  }
+
+  uv_close((uv_handle_t*) handle, NULL);
+}
+
+
+BENCHMARK_IMPL(million_async) {
+  uv_timer_t timer_handle;
+  uv_async_t* handle;
+  uv_loop_t* loop;
+  int timeout;
+  unsigned i;
+
+  loop = uv_default_loop();
+  timeout = 5000;
+
+  container = malloc(sizeof(*container));
+  ASSERT(container != NULL);
+  container->async_events = 0;
+  container->handles_seen = 0;
+
+  for (i = 0; i < ARRAY_SIZE(container->async_handles); i++) {
+    handle = container->async_handles + i;
+    ASSERT(0 == uv_async_init(loop, handle, async_cb));
+    handle->data = NULL;
+  }
+
+  ASSERT(0 == uv_timer_init(loop, &timer_handle));
+  ASSERT(0 == uv_timer_start(&timer_handle, timer_cb, timeout, 0));
+  ASSERT(0 == uv_thread_create(&thread_id, thread_cb, NULL));
+  ASSERT(0 == uv_run(loop));
+  printf("%s async events in %.1f seconds (%s/s, %s unique handles seen)\n",
+          fmt(container->async_events),
+          timeout / 1000.,
+          fmt(container->async_events / (timeout / 1000.)),
+          fmt(container->handles_seen));
+  free(container);
+
+  MAKE_VALGRIND_HAPPY();
+  return 0;
+}
index e1de83d..4518ef8 100644 (file)
@@ -174,7 +174,7 @@ static void pinger_connect_cb(uv_connect_t* req, int status) {
 }
 
 
-static void pinger_new() {
+static void pinger_new(void) {
   int r;
   struct sockaddr_in client_addr = uv_ip4_addr("0.0.0.0", 0);
   struct sockaddr_in server_addr = uv_ip4_addr("127.0.0.1", TEST_PORT);
index 2394425..bf81c4f 100644 (file)
@@ -117,7 +117,7 @@ static void show_stats(uv_timer_t* handle, int status) {
 }
 
 
-static void read_show_stats() {
+static void read_show_stats(void) {
   int64_t diff;
 
   uv_update_time(loop);
@@ -129,13 +129,7 @@ static void read_show_stats() {
 
 
 
-void write_sockets_close_cb(uv_handle_t* handle) {
-  /* If any client closes, the process is done. */
-  exit(0);
-}
-
-
-void read_sockets_close_cb(uv_handle_t* handle) {
+static void read_sockets_close_cb(uv_handle_t* handle) {
   free(handle);
   read_sockets--;
 
@@ -149,7 +143,7 @@ void read_sockets_close_cb(uv_handle_t* handle) {
 }
 
 
-static void start_stats_collection() {
+static void start_stats_collection(void) {
   int r;
 
   /* Show-stats timer */
@@ -231,7 +225,7 @@ static void connect_cb(uv_connect_t* req, int status) {
 }
 
 
-static void maybe_connect_some() {
+static void maybe_connect_some(void) {
   uv_connect_t* req;
   uv_tcp_t* tcp;
   uv_pipe_t* pipe;
@@ -302,7 +296,7 @@ typedef struct req_list_s {
 static req_list_t* req_freelist = NULL;
 
 
-static uv_req_t* req_alloc() {
+static uv_req_t* req_alloc(void) {
   req_list_t* req;
 
   req = req_freelist;
@@ -407,7 +401,7 @@ HELPER_IMPL(pipe_pump_server) {
 }
 
 
-void tcp_pump(int n) {
+static void tcp_pump(int n) {
   ASSERT(n <= MAX_WRITE_HANDLES);
   TARGET_CONNECTIONS = n;
   type = TCP;
@@ -425,7 +419,7 @@ void tcp_pump(int n) {
 }
 
 
-void pipe_pump(int n) {
+static void pipe_pump(int n) {
   ASSERT(n <= MAX_WRITE_HANDLES);
   TARGET_CONNECTIONS = n;
   type = PIPE;
index 43a7183..ca0e856 100644 (file)
@@ -44,10 +44,10 @@ static int process_open;
 static int pipe_open;
 
 
-static void spawn();
+static void spawn(void);
 
 
-void maybe_spawn() {
+static void maybe_spawn(void) {
   if (process_open == 0 && pipe_open == 0) {
     done++;
     if (done < N) {
@@ -71,7 +71,7 @@ static void exit_cb(uv_process_t* process, int exit_status, int term_signal) {
 }
 
 
-uv_buf_t on_alloc(uv_handle_t* handle, size_t suggested_size) {
+static uv_buf_t on_alloc(uv_handle_t* handle, size_t suggested_size) {
   uv_buf_t buf;
   buf.base = output + output_used;
   buf.len = OUTPUT_SIZE - output_used;
@@ -79,14 +79,14 @@ uv_buf_t on_alloc(uv_handle_t* handle, size_t suggested_size) {
 }
 
 
-void pipe_close_cb(uv_handle_t* pipe) {
+static void pipe_close_cb(uv_handle_t* pipe) {
   ASSERT(pipe_open == 1);
   pipe_open = 0;
   maybe_spawn();
 }
 
 
-void on_read(uv_stream_t* pipe, ssize_t nread, uv_buf_t buf) {
+static void on_read(uv_stream_t* pipe, ssize_t nread, uv_buf_t buf) {
   uv_err_t err = uv_last_error(loop);
 
   if (nread > 0) {
@@ -100,7 +100,7 @@ void on_read(uv_stream_t* pipe, ssize_t nread, uv_buf_t buf) {
 }
 
 
-static void spawn() {
+static void spawn(void) {
   uv_stdio_container_t stdio[2];
   int r;
 
index e541e78..f89c3bc 100644 (file)
@@ -63,9 +63,18 @@ static void on_connection(uv_stream_t*, int status);
 
 #define LEN_OFFSET 0
 #define QUERYID_OFFSET 2
-unsigned char DNSRsp[] = {0, 43, 0, 0, 0x81, 0x80, 0, 1, 0, 1, 0, 0, 0, 0 };
-unsigned char qrecord[] = {5, 'e', 'c', 'h', 'o', 's', 3, 's', 'r', 'v', 0, 0, 1, 0, 1};
-unsigned char arecord[] = {0xc0, 0x0c, 0, 1, 0, 1, 0, 0, 5, 0xbd, 0, 4, 10, 0, 1, 1 };
+
+static unsigned char DNSRsp[] = {
+  0, 43, 0, 0, 0x81, 0x80, 0, 1, 0, 1, 0, 0, 0, 0
+};
+
+static unsigned char qrecord[] = {
+  5, 'e', 'c', 'h', 'o', 's', 3, 's', 'r', 'v', 0, 0, 1, 0, 1
+};
+
+static unsigned char arecord[] = {
+  0xc0, 0x0c, 0, 1, 0, 1, 0, 0, 5, 0xbd, 0, 4, 10, 0, 1, 1
+};
 
 
 static void after_write(uv_write_t* req, int status) {
index f6ea45e..267cc7c 100644 (file)
@@ -313,7 +313,7 @@ void process_cleanup(process_info_t *p) {
 
 
 /* Move the console cursor one line up and back to the first column. */
-void rewind_cursor() {
+void rewind_cursor(void) {
   fprintf(stderr, "\033[2K\r");
 }
 
index 5925ec7..01d6c77 100644 (file)
@@ -39,10 +39,18 @@ static void log_progress(int total, int passed, int failed, const char* name) {
 
 
 const char* fmt(double d) {
+  static char buf[1024];
+  static char* p;
   uint64_t v;
-  char* p;
 
-  p = (char *) calloc(1, 32) + 31; /* leaks memory */
+  if (p == NULL)
+    p = buf;
+
+  p += 31;
+
+  if (p >= buf + sizeof(buf))
+    return "<buffer too small>";
+
   v = (uint64_t) d;
 
 #if 0 /* works but we don't care about fractional precision */
index e1bd83b..3919007 100644 (file)
@@ -38,7 +38,7 @@
 typedef struct {
   char *task_name;
   char *process_name;
-  int (*main)();
+  int (*main)(void);
   int is_helper;
   int show_output;
 } task_entry_t, bench_entry_t;
@@ -55,7 +55,7 @@ typedef struct {
   };
 
 #define TEST_DECLARE(name)                          \
-  int run_test_##name();
+  int run_test_##name(void);
 
 #define TEST_ENTRY(name)                            \
     { #name, #name, &run_test_##name, 0, 0 },
@@ -64,13 +64,13 @@ typedef struct {
     { #name, #name, &run_test_##name, 0, 1 },
 
 #define BENCHMARK_DECLARE(name)                     \
-  int run_benchmark_##name();
+  int run_benchmark_##name(void);
 
 #define BENCHMARK_ENTRY(name)                       \
     { #name, #name, &run_benchmark_##name, 0, 0 },
 
 #define HELPER_DECLARE(name)                        \
-  int run_helper_##name();
+  int run_helper_##name(void);
 
 #define HELPER_ENTRY(task_name, name)               \
     { #task_name, #name, &run_helper_##name, 1, 0 },
@@ -123,7 +123,7 @@ void print_tests(FILE* stream);
  */
 
 /* Do platform-specific initialization. */
-void platform_init();
+void platform_init(int argc, char** argv);
 
 /* Invoke "argv[0] test-name [test-part]". Store process info in *p. */
 /* Make sure that all stdio output of the processes is buffered up. */
@@ -154,6 +154,6 @@ int process_reap(process_info_t *p);
 void process_cleanup(process_info_t *p);
 
 /* Move the console cursor one line up and back to the first column. */
-void rewind_cursor();
+void rewind_cursor(void);
 
 #endif /* RUNNER_H_ */
index b351c42..de7c80e 100644 (file)
@@ -79,8 +79,6 @@ typedef enum {
     abort();                                              \
   } while (0)
 
-
-
 /* Have our own assert, so we are sure it does not get optimized away in
  * a release build.
  */
@@ -103,15 +101,17 @@ typedef enum {
   uv_loop_delete(uv_default_loop())
 
 /* Just sugar for wrapping the main() for a task or helper. */
-#define TEST_IMPL(name)   \
-  int run_test_##name()
-
-#define BENCHMARK_IMPL(name)  \
-  int run_benchmark_##name()
+#define TEST_IMPL(name)                                                       \
+  int run_test_##name(void);                                                  \
+  int run_test_##name(void)
 
-#define HELPER_IMPL(name)  \
-  int run_helper_##name()
+#define BENCHMARK_IMPL(name)                                                  \
+  int run_benchmark_##name(void);                                             \
+  int run_benchmark_##name(void)
 
+#define HELPER_IMPL(name)                                                     \
+  int run_helper_##name(void);                                                \
+  int run_helper_##name(void)
 
 /* Pause the calling thread for a number of milliseconds. */
 void uv_sleep(int msec);
index 26194a1..6ab510b 100644 (file)
@@ -35,7 +35,7 @@ static int prepare_cb_called;
 static int close_cb_called;
 
 
-void thread_cb(void *arg) {
+static void thread_cb(void *arg) {
   int n;
   int r;
 
diff --git a/deps/uv/test/test-condvar-consumer-producer.c b/deps/uv/test/test-condvar-consumer-producer.c
deleted file mode 100644 (file)
index a7bd5a6..0000000
+++ /dev/null
@@ -1,138 +0,0 @@
-/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- */
-
-#include "uv.h"
-#include "task.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-
-#define MAX_CONSUMERS 32
-#define MAX_LOOPS 1000
-
-struct buffer_s {
-  ngx_queue_t queue;
-  int data;
-};
-typedef struct buffer_s buffer_t;
-
-static ngx_queue_t queue;
-static uv_mutex_t mutex;
-static uv_cond_t empty;
-static uv_cond_t full;
-
-static volatile int finished_consumers = 0;
-
-
-static void produce(int value) {
-  buffer_t* buf;
-
-  buf = malloc(sizeof(*buf));
-  ngx_queue_init(&buf->queue);
-  buf->data = value;
-  ngx_queue_insert_tail(&queue, &buf->queue);
-}
-
-
-static int consume(void) {
-  ngx_queue_t* q;
-  buffer_t* buf;
-  int data;
-
-  ASSERT(!ngx_queue_empty(&queue));
-  q = ngx_queue_last(&queue);
-  ngx_queue_remove(q);
-
-  buf = ngx_queue_data(q, buffer_t, queue);
-  data = buf->data;
-  free(buf);
-
-  return data;
-}
-
-
-static void producer(void* arg) {
-  int i;
-
-  (void) arg;
-
-  for (i = 0; i < MAX_LOOPS * MAX_CONSUMERS; i++) {
-    uv_mutex_lock(&mutex);
-    while(!ngx_queue_empty(&queue))
-      uv_cond_wait(&empty, &mutex);
-    produce(i);
-    uv_cond_signal(&full);
-    uv_mutex_unlock(&mutex);
-  }
-}
-
-
-static void consumer(void* arg) {
-  int i;
-  int value;
-
-  (void) arg;
-
-  for (i = 0; i < MAX_LOOPS; i++) {
-    uv_mutex_lock(&mutex);
-    while (ngx_queue_empty(&queue))
-      uv_cond_wait(&full, &mutex);
-    value = consume();
-    ASSERT(value < MAX_LOOPS * MAX_CONSUMERS);
-    uv_cond_signal(&empty);
-    uv_mutex_unlock(&mutex);
-  }
-
-  finished_consumers++;
-}
-
-
-TEST_IMPL(consumer_producer) {
-  int i;
-  uv_thread_t cthreads[MAX_CONSUMERS];
-  uv_thread_t pthread;
-
-  ngx_queue_init(&queue);
-  ASSERT(0 == uv_mutex_init(&mutex));
-  ASSERT(0 == uv_cond_init(&empty));
-  ASSERT(0 == uv_cond_init(&full));
-
-  for (i = 0; i < MAX_CONSUMERS; i++) {
-    ASSERT(0 == uv_thread_create(&cthreads[i], consumer, NULL));
-  }
-
-  ASSERT(0 == uv_thread_create(&pthread, producer, NULL));
-
-  for (i = 0; i < MAX_CONSUMERS; i++) {
-    ASSERT(0 == uv_thread_join(&cthreads[i]));
-  }
-
-  ASSERT(0 == uv_thread_join(&pthread));
-
-  LOGF("finished_consumers: %d\n", finished_consumers);
-  ASSERT(finished_consumers == MAX_CONSUMERS);
-
-  uv_cond_destroy(&empty);
-  uv_cond_destroy(&full);
-  uv_mutex_destroy(&mutex);
-
-  return 0;
-}
index 4219f4c..d5cd82b 100644 (file)
@@ -88,7 +88,7 @@ static void on_connect_without_close(uv_connect_t *req, int status) {
 }
 
 
-void connection_fail(uv_connect_cb connect_cb) {
+static void connection_fail(uv_connect_cb connect_cb) {
   struct sockaddr_in client_addr, server_addr;
   int r;
 
index 064fb6a..a5e09f9 100644 (file)
@@ -100,7 +100,7 @@ static void connection_cb(uv_stream_t* tcp, int status) {
 }
 
 
-static void start_server() {
+static void start_server(void) {
   struct sockaddr_in addr = uv_ip4_addr("0.0.0.0", TEST_PORT);
   uv_tcp_t* server = (uv_tcp_t*)malloc(sizeof *server);
   int r;
@@ -153,7 +153,7 @@ static void connect_cb(uv_connect_t* req, int status) {
 }
 
 
-static void client_connect() {
+static void client_connect(void) {
   struct sockaddr_in addr = uv_ip4_addr("127.0.0.1", TEST_PORT);
   uv_tcp_t* client = (uv_tcp_t*)malloc(sizeof *client);
   uv_connect_t* connect_req = malloc(sizeof *connect_req);
index e635596..a8c61e7 100644 (file)
 #include <errno.h>
 
 #ifndef HAVE_KQUEUE
-# if __APPLE__ || __DragonFly__ || __FreeBSD__ || __OpenBSD__ || __NetBSD__
+# if defined(__APPLE__) ||                                                    \
+     defined(__DragonFly__) ||                                                \
+     defined(__FreeBSD__) ||                                                  \
+     defined(__OpenBSD__) ||                                                  \
+     defined(__NetBSD__)
 #  define HAVE_KQUEUE 1
 # endif
 #endif
@@ -84,7 +88,7 @@ static void embed_thread_runner(void* arg) {
 
 
 static void embed_cb(uv_async_t* async, int status) {
-  uv_run_once(uv_default_loop());
+  uv_run2(uv_default_loop(), UV_RUN_ONCE);
 
   uv_sem_post(&embed_sem);
 }
index 249af9a..9218b87 100644 (file)
 #include <fcntl.h>
 
 #ifndef HAVE_KQUEUE
-# if __APPLE__ || __DragonFly__ || __FreeBSD__ || __OpenBSD__ || __NetBSD__
+# if defined(__APPLE__) ||                                                    \
+     defined(__DragonFly__) ||                                                \
+     defined(__FreeBSD__) ||                                                  \
+     defined(__OpenBSD__) ||                                                  \
+     defined(__NetBSD__)
 #  define HAVE_KQUEUE 1
 # endif
 #endif
@@ -431,7 +435,7 @@ TEST_IMPL(fs_event_close_with_pending_event) {
   return 0;
 }
 
-#if HAVE_KQUEUE
+#if defined(HAVE_KQUEUE)
 
 /* kqueue doesn't register fs events if you don't have an active watcher.
  * The file descriptor needs to be part of the kqueue set of interest and
index 597ef97..ccf7793 100644 (file)
@@ -104,7 +104,7 @@ static char buf[32];
 static char test_buf[] = "test-buffer\n";
 
 
-void check_permission(const char* filename, int mode) {
+static void check_permission(const char* filename, int mode) {
   int r;
   uv_fs_t req;
   struct stat* s;
index 043c891..7e2ae69 100644 (file)
@@ -165,7 +165,7 @@ static void on_connect(uv_connect_t* req, int status) {
 }
 
 
-static int tcp_listener() {
+static int tcp_listener(void) {
   struct sockaddr_in addr = uv_ip4_addr("0.0.0.0", server_port);
   struct sockaddr sockname, peername;
   int namelen;
@@ -206,7 +206,7 @@ static int tcp_listener() {
 }
 
 
-static void tcp_connector() {
+static void tcp_connector(void) {
   struct sockaddr_in server_addr = uv_ip4_addr("127.0.0.1", server_port);
   struct sockaddr sockname;
   int r, namelen;
@@ -261,7 +261,7 @@ static void udp_send(uv_udp_send_t* req, int status) {
 }
 
 
-static int udp_listener() {
+static int udp_listener(void) {
   struct sockaddr_in addr = uv_ip4_addr("0.0.0.0", server_port);
   struct sockaddr sockname;
   int namelen;
index c37d151..3bdc8ea 100644 (file)
@@ -108,7 +108,7 @@ static void connect_cb(uv_connect_t* req, int status) {
 }
 
 
-static void make_many_connections() {
+static void make_many_connections(void) {
   tcp_conn* conn;
   struct sockaddr_in addr;
   int r, i;
@@ -406,7 +406,7 @@ TEST_IMPL(listen_no_simultaneous_accepts) {
 
 /* Everything here runs in a child process. */
 
-tcp_conn conn;
+static tcp_conn conn;
 
 
 static void close_cb(uv_handle_t* handle) {
@@ -578,7 +578,7 @@ int ipc_helper(int listen_after_write) {
 }
 
 
-int ipc_helper_tcp_connection() {
+int ipc_helper_tcp_connection(void) {
   /*
    * This is launched from test-ipc.c. stdin is a duplex channel that we
    * over which a handle will be transmitted.
index 9c59a2d..7fdf2f4 100644 (file)
@@ -22,6 +22,7 @@
 TEST_DECLARE   (platform_output)
 TEST_DECLARE   (callback_order)
 TEST_DECLARE   (run_once)
+TEST_DECLARE   (run_nowait)
 TEST_DECLARE   (barrier_1)
 TEST_DECLARE   (barrier_2)
 TEST_DECLARE   (barrier_3)
@@ -30,7 +31,6 @@ TEST_DECLARE   (condvar_2)
 TEST_DECLARE   (condvar_3)
 TEST_DECLARE   (condvar_4)
 TEST_DECLARE   (condvar_5)
-TEST_DECLARE   (consumer_producer)
 TEST_DECLARE   (semaphore_1)
 TEST_DECLARE   (semaphore_2)
 TEST_DECLARE   (semaphore_3)
@@ -192,6 +192,7 @@ TEST_DECLARE   (threadpool_multiple_event_loops)
 TEST_DECLARE   (threadpool_cancel_getaddrinfo)
 TEST_DECLARE   (threadpool_cancel_work)
 TEST_DECLARE   (threadpool_cancel_fs)
+TEST_DECLARE   (threadpool_cancel_single)
 TEST_DECLARE   (thread_mutex)
 TEST_DECLARE   (thread_rwlock)
 TEST_DECLARE   (thread_create)
@@ -227,6 +228,7 @@ TASK_LIST_START
   TEST_ENTRY  (callback_order)
 #endif
   TEST_ENTRY  (run_once)
+  TEST_ENTRY  (run_nowait)
   TEST_ENTRY  (barrier_1)
   TEST_ENTRY  (barrier_2)
   TEST_ENTRY  (barrier_3)
@@ -235,7 +237,6 @@ TASK_LIST_START
   TEST_ENTRY  (condvar_3)
   TEST_ENTRY  (condvar_4)
   TEST_ENTRY  (condvar_5)
-  TEST_ENTRY  (consumer_producer)
   TEST_ENTRY  (semaphore_1)
   TEST_ENTRY  (semaphore_2)
   TEST_ENTRY  (semaphore_3)
@@ -466,6 +467,7 @@ TASK_LIST_START
   TEST_ENTRY  (threadpool_cancel_getaddrinfo)
   TEST_ENTRY  (threadpool_cancel_work)
   TEST_ENTRY  (threadpool_cancel_fs)
+  TEST_ENTRY  (threadpool_cancel_single)
   TEST_ENTRY  (thread_mutex)
   TEST_ENTRY  (thread_rwlock)
   TEST_ENTRY  (thread_create)
index 18197d1..aced132 100644 (file)
@@ -44,7 +44,7 @@ static void connection_cb(uv_stream_t* tcp, int status) {
 }
 
 
-static void start_server() {
+static void start_server(void) {
   struct sockaddr_in addr = uv_ip4_addr("0.0.0.0", TEST_PORT);
   int r;
 
@@ -71,7 +71,7 @@ static void connect_cb(uv_connect_t* req, int status) {
 }
 
 
-static void client_connect() {
+static void client_connect(void) {
   struct sockaddr_in addr = uv_ip4_addr("127.0.0.1", TEST_PORT);
   uv_connect_t* connect_req = malloc(sizeof *connect_req);
   int r;
index a7b31c7..e7f7e9a 100644 (file)
@@ -47,8 +47,6 @@ typedef struct {
   char read_buffer[BUFSIZE];
 } pinger_t;
 
-void pinger_try_read(pinger_t* pinger);
-
 
 static uv_buf_t alloc_cb(uv_handle_t* handle, size_t size) {
   return uv_buf_init(malloc(size), size);
@@ -145,7 +143,7 @@ static void pinger_on_connect(uv_connect_t *req, int status) {
 
 
 /* same ping-pong test, but using IPv6 connection */
-static void tcp_pinger_v6_new() {
+static void tcp_pinger_v6_new(void) {
   int r;
   struct sockaddr_in6 server_addr = uv_ip6_addr("::1", TEST_PORT);
   pinger_t *pinger;
@@ -170,7 +168,7 @@ static void tcp_pinger_v6_new() {
 }
 
 
-static void tcp_pinger_new() {
+static void tcp_pinger_new(void) {
   int r;
   struct sockaddr_in server_addr = uv_ip4_addr("127.0.0.1", TEST_PORT);
   pinger_t *pinger;
@@ -195,7 +193,7 @@ static void tcp_pinger_new() {
 }
 
 
-static void pipe_pinger_new() {
+static void pipe_pinger_new(void) {
   int r;
   pinger_t *pinger;
 
index eb5cb84..039e95c 100644 (file)
@@ -72,7 +72,7 @@ static int valid_writable_wakeups = 0;
 static int spurious_writable_wakeups = 0;
 
 
-static int got_eagain() {
+static int got_eagain(void) {
 #ifdef _WIN32
   return WSAGetLastError() == WSAEWOULDBLOCK;
 #else
@@ -495,7 +495,7 @@ static void server_poll_cb(uv_poll_t* handle, int status, int events) {
 }
 
 
-static void start_server() {
+static void start_server(void) {
   uv_os_sock_t sock;
   server_context_t* context;
   int r;
@@ -511,7 +511,7 @@ static void start_server() {
 }
 
 
-static void start_client() {
+static void start_client(void) {
   uv_os_sock_t sock;
   connection_context_t* context;
   struct sockaddr_in server_addr = uv_ip4_addr("127.0.0.1", TEST_PORT);
@@ -531,7 +531,7 @@ static void start_client() {
 }
 
 
-static void start_poll_test() {
+static void start_poll_test(void) {
   int i, r;
 
 #ifdef _WIN32
index bc0030d..7b1de1d 100644 (file)
@@ -58,6 +58,11 @@ static void fail_cb(void) {
 }
 
 
+static void fail_cb2(void) {
+  ASSERT(0 && "fail_cb2 should not have been called");
+}
+
+
 static void req_cb(uv_handle_t* req, int status) {
   req_cb_called++;
 }
@@ -104,7 +109,7 @@ TEST_IMPL(ref) {
 TEST_IMPL(idle_ref) {
   uv_idle_t h;
   uv_idle_init(uv_default_loop(), &h);
-  uv_idle_start(&h, NULL);
+  uv_idle_start(&h, (uv_idle_cb) fail_cb2);
   uv_unref((uv_handle_t*)&h);
   uv_run(uv_default_loop());
   do_close(&h);
@@ -127,7 +132,7 @@ TEST_IMPL(async_ref) {
 TEST_IMPL(prepare_ref) {
   uv_prepare_t h;
   uv_prepare_init(uv_default_loop(), &h);
-  uv_prepare_start(&h, NULL);
+  uv_prepare_start(&h, (uv_prepare_cb) fail_cb2);
   uv_unref((uv_handle_t*)&h);
   uv_run(uv_default_loop());
   do_close(&h);
@@ -139,7 +144,7 @@ TEST_IMPL(prepare_ref) {
 TEST_IMPL(check_ref) {
   uv_check_t h;
   uv_check_init(uv_default_loop(), &h);
-  uv_check_start(&h, NULL);
+  uv_check_start(&h, (uv_check_cb) fail_cb2);
   uv_unref((uv_handle_t*)&h);
   uv_run(uv_default_loop());
   do_close(&h);
@@ -235,19 +240,12 @@ TEST_IMPL(tcp_ref2) {
 }
 
 
-static void tcp_ref2b_close_cb(uv_handle_t* handle) {
-  (*(int*) handle->data)++;
-}
-
-
 TEST_IMPL(tcp_ref2b) {
-  int close_cb_called = 0;
   uv_tcp_t h;
-  h.data = &close_cb_called;
   uv_tcp_init(uv_default_loop(), &h);
   uv_listen((uv_stream_t*)&h, 128, (uv_connection_cb)fail_cb);
   uv_unref((uv_handle_t*)&h);
-  uv_close((uv_handle_t*)&h, tcp_ref2b_close_cb);
+  uv_close((uv_handle_t*)&h, close_cb);
   uv_run(uv_default_loop());
   ASSERT(close_cb_called == 1);
   MAKE_VALGRIND_HAPPY();
diff --git a/deps/uv/test/test-run-nowait.c b/deps/uv/test/test-run-nowait.c
new file mode 100644 (file)
index 0000000..fe8dd89
--- /dev/null
@@ -0,0 +1,46 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include "uv.h"
+#include "task.h"
+
+static uv_timer_t timer_handle;
+static int timer_called = 0;
+
+
+static void timer_cb(uv_timer_t* handle, int status) {
+  ASSERT(handle == &timer_handle);
+  ASSERT(status == 0);
+  timer_called = 1;
+}
+
+
+TEST_IMPL(run_nowait) {
+  int r;
+  uv_timer_init(uv_default_loop(), &timer_handle);
+  uv_timer_start(&timer_handle, timer_cb, 100, 100);
+
+  r = uv_run2(uv_default_loop(), UV_RUN_NOWAIT);
+  ASSERT(r != 0);
+  ASSERT(timer_called == 0);
+
+  return 0;
+}
index b425a42..ecd82a2 100644 (file)
@@ -41,7 +41,7 @@ TEST_IMPL(run_once) {
   uv_idle_init(uv_default_loop(), &idle_handle);
   uv_idle_start(&idle_handle, idle_cb);
 
-  while (uv_run_once(uv_default_loop()));
+  while (uv_run2(uv_default_loop(), UV_RUN_ONCE));
   ASSERT(idle_counter == NUM_TICKS);
 
   MAKE_VALGRIND_HAPPY();
index 22f6da5..6e55a7d 100644 (file)
@@ -110,7 +110,7 @@ static void connect_cb(uv_connect_t *req, int status) {
 }
 
 
-void tcp_close_cb(uv_handle_t* handle) {
+static void tcp_close_cb(uv_handle_t* handle) {
   ASSERT(handle == (uv_handle_t*) &tcp);
 
   ASSERT(called_connect_cb == 1);
@@ -122,13 +122,13 @@ void tcp_close_cb(uv_handle_t* handle) {
 }
 
 
-void timer_close_cb(uv_handle_t* handle) {
+static void timer_close_cb(uv_handle_t* handle) {
   ASSERT(handle == (uv_handle_t*) &timer);
   called_timer_close_cb++;
 }
 
 
-void timer_cb(uv_timer_t* handle, int status) {
+static void timer_cb(uv_timer_t* handle, int status) {
   ASSERT(handle == &timer);
   uv_close((uv_handle_t*) handle, timer_close_cb);
 
index 48ab239..c97595f 100644 (file)
@@ -106,7 +106,7 @@ static uv_buf_t on_alloc(uv_handle_t* handle, size_t suggested_size) {
 }
 
 
-void on_read(uv_stream_t* tcp, ssize_t nread, uv_buf_t buf) {
+static void on_read(uv_stream_t* tcp, ssize_t nread, uv_buf_t buf) {
   uv_err_t err = uv_last_error(uv_default_loop());
 
   if (nread > 0) {
@@ -118,7 +118,7 @@ void on_read(uv_stream_t* tcp, ssize_t nread, uv_buf_t buf) {
 }
 
 
-void write_cb(uv_write_t* req, int status) {
+static void write_cb(uv_write_t* req, int status) {
   ASSERT(status == 0);
   uv_close((uv_handle_t*)req->handle, close_cb);
 }
index aeb7bd9..c0028ee 100644 (file)
@@ -34,7 +34,8 @@ static int close_cb_called;
 static int exit_cb_called;
 static int on_read_cb_called;
 static int after_write_cb_called;
-uv_pipe_t out, in;
+static uv_pipe_t in;
+static uv_pipe_t out;
 static uv_loop_t* loop;
 #define OUTPUT_SIZE 1024
 static char output[OUTPUT_SIZE];
@@ -182,7 +183,7 @@ static uv_buf_t on_read_alloc(uv_handle_t* handle, size_t suggested_size) {
 }
 
 
-int stdio_over_pipes_helper() {
+int stdio_over_pipes_helper(void) {
   /* Write several buffers to test that the write order is preserved. */
   char* buffers[] = {
     "he",
index db0397a..970e9fe 100644 (file)
@@ -156,6 +156,15 @@ static void timer_cb(uv_timer_t* handle, int status) {
 }
 
 
+static void nop_work_cb(uv_work_t* req) {
+}
+
+
+static void nop_done_cb(uv_work_t* req, int status) {
+  req->data = "OK";
+}
+
+
 TEST_IMPL(threadpool_cancel_getaddrinfo) {
   uv_getaddrinfo_t reqs[4];
   struct cancel_info ci;
@@ -264,3 +273,35 @@ TEST_IMPL(threadpool_cancel_fs) {
 
   return 0;
 }
+
+
+TEST_IMPL(threadpool_cancel_single) {
+  uv_loop_t* loop;
+  uv_work_t req;
+  int cancelled;
+  int i;
+
+  loop = uv_default_loop();
+  for (i = 0; i < 5000; i++) {
+    req.data = NULL;
+    ASSERT(0 == uv_queue_work(loop, &req, nop_work_cb, nop_done_cb));
+
+    cancelled = uv_cancel((uv_req_t*) &req);
+    if (cancelled == 0)
+      break;
+
+    ASSERT(0 == uv_run(loop));
+  }
+
+  if (cancelled != 0) {
+    fputs("Failed to cancel a work req in 5,000 iterations, giving up.\n",
+          stderr);
+    return 1;
+  }
+
+  ASSERT(req.data == NULL);
+  ASSERT(0 == uv_run(loop));
+  ASSERT(req.data != NULL);  /* Should have been updated by nop_done_cb(). */
+
+  return 0;
+}
index ac6f7f0..f40e46a 100644 (file)
         'include_dirs': [ 'include' ],
         'conditions': [
           ['OS != "win"', {
-            'defines': [ '_LARGEFILE_SOURCE', '_FILE_OFFSET_BITS=64' ],
+            'defines': [
+              '_LARGEFILE_SOURCE',
+              '_FILE_OFFSET_BITS=64',
+              '_POSIX_C_SOURCE=200112',
+            ],
           }],
           ['OS == "mac"', {
-            'defines': [ '_DARWIN_USE_64_BIT_INODE=1' ],
+            'defines': [
+              '_DARWIN_USE_64_BIT_INODE=1',
+              '_DARWIN_C_SOURCE',  # _POSIX_C_SOURCE hides SysV definitions.
+            ],
           }],
         ],
       },
         'test/test-poll-close.c',
         'test/test-process-title.c',
         'test/test-ref.c',
+        'test/test-run-nowait.c',
         'test/test-run-once.c',
         'test/test-semaphore.c',
         'test/test-shutdown-close.c',
         'test/test-thread.c',
         'test/test-barrier.c',
         'test/test-condvar.c',
-        'test/test-condvar-consumer-producer.c',
         'test/test-timer-again.c',
         'test/test-timer.c',
         'test/test-tty.c',
         'test/benchmark-getaddrinfo.c',
         'test/benchmark-list.h',
         'test/benchmark-loop-count.c',
+        'test/benchmark-million-async.c',
         'test/benchmark-million-timers.c',
         'test/benchmark-multi-accept.c',
         'test/benchmark-ping-pongs.c',