deps: upgrade libuv to 3c41597
authorBen Noordhuis <info@bnoordhuis.nl>
Tue, 10 Apr 2012 21:26:28 +0000 (23:26 +0200)
committerBen Noordhuis <info@bnoordhuis.nl>
Tue, 10 Apr 2012 21:32:47 +0000 (23:32 +0200)
41 files changed:
deps/uv/config-unix.mk
deps/uv/include/uv-private/tree.h
deps/uv/include/uv-private/uv-unix.h
deps/uv/include/uv-private/uv-win.h
deps/uv/include/uv.h
deps/uv/src/unix/async.c [new file with mode: 0644]
deps/uv/src/unix/cares.c
deps/uv/src/unix/check.c [new file with mode: 0644]
deps/uv/src/unix/core.c
deps/uv/src/unix/cygwin.c
deps/uv/src/unix/darwin.c
deps/uv/src/unix/ev/ev_kqueue.c
deps/uv/src/unix/fs.c
deps/uv/src/unix/idle.c [new file with mode: 0644]
deps/uv/src/unix/internal.h
deps/uv/src/unix/kqueue.c
deps/uv/src/unix/linux/inotify.c
deps/uv/src/unix/linux/syscalls.c [new file with mode: 0644]
deps/uv/src/unix/linux/syscalls.h [new file with mode: 0644]
deps/uv/src/unix/loop.c [new file with mode: 0644]
deps/uv/src/unix/pipe.c
deps/uv/src/unix/prepare.c [new file with mode: 0644]
deps/uv/src/unix/process.c
deps/uv/src/unix/stream.c
deps/uv/src/unix/sunos.c
deps/uv/src/unix/timer.c [new file with mode: 0644]
deps/uv/src/unix/udp.c
deps/uv/src/uv-common.c
deps/uv/src/uv-common.h
deps/uv/src/win/handle.c
deps/uv/src/win/internal.h
deps/uv/src/win/tcp.c
deps/uv/src/win/udp.c
deps/uv/src/win/util.c
deps/uv/test/test-ipc-send-recv.c
deps/uv/test/test-ipc.c
deps/uv/test/test-ping-pong.c
deps/uv/test/test-pipe-connect-error.c
deps/uv/test/test-platform-output.c
deps/uv/test/test-shutdown-close.c
deps/uv/uv.gyp

index 6450183..2af3f3c 100644 (file)
@@ -27,18 +27,24 @@ LINKFLAGS=-lm
 CPPFLAGS += -D_LARGEFILE_SOURCE
 CPPFLAGS += -D_FILE_OFFSET_BITS=64
 
+OBJS += src/unix/async.o
+OBJS += src/unix/cares.o
+OBJS += src/unix/check.o
 OBJS += src/unix/core.o
 OBJS += src/unix/dl.o
-OBJS += src/unix/fs.o
-OBJS += src/unix/cares.o
-OBJS += src/unix/udp.o
 OBJS += src/unix/error.o
-OBJS += src/unix/thread.o
+OBJS += src/unix/fs.o
+OBJS += src/unix/idle.o
+OBJS += src/unix/loop.o
+OBJS += src/unix/pipe.o
+OBJS += src/unix/prepare.o
 OBJS += src/unix/process.o
+OBJS += src/unix/stream.o
 OBJS += src/unix/tcp.o
-OBJS += src/unix/pipe.o
+OBJS += src/unix/thread.o
+OBJS += src/unix/timer.o
 OBJS += src/unix/tty.o
-OBJS += src/unix/stream.o
+OBJS += src/unix/udp.o
 
 ifeq (SunOS,$(uname_S))
 EV_CONFIG=config_sunos.h
@@ -51,7 +57,7 @@ endif
 ifeq (Darwin,$(uname_S))
 EV_CONFIG=config_darwin.h
 EIO_CONFIG=config_darwin.h
-CPPFLAGS += -Isrc/ares/config_darwin
+CPPFLAGS += -D_DARWIN_USE_64_BIT_INODE=1 -Isrc/ares/config_darwin
 LINKFLAGS+=-framework CoreServices
 OBJS += src/unix/darwin.o
 OBJS += src/unix/kqueue.o
@@ -63,7 +69,7 @@ EIO_CONFIG=config_linux.h
 CSTDFLAG += -D_GNU_SOURCE
 CPPFLAGS += -Isrc/ares/config_linux
 LINKFLAGS+=-ldl -lrt
-OBJS += src/unix/linux/core.o src/unix/linux/inotify.o
+OBJS += src/unix/linux/core.o src/unix/linux/inotify.o src/unix/linux/syscalls.o
 endif
 
 ifeq (FreeBSD,$(uname_S))
index eb05cdc..f936416 100644 (file)
 #ifndef  UV_TREE_H_
 #define  UV_TREE_H_
 
-#if __GNUC__
-# define __unused __attribute__((unused))
-#else
-# define __unused
+#ifndef UV__UNUSED
+# if __GNUC__
+#  define UV__UNUSED __attribute__((unused))
+# else
+#  define UV__UNUSED
+# endif
 #endif
 
 /*
@@ -381,7 +383,7 @@ struct {                                                                      \
 #define  RB_PROTOTYPE(name, type, field, cmp)                                 \
   RB_PROTOTYPE_INTERNAL(name, type, field, cmp,)
 #define  RB_PROTOTYPE_STATIC(name, type, field, cmp)                          \
-  RB_PROTOTYPE_INTERNAL(name, type, field, cmp, __unused static)
+  RB_PROTOTYPE_INTERNAL(name, type, field, cmp, UV__UNUSED static)
 #define RB_PROTOTYPE_INTERNAL(name, type, field, cmp, attr)                   \
 attr void name##_RB_INSERT_COLOR(struct name *, struct type *);               \
 attr void name##_RB_REMOVE_COLOR(struct name *, struct type *, struct type *);\
@@ -400,7 +402,7 @@ attr struct type *name##_RB_MINMAX(struct name *, int);                       \
 #define  RB_GENERATE(name, type, field, cmp)                                  \
   RB_GENERATE_INTERNAL(name, type, field, cmp,)
 #define  RB_GENERATE_STATIC(name, type, field, cmp)                           \
-  RB_GENERATE_INTERNAL(name, type, field, cmp, __unused static)
+  RB_GENERATE_INTERNAL(name, type, field, cmp, UV__UNUSED static)
 #define RB_GENERATE_INTERNAL(name, type, field, cmp, attr)                    \
 attr void                                                                     \
 name##_RB_INSERT_COLOR(struct name *head, struct type *elm)                   \
index 798be5e..0137c0c 100644 (file)
@@ -55,6 +55,9 @@ typedef pthread_rwlock_t uv_rwlock_t;
 typedef void* uv_lib_t;
 #define UV_DYNAMIC /* empty */
 
+#define UV_HANDLE_TYPE_PRIVATE /* empty */
+#define UV_REQ_TYPE_PRIVATE /* empty */
+
 #if __linux__
 # define UV_LOOP_PRIVATE_PLATFORM_FIELDS              \
   /* RB_HEAD(uv__inotify_watchers, uv_fs_event_s) */  \
@@ -74,7 +77,7 @@ typedef void* uv_lib_t;
    * sure that we're always calling ares_process. See the warning above the \
    * definition of ares_timeout(). \
    */ \
-  ev_timer timer; \
+  uv_timer_t timer; \
   /* Poll result queue */ \
   eio_channel uv_eio_channel; \
   struct ev_loop* ev; \
@@ -82,6 +85,7 @@ typedef void* uv_lib_t;
   uv_async_t uv_eio_want_poll_notifier; \
   uv_async_t uv_eio_done_poll_notifier; \
   uv_idle_t uv_eio_poller; \
+  uv_handle_t* endgame_handles; \
   UV_LOOP_PRIVATE_PLATFORM_FIELDS
 
 #define UV_REQ_BUFSML_SIZE (4)
@@ -118,7 +122,7 @@ typedef void* uv_lib_t;
 #define UV_HANDLE_PRIVATE_FIELDS \
   int fd; \
   int flags; \
-  ev_idle next_watcher;
+  uv_handle_t* endgame_next; /* that's what uv-win calls it */ \
 
 
 #define UV_STREAM_PRIVATE_FIELDS \
@@ -182,11 +186,6 @@ typedef void* uv_lib_t;
   ev_timer timer_watcher; \
   uv_timer_cb timer_cb;
 
-#define UV_ARES_TASK_PRIVATE_FIELDS \
-  int sock; \
-  ev_io read_watcher; \
-  ev_io write_watcher;
-
 #define UV_GETADDRINFO_PRIVATE_FIELDS \
   uv_getaddrinfo_cb cb; \
   struct addrinfo* hints; \
@@ -223,7 +222,7 @@ typedef void* uv_lib_t;
   ev_io read_watcher;                 \
   uv_fs_event_cb cb;
 
-#elif (defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1060) \
+#elif defined(__APPLE__)  \
   || defined(__FreeBSD__) \
   || defined(__OpenBSD__) \
   || defined(__NetBSD__)
index 812b274..baeb3e3 100644 (file)
@@ -206,15 +206,21 @@ RB_HEAD(uv_timer_tree_s, uv_timer_s);
   /* Counter to keep track of active udp streams */                           \
   unsigned int active_udp_streams;
 
+#define UV_HANDLE_TYPE_PRIVATE            \
+  UV_ARES_EVENT,
+
 #define UV_REQ_TYPE_PRIVATE               \
   /* TODO: remove the req suffix */       \
+  UV_ACCEPT,                              \
   UV_ARES_EVENT_REQ,                      \
   UV_ARES_CLEANUP_REQ,                    \
+  UV_FS_EVENT_REQ,                        \
   UV_GETADDRINFO_REQ,                     \
   UV_PROCESS_EXIT,                        \
   UV_PROCESS_CLOSE,                       \
+  UV_READ,                                \
   UV_UDP_RECV,                            \
-  UV_FS_EVENT_REQ
+  UV_WAKEUP,
 
 #define UV_REQ_PRIVATE_FIELDS             \
   union {                                 \
@@ -390,13 +396,6 @@ RB_HEAD(uv_timer_tree_s, uv_timer_s);
   uv_handle_t* endgame_next;              \
   unsigned int flags;
 
-#define UV_ARES_TASK_PRIVATE_FIELDS       \
-  struct uv_req_s ares_req;               \
-  SOCKET sock;                            \
-  HANDLE h_wait;                          \
-  WSAEVENT h_event;                       \
-  HANDLE h_close_event;
-
 #define UV_GETADDRINFO_PRIVATE_FIELDS     \
   struct uv_req_s getadddrinfo_req;       \
   uv_getaddrinfo_cb getaddrinfo_cb;       \
index 1609884..0ede308 100644 (file)
@@ -132,37 +132,46 @@ typedef enum {
 } uv_err_code;
 #undef UV_ERRNO_GEN
 
+#define UV_HANDLE_TYPE_MAP(XX)  \
+  XX(ARES_TASK, ares_task)      \
+  XX(ASYNC, async)              \
+  XX(CHECK, check)              \
+  XX(FS_EVENT, fs_event)        \
+  XX(IDLE, idle)                \
+  XX(NAMED_PIPE, pipe)          \
+  XX(PREPARE, prepare)          \
+  XX(PROCESS, process)          \
+  XX(TCP, tcp)                  \
+  XX(TIMER, timer)              \
+  XX(TTY, tty)                  \
+  XX(UDP, udp)                  \
+
+#define UV_REQ_TYPE_MAP(XX)     \
+  XX(CONNECT, connect)          \
+  XX(WRITE, write)              \
+  XX(SHUTDOWN, shutdown)        \
+  XX(UDP_SEND, udp_send)        \
+  XX(FS, fs)                    \
+  XX(WORK, work)                \
+  XX(GETADDRINFO, getaddrinfo)  \
+
 typedef enum {
   UV_UNKNOWN_HANDLE = 0,
-  UV_TCP,
-  UV_UDP,
-  UV_NAMED_PIPE,
-  UV_TTY,
+#define XX(uc, lc) UV_##uc,
+  UV_HANDLE_TYPE_MAP(XX)
+#undef XX
   UV_FILE,
-  UV_TIMER,
-  UV_PREPARE,
-  UV_CHECK,
-  UV_IDLE,
-  UV_ASYNC,
-  UV_ARES_TASK,
-  UV_ARES_EVENT,
-  UV_PROCESS,
-  UV_FS_EVENT
+  UV_HANDLE_TYPE_PRIVATE
+  UV_HANDLE_TYPE_MAX
 } uv_handle_type;
 
 typedef enum {
   UV_UNKNOWN_REQ = 0,
-  UV_CONNECT,
-  UV_ACCEPT,
-  UV_READ,
-  UV_WRITE,
-  UV_SHUTDOWN,
-  UV_WAKEUP,
-  UV_UDP_SEND,
-  UV_FS,
-  UV_WORK,
-  UV_GETADDRINFO,
+#define XX(uc, lc) UV_##uc,
+  UV_REQ_TYPE_MAP(XX)
+#undef XX
   UV_REQ_TYPE_PRIVATE
+  UV_REQ_TYPE_MAX
 } uv_req_type;
 
 
@@ -374,6 +383,18 @@ struct uv_handle_s {
 };
 
 /*
+ * Returns size of various handle types, useful for FFI
+ * bindings to allocate correct memory without copying struct
+ * definitions
+ */
+UV_EXTERN size_t uv_handle_size(uv_handle_type type);
+
+/*
+ * Returns size of request types, useful for dynamic lookup with FFI
+ */
+UV_EXTERN size_t uv_req_size(uv_req_type type);
+
+/*
  * Returns 1 if the prepare/check/idle/timer handle has been started, 0
  * otherwise. For other handle types this always returns 1.
  */
@@ -523,6 +544,16 @@ UV_EXTERN int uv_is_writable(uv_stream_t* handle);
 
 
 /*
+ * Used to determine whether a stream is closing or closed.
+ *
+ * N.B. is only valid between the initialization of the handle
+ *      and the arrival of the close callback, and cannot be used
+ *      to validate the handle.
+ */
+UV_EXTERN int uv_is_closing(uv_handle_t* handle);
+
+
+/*
  * uv_tcp_t is a subclass of uv_stream_t
  *
  * Represents a TCP stream or TCP server.
@@ -1501,6 +1532,7 @@ struct uv_loop_s {
 
 
 /* Don't export the private CPP symbols. */
+#undef UV_HANDLE_TYPE_PRIVATE
 #undef UV_REQ_TYPE_PRIVATE
 #undef UV_REQ_PRIVATE_FIELDS
 #undef UV_STREAM_PRIVATE_FIELDS
diff --git a/deps/uv/src/unix/async.c b/deps/uv/src/unix/async.c
new file mode 100644 (file)
index 0000000..638774c
--- /dev/null
@@ -0,0 +1,58 @@
+/* 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 "internal.h"
+
+
+static void uv__async(EV_P_ ev_async* w, int revents) {
+  uv_async_t* async = container_of(w, uv_async_t, async_watcher);
+
+  if (async->async_cb) {
+    async->async_cb(async, 0);
+  }
+}
+
+
+int uv_async_init(uv_loop_t* loop, uv_async_t* async, uv_async_cb async_cb) {
+  uv__handle_init(loop, (uv_handle_t*)async, UV_ASYNC);
+  loop->counters.async_init++;
+
+  ev_async_init(&async->async_watcher, uv__async);
+  async->async_cb = async_cb;
+
+  /* Note: This does not have symmetry with the other libev wrappers. */
+  ev_async_start(loop->ev, &async->async_watcher);
+  ev_unref(loop->ev);
+
+  return 0;
+}
+
+
+int uv_async_send(uv_async_t* async) {
+  ev_async_send(async->loop->ev, &async->async_watcher);
+  return 0;
+}
+
+
+void uv__async_close(uv_async_t* handle) {
+  ev_async_stop(handle->loop->ev, &handle->async_watcher);
+  ev_ref(handle->loop->ev);
+}
index 18cdefe..03667fd 100644 (file)
  * This is called once per second by loop->timer. It is used to
  * constantly callback into c-ares for possibly processing timeouts.
  */
-static void uv__ares_timeout(struct ev_loop* ev, struct ev_timer* watcher,
-    int revents) {
-  uv_loop_t* loop = ev_userdata(ev);
+static void uv__ares_timeout(uv_timer_t* handle, int status) {
+  assert(!uv_ares_handles_empty(handle->loop));
+  ares_process_fd(handle->loop->channel, ARES_SOCKET_BAD, ARES_SOCKET_BAD);
+}
+
+
+static void uv__ares_timer_start(uv_loop_t* loop) {
+  if (uv_is_active((uv_handle_t*)&loop->timer)) return;
+  uv_timer_start(&loop->timer, uv__ares_timeout, 1000, 1000);
+  uv_ref(loop);
+}
 
-  assert(ev == loop->ev);
-  assert((uv_loop_t*)watcher->data == loop);
-  assert(watcher == &loop->timer);
-  assert(revents == EV_TIMER);
-  assert(!uv_ares_handles_empty(loop));
 
-  ares_process_fd(loop->channel, ARES_SOCKET_BAD, ARES_SOCKET_BAD);
+static void uv__ares_timer_stop(uv_loop_t* loop) {
+  if (!uv_is_active((uv_handle_t*)&loop->timer)) return;
+  uv_timer_stop(&loop->timer);
+  uv_unref(loop);
 }
 
 
@@ -52,7 +58,7 @@ static void uv__ares_io(struct ev_loop* ev, struct ev_io* watcher,
   assert(ev == loop->ev);
 
   /* Reset the idle timer */
-  ev_timer_again(ev, &loop->timer);
+  uv_timer_again(&loop->timer);
 
   /* Process DNS responses */
   ares_process_fd(loop->channel,
@@ -98,9 +104,9 @@ static void uv__ares_sockstate_cb(void* data, ares_socket_t sock,
       /* New socket */
 
       /* If this is the first socket then start the timer. */
-      if (!ev_is_active(&loop->timer)) {
+      if (!uv_is_active((uv_handle_t*)&loop->timer)) {
         assert(uv_ares_handles_empty(loop));
-        ev_timer_again(loop->ev, &loop->timer);
+        uv__ares_timer_start(loop);
       }
 
       h = uv__ares_task_create(loop, sock);
@@ -134,7 +140,7 @@ static void uv__ares_sockstate_cb(void* data, ares_socket_t sock,
     free(h);
 
     if (uv_ares_handles_empty(loop)) {
-      ev_timer_stop(loop->ev, &loop->timer);
+      uv__ares_timer_stop(loop);
     }
   }
 }
@@ -169,7 +175,8 @@ int uv_ares_init_options(uv_loop_t* loop, ares_channel *channelptr,
    * Initialize the timeout timer. The timer won't be started until the
    * first socket is opened.
    */
-  ev_timer_init(&loop->timer, uv__ares_timeout, 1., 1.);
+  uv_timer_init(loop, &loop->timer);
+  uv_unref(loop);
   loop->timer.data = loop;
 
   return rc;
@@ -180,7 +187,7 @@ int uv_ares_init_options(uv_loop_t* loop, ares_channel *channelptr,
 void uv_ares_destroy(uv_loop_t* loop, ares_channel channel) {
   /* only allow destroy if did init */
   if (loop->channel) {
-    ev_timer_stop(loop->ev, &loop->timer);
+    uv__ares_timer_stop(loop);
     ares_destroy(channel);
     loop->channel = NULL;
   }
diff --git a/deps/uv/src/unix/check.c b/deps/uv/src/unix/check.c
new file mode 100644 (file)
index 0000000..a975210
--- /dev/null
@@ -0,0 +1,80 @@
+/* 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 "internal.h"
+
+
+static void uv__check(EV_P_ ev_check* w, int revents) {
+  uv_check_t* check = container_of(w, uv_check_t, check_watcher);
+
+  if (check->check_cb) {
+    check->check_cb(check, 0);
+  }
+}
+
+
+int uv_check_init(uv_loop_t* loop, uv_check_t* check) {
+  uv__handle_init(loop, (uv_handle_t*)check, UV_CHECK);
+  loop->counters.check_init++;
+
+  ev_check_init(&check->check_watcher, uv__check);
+  check->check_cb = NULL;
+
+  return 0;
+}
+
+
+int uv_check_start(uv_check_t* check, uv_check_cb cb) {
+  int was_active = ev_is_active(&check->check_watcher);
+
+  check->check_cb = cb;
+
+  ev_check_start(check->loop->ev, &check->check_watcher);
+
+  if (!was_active) {
+    ev_unref(check->loop->ev);
+  }
+
+  return 0;
+}
+
+
+int uv_check_stop(uv_check_t* check) {
+  int was_active = ev_is_active(&check->check_watcher);
+
+  ev_check_stop(check->loop->ev, &check->check_watcher);
+
+  if (was_active) {
+    ev_ref(check->loop->ev);
+  }
+
+  return 0;
+}
+
+
+int uv__check_active(const uv_check_t* handle) {
+  return ev_is_active(&handle->check_watcher);
+}
+
+
+void uv__check_close(uv_check_t* handle) {
+  uv_check_stop(handle);
+}
index e4d481a..5d5048a 100644 (file)
 static uv_loop_t default_loop_struct;
 static uv_loop_t* default_loop_ptr;
 
-void uv__next(EV_P_ ev_idle* watcher, int revents);
 static void uv__finish_close(uv_handle_t* handle);
 
 
 void uv_close(uv_handle_t* handle, uv_close_cb close_cb) {
-  uv_async_t* async;
-  uv_stream_t* stream;
-  uv_process_t* process;
-
   handle->close_cb = close_cb;
 
   switch (handle->type) {
-    case UV_NAMED_PIPE:
-      uv_pipe_cleanup((uv_pipe_t*)handle);
-      /* Fall through. */
-
-    case UV_TTY:
-    case UV_TCP:
-      stream = (uv_stream_t*)handle;
-
-      uv_read_stop(stream);
-      ev_io_stop(stream->loop->ev, &stream->write_watcher);
-
-      close(stream->fd);
-      stream->fd = -1;
-
-      if (stream->accepted_fd >= 0) {
-        close(stream->accepted_fd);
-        stream->accepted_fd = -1;
-      }
+  case UV_NAMED_PIPE:
+    uv__pipe_close((uv_pipe_t*)handle);
+    break;
 
-      assert(!ev_is_active(&stream->read_watcher));
-      assert(!ev_is_active(&stream->write_watcher));
-      break;
+  case UV_TTY:
+  case UV_TCP:
+    uv__stream_close((uv_stream_t*)handle);
+    break;
 
-    case UV_UDP:
-      uv__udp_start_close((uv_udp_t*)handle);
-      break;
+  case UV_UDP:
+    uv__udp_close((uv_udp_t*)handle);
+    break;
 
-    case UV_PREPARE:
-      uv_prepare_stop((uv_prepare_t*) handle);
-      break;
+  case UV_PREPARE:
+    uv__prepare_close((uv_prepare_t*)handle);
+    break;
 
-    case UV_CHECK:
-      uv_check_stop((uv_check_t*) handle);
-      break;
+  case UV_CHECK:
+    uv__check_close((uv_check_t*)handle);
+    break;
 
-    case UV_IDLE:
-      uv_idle_stop((uv_idle_t*) handle);
-      break;
+  case UV_IDLE:
+    uv__idle_close((uv_idle_t*)handle);
+    break;
 
-    case UV_ASYNC:
-      async = (uv_async_t*)handle;
-      ev_async_stop(async->loop->ev, &async->async_watcher);
-      ev_ref(async->loop->ev);
-      break;
+  case UV_ASYNC:
+    uv__async_close((uv_async_t*)handle);
+    break;
 
-    case UV_TIMER:
-      uv_timer_stop((uv_timer_t*)handle);
-      break;
+  case UV_TIMER:
+    uv__timer_close((uv_timer_t*)handle);
+    break;
 
-    case UV_PROCESS:
-      process = (uv_process_t*)handle;
-      ev_child_stop(process->loop->ev, &process->child_watcher);
-      break;
+  case UV_PROCESS:
+    uv__process_close((uv_process_t*)handle);
+    break;
 
-    case UV_FS_EVENT:
-      uv__fs_event_destroy((uv_fs_event_t*)handle);
-      break;
+  case UV_FS_EVENT:
+    uv__fs_event_close((uv_fs_event_t*)handle);
+    break;
 
-    default:
-      assert(0);
+  default:
+    assert(0);
   }
 
   handle->flags |= UV_CLOSING;
+  handle->endgame_next = handle->loop->endgame_handles;
+  handle->loop->endgame_handles = handle;
+  uv_unref(handle->loop);
+}
+
 
-  /* This is used to call the on_close callback in the next loop. */
-  ev_idle_start(handle->loop->ev, &handle->next_watcher);
-  ev_feed_event(handle->loop->ev, &handle->next_watcher, EV_IDLE);
-  assert(ev_is_pending(&handle->next_watcher));
+int uv_is_closing(uv_handle_t* handle) {
+  return handle->flags & (UV_CLOSING | UV_CLOSED);
 }
 
 
-static int uv__loop_init(uv_loop_t* loop,
-                         struct ev_loop *(ev_loop_new)(unsigned int flags)) {
-  memset(loop, 0, sizeof(*loop));
-  RB_INIT(&loop->uv_ares_handles_);
-#if HAVE_KQUEUE
-  loop->ev = ev_loop_new(EVBACKEND_KQUEUE);
-#else
-  loop->ev = ev_loop_new(EVFLAG_AUTO);
-#endif
-  ev_set_userdata(loop->ev, loop);
-  eio_channel_init(&loop->uv_eio_channel, loop);
-  uv__loop_platform_init(loop);
-  return 0;
+uv_loop_t* uv_default_loop(void) {
+  if (default_loop_ptr)
+    return default_loop_ptr;
+
+  if (uv__loop_init(&default_loop_struct, /* default_loop? */ 1))
+    return NULL;
+
+  return (default_loop_ptr = &default_loop_struct);
 }
 
 
@@ -164,7 +140,7 @@ uv_loop_t* uv_loop_new(void) {
   if ((loop = malloc(sizeof(*loop))) == NULL)
     return NULL;
 
-  if (uv__loop_init(loop, ev_loop_new)) {
+  if (uv__loop_init(loop, /* default_loop? */ 0)) {
     free(loop);
     return NULL;
   }
@@ -174,9 +150,7 @@ uv_loop_t* uv_loop_new(void) {
 
 
 void uv_loop_delete(uv_loop_t* loop) {
-  uv_ares_destroy(loop, loop->channel);
-  ev_loop_destroy(loop->ev);
-  uv__loop_platform_delete(loop);
+  uv__loop_delete(loop);
 #ifndef NDEBUG
   memset(loop, -1, sizeof *loop);
 #endif
@@ -192,26 +166,25 @@ int uv_loop_refcount(const uv_loop_t* loop) {
 }
 
 
-uv_loop_t* uv_default_loop(void) {
-  if (default_loop_ptr)
-    return default_loop_ptr;
-
-  if (uv__loop_init(&default_loop_struct, ev_default_loop))
-    return NULL;
+void uv__run(uv_loop_t* loop) {
+  ev_run(loop->ev, EVRUN_ONCE);
 
-  default_loop_ptr = &default_loop_struct;
-  return default_loop_ptr;
+  while (loop->endgame_handles)
+    uv__finish_close(loop->endgame_handles);
 }
 
 
 int uv_run(uv_loop_t* loop) {
-  ev_run(loop->ev, 0);
+  do
+    uv__run(loop);
+  while (uv_loop_refcount(loop) > 0);
+
   return 0;
 }
 
 
 int uv_run_once(uv_loop_t* loop) {
-  ev_run(loop->ev, EVRUN_ONCE);
+  uv__run(loop);
   return 0;
 }
 
@@ -223,11 +196,8 @@ void uv__handle_init(uv_loop_t* loop, uv_handle_t* handle,
   handle->loop = loop;
   handle->type = type;
   handle->flags = 0;
-
-  ev_init(&handle->next_watcher, uv__next);
-
-  /* Ref the loop until this handle is closed. See uv__finish_close. */
-  ev_ref(loop->ev);
+  handle->endgame_next = NULL;
+  uv_ref(loop); /* unref'd in uv_close() */
 }
 
 
@@ -284,26 +254,12 @@ void uv__finish_close(uv_handle_t* handle) {
       break;
   }
 
-  ev_idle_stop(loop->ev, &handle->next_watcher);
+
+  loop->endgame_handles = handle->endgame_next;
 
   if (handle->close_cb) {
     handle->close_cb(handle);
   }
-
-  ev_unref(loop->ev);
-}
-
-
-void uv__next(EV_P_ ev_idle* w, int revents) {
-  uv_handle_t* handle = container_of(w, uv_handle_t, next_watcher);
-
-  assert(revents == EV_IDLE);
-
-  /* For now this function is only to handle the closing event, but we might
-   * put more stuff here later.
-   */
-  assert(handle->flags & UV_CLOSING);
-  uv__finish_close(handle);
 }
 
 
@@ -333,299 +289,22 @@ void uv__req_init(uv_loop_t* loop, uv_req_t* req) {
 }
 
 
-static void uv__prepare(EV_P_ ev_prepare* w, int revents) {
-  uv_prepare_t* prepare = container_of(w, uv_prepare_t, prepare_watcher);
-
-  if (prepare->prepare_cb) {
-    prepare->prepare_cb(prepare, 0);
-  }
-}
-
-
-int uv_prepare_init(uv_loop_t* loop, uv_prepare_t* prepare) {
-  uv__handle_init(loop, (uv_handle_t*)prepare, UV_PREPARE);
-  loop->counters.prepare_init++;
-
-  ev_prepare_init(&prepare->prepare_watcher, uv__prepare);
-  prepare->prepare_cb = NULL;
-
-  return 0;
-}
-
-
-int uv_prepare_start(uv_prepare_t* prepare, uv_prepare_cb cb) {
-  int was_active = ev_is_active(&prepare->prepare_watcher);
-
-  prepare->prepare_cb = cb;
-
-  ev_prepare_start(prepare->loop->ev, &prepare->prepare_watcher);
-
-  if (!was_active) {
-    ev_unref(prepare->loop->ev);
-  }
-
-  return 0;
-}
-
-
-int uv_prepare_stop(uv_prepare_t* prepare) {
-  int was_active = ev_is_active(&prepare->prepare_watcher);
-
-  ev_prepare_stop(prepare->loop->ev, &prepare->prepare_watcher);
-
-  if (was_active) {
-    ev_ref(prepare->loop->ev);
-  }
-  return 0;
-}
-
-
-
-static void uv__check(EV_P_ ev_check* w, int revents) {
-  uv_check_t* check = container_of(w, uv_check_t, check_watcher);
-
-  if (check->check_cb) {
-    check->check_cb(check, 0);
-  }
-}
-
-
-int uv_check_init(uv_loop_t* loop, uv_check_t* check) {
-  uv__handle_init(loop, (uv_handle_t*)check, UV_CHECK);
-  loop->counters.check_init++;
-
-  ev_check_init(&check->check_watcher, uv__check);
-  check->check_cb = NULL;
-
-  return 0;
-}
-
-
-int uv_check_start(uv_check_t* check, uv_check_cb cb) {
-  int was_active = ev_is_active(&check->check_watcher);
-
-  check->check_cb = cb;
-
-  ev_check_start(check->loop->ev, &check->check_watcher);
-
-  if (!was_active) {
-    ev_unref(check->loop->ev);
-  }
-
-  return 0;
-}
-
-
-int uv_check_stop(uv_check_t* check) {
-  int was_active = ev_is_active(&check->check_watcher);
-
-  ev_check_stop(check->loop->ev, &check->check_watcher);
-
-  if (was_active) {
-    ev_ref(check->loop->ev);
-  }
-
-  return 0;
-}
-
-
-static void uv__idle(EV_P_ ev_idle* w, int revents) {
-  uv_idle_t* idle = container_of(w, uv_idle_t, idle_watcher);
-
-  if (idle->idle_cb) {
-    idle->idle_cb(idle, 0);
-  }
-}
-
-
-
-int uv_idle_init(uv_loop_t* loop, uv_idle_t* idle) {
-  uv__handle_init(loop, (uv_handle_t*)idle, UV_IDLE);
-  loop->counters.idle_init++;
-
-  ev_idle_init(&idle->idle_watcher, uv__idle);
-  idle->idle_cb = NULL;
-
-  return 0;
-}
-
-
-int uv_idle_start(uv_idle_t* idle, uv_idle_cb cb) {
-  int was_active = ev_is_active(&idle->idle_watcher);
-
-  idle->idle_cb = cb;
-  ev_idle_start(idle->loop->ev, &idle->idle_watcher);
-
-  if (!was_active) {
-    ev_unref(idle->loop->ev);
-  }
-
-  return 0;
-}
-
-
-int uv_idle_stop(uv_idle_t* idle) {
-  int was_active = ev_is_active(&idle->idle_watcher);
-
-  ev_idle_stop(idle->loop->ev, &idle->idle_watcher);
-
-  if (was_active) {
-    ev_ref(idle->loop->ev);
-  }
-
-  return 0;
-}
-
-
 int uv_is_active(uv_handle_t* handle) {
   switch (handle->type) {
-    case UV_TIMER:
-      return ev_is_active(&((uv_timer_t*)handle)->timer_watcher);
-
-    case UV_PREPARE:
-      return ev_is_active(&((uv_prepare_t*)handle)->prepare_watcher);
-
-    case UV_CHECK:
-      return ev_is_active(&((uv_check_t*)handle)->check_watcher);
-
-    case UV_IDLE:
-      return ev_is_active(&((uv_idle_t*)handle)->idle_watcher);
-
-    default:
-      return 1;
+  case UV_CHECK:
+    return uv__check_active((uv_check_t*)handle);
+  case UV_IDLE:
+    return uv__idle_active((uv_idle_t*)handle);
+  case UV_PREPARE:
+    return uv__prepare_active((uv_prepare_t*)handle);
+  case UV_TIMER:
+    return uv__timer_active((uv_timer_t*)handle);
+  default:
+    return 1;
   }
 }
 
 
-static void uv__async(EV_P_ ev_async* w, int revents) {
-  uv_async_t* async = container_of(w, uv_async_t, async_watcher);
-
-  if (async->async_cb) {
-    async->async_cb(async, 0);
-  }
-}
-
-
-int uv_async_init(uv_loop_t* loop, uv_async_t* async, uv_async_cb async_cb) {
-  uv__handle_init(loop, (uv_handle_t*)async, UV_ASYNC);
-  loop->counters.async_init++;
-
-  ev_async_init(&async->async_watcher, uv__async);
-  async->async_cb = async_cb;
-
-  /* Note: This does not have symmetry with the other libev wrappers. */
-  ev_async_start(loop->ev, &async->async_watcher);
-  ev_unref(loop->ev);
-
-  return 0;
-}
-
-
-int uv_async_send(uv_async_t* async) {
-  ev_async_send(async->loop->ev, &async->async_watcher);
-  return 0;
-}
-
-
-static int uv__timer_active(const uv_timer_t* timer) {
-  return timer->flags & UV_TIMER_ACTIVE;
-}
-
-
-static int uv__timer_repeating(const uv_timer_t* timer) {
-  return timer->flags & UV_TIMER_REPEAT;
-}
-
-
-static void uv__timer_cb(EV_P_ ev_timer* w, int revents) {
-  uv_timer_t* timer = container_of(w, uv_timer_t, timer_watcher);
-
-  assert(uv__timer_active(timer));
-
-  if (!uv__timer_repeating(timer)) {
-    timer->flags &= ~UV_TIMER_ACTIVE;
-    ev_ref(EV_A);
-  }
-
-  if (timer->timer_cb) {
-    timer->timer_cb(timer, 0);
-  }
-}
-
-
-int uv_timer_init(uv_loop_t* loop, uv_timer_t* timer) {
-  uv__handle_init(loop, (uv_handle_t*)timer, UV_TIMER);
-  loop->counters.timer_init++;
-
-  ev_init(&timer->timer_watcher, uv__timer_cb);
-
-  return 0;
-}
-
-
-int uv_timer_start(uv_timer_t* timer, uv_timer_cb cb, int64_t timeout,
-    int64_t repeat) {
-  if (uv__timer_active(timer)) {
-    return -1;
-  }
-
-  timer->timer_cb = cb;
-  timer->flags |= UV_TIMER_ACTIVE;
-
-  if (repeat)
-    timer->flags |= UV_TIMER_REPEAT;
-  else
-    timer->flags &= ~UV_TIMER_REPEAT;
-
-  ev_timer_set(&timer->timer_watcher, timeout / 1000.0, repeat / 1000.0);
-  ev_timer_start(timer->loop->ev, &timer->timer_watcher);
-  ev_unref(timer->loop->ev);
-
-  return 0;
-}
-
-
-int uv_timer_stop(uv_timer_t* timer) {
-  if (uv__timer_active(timer)) {
-    ev_ref(timer->loop->ev);
-  }
-
-  timer->flags &= ~(UV_TIMER_ACTIVE | UV_TIMER_REPEAT);
-  ev_timer_stop(timer->loop->ev, &timer->timer_watcher);
-
-  return 0;
-}
-
-
-int uv_timer_again(uv_timer_t* timer) {
-  if (!uv__timer_active(timer)) {
-    uv__set_sys_error(timer->loop, EINVAL);
-    return -1;
-  }
-
-  assert(uv__timer_repeating(timer));
-  ev_timer_again(timer->loop->ev, &timer->timer_watcher);
-  return 0;
-}
-
-
-void uv_timer_set_repeat(uv_timer_t* timer, int64_t repeat) {
-  assert(timer->type == UV_TIMER);
-  timer->timer_watcher.repeat = repeat / 1000.0;
-
-  if (repeat)
-    timer->flags |= UV_TIMER_REPEAT;
-  else
-    timer->flags &= ~UV_TIMER_REPEAT;
-}
-
-
-int64_t uv_timer_get_repeat(uv_timer_t* timer) {
-  assert(timer->type == UV_TIMER);
-  return (int64_t)(1000 * timer->timer_watcher.repeat);
-}
-
-
 static int uv_getaddrinfo_done(eio_req* req) {
   uv_getaddrinfo_t* handle = req->data;
   struct addrinfo *res = handle->res;
@@ -767,9 +446,8 @@ int uv__accept(int sockfd, struct sockaddr* saddr, socklen_t slen) {
   assert(sockfd >= 0);
 
   while (1) {
-#if HAVE_SYS_ACCEPT4
-    peerfd = sys_accept4(sockfd, saddr, &slen, SOCK_NONBLOCK | SOCK_CLOEXEC);
-
+#if __linux__
+    peerfd = uv__accept4(sockfd, saddr, &slen, UV__SOCK_NONBLOCK|UV__SOCK_CLOEXEC);
     if (peerfd != -1)
       break;
 
index aef8d76..31b069f 100644 (file)
@@ -79,6 +79,6 @@ int uv_fs_event_init(uv_loop_t* loop,
 }
 
 
-void uv__fs_event_destroy(uv_fs_event_t* handle) {
+void uv__fs_event_close(uv_fs_event_t* handle) {
   assert(0 && "implement me");
 }
index 6b3705f..e6deb30 100644 (file)
@@ -73,6 +73,7 @@ uint64_t uv_hrtime() {
 int uv_exepath(char* buffer, size_t* size) {
   uint32_t usize;
   int result;
+  char* path;
   char* fullpath;
 
   if (!buffer || !size) {
@@ -83,9 +84,11 @@ int uv_exepath(char* buffer, size_t* size) {
   result = _NSGetExecutablePath(buffer, &usize);
   if (result) return result;
 
-  fullpath = realpath(buffer, NULL);
+  path = (char*)malloc(2 * PATH_MAX);
+  fullpath = realpath(buffer, path);
 
   if (fullpath == NULL) {
+    free(path);
     return -1;
   }
 
index f03cb80..871e771 100644 (file)
 #include <string.h>
 #include <errno.h>
 
+/* These are the same on OS X and the BSDs. */
+#ifndef NOTE_DELETE
+# define NOTE_DELETE  0x01
+#endif
+#ifndef NOTE_WRITE
+# define NOTE_WRITE    0x02
+#endif
+#ifndef NOTE_EXTEND
+# define NOTE_EXTEND  0x04
+#endif
+#ifndef NOTE_ATTRIB
+# define NOTE_ATTRIB  0x08
+#endif
+#ifndef NOTE_LINK
+# define NOTE_LINK    0x10
+#endif
+#ifndef NOTE_RENAME
+# define NOTE_RENAME  0x20
+#endif
+#ifndef NOTE_REVOKE
+# define NOTE_REVOKE  0x40
+#endif
+
+
 extern void
 uv__kqueue_hack (EV_P_ int fflags, ev_io *w);
 
index 6615516..81dd8ea 100644 (file)
@@ -497,23 +497,27 @@ int uv_fs_utime(uv_loop_t* loop, uv_fs_t* req, const char* path, double atime,
 
 
 #if HAVE_FUTIMES
-static int _futime(const uv_file file, double atime, double mtime) {
+static int _futime(const uv_file fd, double atime, double mtime) {
+#if __linux__
+  /* utimesat() has nanosecond resolution but we stick to microseconds
+   * for the sake of consistency with other platforms.
+   */
+  struct timespec ts[2];
+  ts[0].tv_sec = atime;
+  ts[0].tv_nsec = (unsigned long)(atime * 1000000) % 1000000 * 1000;
+  ts[1].tv_sec = mtime;
+  ts[1].tv_nsec = (unsigned long)(mtime * 1000000) % 1000000 * 1000;
+  return uv__utimesat(fd, NULL, ts, 0);
+#else
   struct timeval tv[2];
-
-  /* FIXME possible loss of precision in floating-point arithmetic? */
   tv[0].tv_sec = atime;
   tv[0].tv_usec = (unsigned long)(atime * 1000000) % 1000000;
-
   tv[1].tv_sec = mtime;
   tv[1].tv_usec = (unsigned long)(mtime * 1000000) % 1000000;
-
-#ifdef __sun
-  return futimesat(file, NULL, tv);
-#else
-  return futimes(file, tv);
-#endif
+  return futimes(fd, tv);
+#endif /* __linux__ */
 }
-#endif
+#endif /* HAVE_FUTIMES */
 
 
 int uv_fs_futime(uv_loop_t* loop, uv_fs_t* req, uv_file file, double atime,
diff --git a/deps/uv/src/unix/idle.c b/deps/uv/src/unix/idle.c
new file mode 100644 (file)
index 0000000..5b4cf57
--- /dev/null
@@ -0,0 +1,79 @@
+/* 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 "internal.h"
+
+
+static void uv__idle(EV_P_ ev_idle* w, int revents) {
+  uv_idle_t* idle = container_of(w, uv_idle_t, idle_watcher);
+
+  if (idle->idle_cb) {
+    idle->idle_cb(idle, 0);
+  }
+}
+
+
+int uv_idle_init(uv_loop_t* loop, uv_idle_t* idle) {
+  uv__handle_init(loop, (uv_handle_t*)idle, UV_IDLE);
+  loop->counters.idle_init++;
+
+  ev_idle_init(&idle->idle_watcher, uv__idle);
+  idle->idle_cb = NULL;
+
+  return 0;
+}
+
+
+int uv_idle_start(uv_idle_t* idle, uv_idle_cb cb) {
+  int was_active = ev_is_active(&idle->idle_watcher);
+
+  idle->idle_cb = cb;
+  ev_idle_start(idle->loop->ev, &idle->idle_watcher);
+
+  if (!was_active) {
+    ev_unref(idle->loop->ev);
+  }
+
+  return 0;
+}
+
+
+int uv_idle_stop(uv_idle_t* idle) {
+  int was_active = ev_is_active(&idle->idle_watcher);
+
+  ev_idle_stop(idle->loop->ev, &idle->idle_watcher);
+
+  if (was_active) {
+    ev_ref(idle->loop->ev);
+  }
+
+  return 0;
+}
+
+
+int uv__idle_active(const uv_idle_t* handle) {
+  return ev_is_active(&handle->idle_watcher);
+}
+
+
+void uv__idle_close(uv_idle_t* handle) {
+  uv_idle_stop(handle);
+}
index 3cc086f..379b996 100644 (file)
 #undef HAVE_KQUEUE
 #undef HAVE_PORTS_FS
 
-#if defined(__linux__)
-
-# undef HAVE_SYS_UTIMESAT
-# undef HAVE_SYS_PIPE2
-# undef HAVE_SYS_ACCEPT4
-
-# undef _GNU_SOURCE
-# define _GNU_SOURCE
-
-# include <linux/version.h>
-# include <sys/syscall.h>
-# include <features.h>
-# include <unistd.h>
-
-# if __NR_utimensat
-#  define HAVE_SYS_UTIMESAT 1
-# endif
-# if __NR_pipe2
-#  define HAVE_SYS_PIPE2 1
-# endif
-# if __NR_accept4
-#  define HAVE_SYS_ACCEPT4 1
-# endif
-
-# ifndef O_CLOEXEC
-#  define O_CLOEXEC 02000000
-# endif
-
-# ifndef SOCK_CLOEXEC
-#  define SOCK_CLOEXEC O_CLOEXEC
-# endif
-
-# ifndef SOCK_NONBLOCK
-#  define SOCK_NONBLOCK O_NONBLOCK
-# endif
-
-# if HAVE_SYS_UTIMESAT
-inline static int sys_utimesat(int dirfd,
-                               const char* path,
-                               const struct timespec times[2],
-                               int flags)
-{
-  return syscall(__NR_utimensat, dirfd, path, times, flags);
-}
-inline static int sys_futimes(int fd, const struct timeval times[2])
-{
-  struct timespec ts[2];
-  ts[0].tv_sec = times[0].tv_sec, ts[0].tv_nsec = times[0].tv_usec * 1000;
-  ts[1].tv_sec = times[1].tv_sec, ts[1].tv_nsec = times[1].tv_usec * 1000;
-  return sys_utimesat(fd, NULL, ts, 0);
-}
-#  undef HAVE_FUTIMES
-#  define HAVE_FUTIMES 1
-#  define futimes(fd, times) sys_futimes(fd, times)
-# endif /* HAVE_SYS_FUTIMESAT */
-
-# if HAVE_SYS_PIPE2
-inline static int sys_pipe2(int pipefd[2], int flags)
-{
-  return syscall(__NR_pipe2, pipefd, flags);
-}
-# endif /* HAVE_SYS_PIPE2 */
-
-# if HAVE_SYS_ACCEPT4
-inline static int sys_accept4(int fd,
-                              struct sockaddr* addr,
-                              socklen_t* addrlen,
-                              int flags)
-{
-  return syscall(__NR_accept4, fd, addr, addrlen, flags);
-}
-# endif /* HAVE_SYS_ACCEPT4 */
-
+#if __linux__
+# include "linux/syscalls.h"
+# define HAVE_FUTIMES 1 /* emulated with utimesat() */
 #endif /* __linux__ */
 
 #if defined(__sun)
@@ -118,6 +48,8 @@ inline static int sys_accept4(int fd,
 # ifdef PORT_SOURCE_FILE
 #  define HAVE_PORTS_FS 1
 # endif
+# define HAVE_FUTIMES 1
+# define futimes(fd, tv) futimesat(fd, (void*)0, tv)
 #endif /* __sun */
 
 #if defined(__APPLE__) || defined(__FreeBSD__) || defined(__sun)
@@ -125,7 +57,7 @@ inline static int sys_accept4(int fd,
 #endif
 
 /* FIXME exact copy of the #ifdef guard in uv-unix.h */
-#if (defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1060) \
+#if defined(__APPLE__)  \
   || defined(__FreeBSD__) \
   || defined(__OpenBSD__) \
   || defined(__NetBSD__)
@@ -172,6 +104,10 @@ int uv__cloexec(int fd, int set) __attribute__((unused));
 int uv__socket(int domain, int type, int protocol);
 int uv__dup(int fd);
 
+/* loop */
+int uv__loop_init(uv_loop_t* loop, int default_loop);
+void uv__loop_delete(uv_loop_t* loop);
+
 /* error */
 uv_err_code uv_translate_sys_error(int sys_errno);
 void uv_fatal_error(const int errorno, const char* syscall);
@@ -198,28 +134,28 @@ int uv__tcp_keepalive(uv_tcp_t* handle, int enable, unsigned int delay);
 /* pipe */
 int uv_pipe_listen(uv_pipe_t* handle, int backlog, uv_connection_cb cb);
 void uv__pipe_accept(EV_P_ ev_io* watcher, int revents);
-int uv_pipe_cleanup(uv_pipe_t* handle);
 
-/* udp */
-void uv__udp_start_close(uv_udp_t* handle);
+/* various */
+int uv__check_active(const uv_check_t* handle);
+int uv__idle_active(const uv_idle_t* handle);
+int uv__prepare_active(const uv_prepare_t* handle);
+int uv__timer_active(const uv_timer_t* handle);
+
+void uv__async_close(uv_async_t* handle);
+void uv__check_close(uv_check_t* handle);
+void uv__fs_event_close(uv_fs_event_t* handle);
+void uv__idle_close(uv_idle_t* handle);
+void uv__pipe_close(uv_pipe_t* handle);
+void uv__prepare_close(uv_prepare_t* handle);
+void uv__process_close(uv_process_t* handle);
+void uv__stream_close(uv_stream_t* handle);
+void uv__timer_close(uv_timer_t* handle);
+void uv__udp_close(uv_udp_t* handle);
 void uv__udp_finish_close(uv_udp_t* handle);
 
-/* fs */
-void uv__fs_event_destroy(uv_fs_event_t* handle);
-
 #define UV__F_IPC        (1 << 0)
 #define UV__F_NONBLOCK   (1 << 1)
 int uv__make_socketpair(int fds[2], int flags);
 int uv__make_pipe(int fds[2], int flags);
 
-#if __linux__
-void uv__inotify_loop_init(uv_loop_t* loop);
-void uv__inotify_loop_delete(uv_loop_t* loop);
-# define uv__loop_platform_init(loop)   uv__inotify_loop_init(loop)
-# define uv__loop_platform_delete(loop) uv__inotify_loop_delete(loop)
-#else
-# define uv__loop_platform_init(loop)
-# define uv__loop_platform_delete(loop)
-#endif
-
 #endif /* UV_UNIX_INTERNAL_H_ */
index 58988f9..1af2fbe 100644 (file)
@@ -26,8 +26,6 @@
 #include <string.h>
 #include <errno.h>
 
-#if HAVE_KQUEUE
-
 #include <sys/sysctl.h>
 #include <sys/types.h>
 #include <sys/event.h>
@@ -121,34 +119,9 @@ int uv_fs_event_init(uv_loop_t* loop,
 }
 
 
-void uv__fs_event_destroy(uv_fs_event_t* handle) {
+void uv__fs_event_close(uv_fs_event_t* handle) {
   uv__fs_event_stop(handle);
   free(handle->filename);
   close(handle->fd);
   handle->fd = -1;
 }
-
-#else /* !HAVE_KQUEUE */
-
-int uv_fs_event_init(uv_loop_t* loop,
-                     uv_fs_event_t* handle,
-                     const char* filename,
-                     uv_fs_event_cb cb,
-                     int flags) {
-  loop->counters.fs_event_init++;
-  uv__set_sys_error(loop, ENOSYS);
-  return -1;
-}
-
-
-void uv__fs_event_destroy(uv_fs_event_t* handle) {
-  UNREACHABLE();
-}
-
-
-/* Called by libev, don't touch. */
-void uv__kqueue_hack(EV_P_ int fflags, ev_io *w) {
-  UNREACHABLE();
-}
-
-#endif /* HAVE_KQUEUE */
index 9819f55..0414783 100644 (file)
@@ -21,6 +21,7 @@
 #include "uv.h"
 #include "tree.h"
 #include "../internal.h"
+#include "syscalls.h"
 
 #include <stdint.h>
 #include <stdio.h>
 
 #include <sys/types.h>
 #include <unistd.h>
-#include <fcntl.h>
-
-#undef HAVE_INOTIFY_INIT
-#undef HAVE_INOTIFY_INIT1
-#undef HAVE_INOTIFY_ADD_WATCH
-#undef HAVE_INOTIFY_RM_WATCH
-
-#if __NR_inotify_init
-# define HAVE_INOTIFY_INIT 1
-#endif
-#if __NR_inotify_init1
-# define HAVE_INOTIFY_INIT1 1
-#endif
-#if __NR_inotify_add_watch
-# define HAVE_INOTIFY_ADD_WATCH 1
-#endif
-#if __NR_inotify_rm_watch
-# define HAVE_INOTIFY_RM_WATCH 1
-#endif
-
-#if HAVE_INOTIFY_INIT || HAVE_INOTIFY_INIT1
-# undef IN_ACCESS
-# undef IN_MODIFY
-# undef IN_ATTRIB
-# undef IN_CLOSE_WRITE
-# undef IN_CLOSE_NOWRITE
-# undef IN_OPEN
-# undef IN_MOVED_FROM
-# undef IN_MOVED_TO
-# undef IN_CREATE
-# undef IN_DELETE
-# undef IN_DELETE_SELF
-# undef IN_MOVE_SELF
-# define IN_ACCESS         0x001
-# define IN_MODIFY         0x002
-# define IN_ATTRIB         0x004
-# define IN_CLOSE_WRITE    0x008
-# define IN_CLOSE_NOWRITE  0x010
-# define IN_OPEN           0x020
-# define IN_MOVED_FROM     0x040
-# define IN_MOVED_TO       0x080
-# define IN_CREATE         0x100
-# define IN_DELETE         0x200
-# define IN_DELETE_SELF    0x400
-# define IN_MOVE_SELF      0x800
-struct inotify_event {
-  int32_t wd;
-  uint32_t mask;
-  uint32_t cookie;
-  uint32_t len;
-  /* char name[0]; */
-};
-#endif /* HAVE_INOTIFY_INIT || HAVE_INOTIFY_INIT1 */
-
-#undef IN_CLOEXEC
-#undef IN_NONBLOCK
-
-#if HAVE_INOTIFY_INIT1
-# define IN_CLOEXEC O_CLOEXEC
-# define IN_NONBLOCK O_NONBLOCK
-#endif /* HAVE_INOTIFY_INIT1 */
-
-#if HAVE_INOTIFY_INIT
-inline static int inotify_init(void) {
-  return syscall(__NR_inotify_init);
-}
-#endif /* HAVE_INOTIFY_INIT */
-
-#if HAVE_INOTIFY_INIT1
-inline static int inotify_init1(int flags) {
-  return syscall(__NR_inotify_init1, flags);
-}
-#endif /* HAVE_INOTIFY_INIT1 */
-
-#if HAVE_INOTIFY_ADD_WATCH
-inline static int inotify_add_watch(int fd, const char* path, uint32_t mask) {
-  return syscall(__NR_inotify_add_watch, fd, path, mask);
-}
-#endif /* HAVE_INOTIFY_ADD_WATCH */
-
-#if HAVE_INOTIFY_RM_WATCH
-inline static int inotify_rm_watch(int fd, uint32_t wd) {
-  return syscall(__NR_inotify_rm_watch, fd, wd);
-}
-#endif /* HAVE_INOTIFY_RM_WATCH */
 
 
 /* Don't look aghast, this is exactly how glibc's basename() works. */
@@ -135,37 +51,19 @@ static int compare_watchers(const uv_fs_event_t* a, const uv_fs_event_t* b) {
 RB_GENERATE_STATIC(uv__inotify_watchers, uv_fs_event_s, node, compare_watchers)
 
 
-void uv__inotify_loop_init(uv_loop_t* loop) {
-  RB_INIT(&loop->inotify_watchers);
-  loop->inotify_fd = -1;
-}
-
-
-void uv__inotify_loop_delete(uv_loop_t* loop) {
-  if (loop->inotify_fd == -1) return;
-  ev_io_stop(loop->ev, &loop->inotify_read_watcher);
-  close(loop->inotify_fd);
-  loop->inotify_fd = -1;
-}
-
-
-#if HAVE_INOTIFY_INIT || HAVE_INOTIFY_INIT1
-
 static void uv__inotify_read(EV_P_ ev_io* w, int revents);
 
 
 static int new_inotify_fd(void) {
   int fd;
 
-#if HAVE_INOTIFY_INIT1
-  fd = inotify_init1(IN_NONBLOCK | IN_CLOEXEC);
+  fd = uv__inotify_init1(UV__IN_NONBLOCK | UV__IN_CLOEXEC);
   if (fd != -1)
     return fd;
   if (errno != ENOSYS)
     return -1;
-#endif
 
-  if ((fd = inotify_init()) == -1)
+  if ((fd = uv__inotify_init()) == -1)
     return -1;
 
   if (uv__cloexec(fd, 1) || uv__nonblock(fd, 1)) {
@@ -216,7 +114,7 @@ static void remove_watcher(uv_fs_event_t* handle) {
 
 
 static void uv__inotify_read(EV_P_ ev_io* w, int revents) {
-  const struct inotify_event* e;
+  const struct uv__inotify_event* e;
   uv_fs_event_t* handle;
   uv_loop_t* uv_loop;
   const char* filename;
@@ -243,12 +141,12 @@ static void uv__inotify_read(EV_P_ ev_io* w, int revents) {
 
     /* Now we have one or more inotify_event structs. */
     for (p = buf; p < buf + size; p += sizeof(*e) + e->len) {
-      e = (const struct inotify_event*)p;
+      e = (const struct uv__inotify_event*)p;
 
       events = 0;
-      if (e->mask & (IN_ATTRIB|IN_MODIFY))
+      if (e->mask & (UV__IN_ATTRIB|UV__IN_MODIFY))
         events |= UV_CHANGE;
-      if (e->mask & ~(IN_ATTRIB|IN_MODIFY))
+      if (e->mask & ~(UV__IN_ATTRIB|UV__IN_MODIFY))
         events |= UV_RENAME;
 
       handle = find_watcher(uv_loop, e->wd);
@@ -282,15 +180,15 @@ int uv_fs_event_init(uv_loop_t* loop,
 
   if (init_inotify(loop)) return -1;
 
-  events = IN_ATTRIB
-         | IN_CREATE
-         | IN_MODIFY
-         | IN_DELETE
-         | IN_DELETE_SELF
-         | IN_MOVED_FROM
-         | IN_MOVED_TO;
+  events = UV__IN_ATTRIB
+         | UV__IN_CREATE
+         | UV__IN_MODIFY
+         | UV__IN_DELETE
+         | UV__IN_DELETE_SELF
+         | UV__IN_MOVED_FROM
+         | UV__IN_MOVED_TO;
 
-  wd = inotify_add_watch(loop->inotify_fd, filename, events);
+  wd = uv__inotify_add_watch(loop->inotify_fd, filename, events);
   if (wd == -1) return uv__set_sys_error(loop, errno);
 
   uv__handle_init(loop, (uv_handle_t*)handle, UV_FS_EVENT);
@@ -303,30 +201,11 @@ int uv_fs_event_init(uv_loop_t* loop,
 }
 
 
-void uv__fs_event_destroy(uv_fs_event_t* handle) {
-  inotify_rm_watch(handle->loop->inotify_fd, handle->fd);
+void uv__fs_event_close(uv_fs_event_t* handle) {
+  uv__inotify_rm_watch(handle->loop->inotify_fd, handle->fd);
   remove_watcher(handle);
   handle->fd = -1;
 
   free(handle->filename);
   handle->filename = NULL;
 }
-
-#else /* !HAVE_INOTIFY_INIT || HAVE_INOTIFY_INIT1 */
-
-int uv_fs_event_init(uv_loop_t* loop,
-                     uv_fs_event_t* handle,
-                     const char* filename,
-                     uv_fs_event_cb cb,
-                     int flags) {
-  loop->counters.fs_event_init++;
-  uv__set_sys_error(loop, ENOSYS);
-  return -1;
-}
-
-
-void uv__fs_event_destroy(uv_fs_event_t* handle) {
-  UNREACHABLE();
-}
-
-#endif /* HAVE_INOTIFY_INIT || HAVE_INOTIFY_INIT1 */
diff --git a/deps/uv/src/unix/linux/syscalls.c b/deps/uv/src/unix/linux/syscalls.c
new file mode 100644 (file)
index 0000000..bdf90cf
--- /dev/null
@@ -0,0 +1,230 @@
+/* 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 "syscalls.h"
+#include <unistd.h>
+#include <sys/syscall.h>
+#include <sys/types.h>
+#include <errno.h>
+
+#if __i386__
+# ifndef __NR_socketcall
+#  define __NR_socketcall 102
+# endif
+#endif
+
+#if __arm__
+# if __thumb__ || __ARM_EABI__
+#  define UV_SYSCALL_BASE 0
+# else
+#  define UV_SYSCALL_BASE 0x900000
+# endif
+#endif /* __arm__ */
+
+#ifndef __NR_accept4
+# if __x86_64__
+#  define __NR_accept4 288
+# elif __i386__
+   /* Nothing. Handled through socketcall(). */
+# elif __arm__
+#  define __NR_accept4 (UV_SYSCALL_BASE + 366)
+# endif
+#endif /* __NR_accept4 */
+
+#ifndef __NR_inotify_init
+# if __x86_64__
+#  define __NR_inotify_init 253
+# elif __i386__
+#  define __NR_inotify_init 291
+# elif __arm__
+#  define __NR_inotify_init (UV_SYSCALL_BASE + 316)
+# endif
+#endif /* __NR_inotify_init */
+
+#ifndef __NR_inotify_init1
+# if __x86_64__
+#  define __NR_inotify_init1 294
+# elif __i386__
+#  define __NR_inotify_init1 332
+# elif __arm__
+#  define __NR_inotify_init1 (UV_SYSCALL_BASE + 360)
+# endif
+#endif /* __NR_inotify_init1 */
+
+#ifndef __NR_inotify_add_watch
+# if __x86_64__
+#  define __NR_inotify_add_watch 254
+# elif __i386__
+#  define __NR_inotify_add_watch 292
+# elif __arm__
+#  define __NR_inotify_add_watch (UV_SYSCALL_BASE + 317)
+# endif
+#endif /* __NR_inotify_add_watch */
+
+#ifndef __NR_inotify_rm_watch
+# if __x86_64__
+#  define __NR_inotify_rm_watch 255
+# elif __i386__
+#  define __NR_inotify_rm_watch 293
+# elif __arm__
+#  define __NR_inotify_rm_watch (UV_SYSCALL_BASE + 318)
+# endif
+#endif /* __NR_inotify_rm_watch */
+
+#ifndef __NR_pipe2
+# if __x86_64__
+#  define __NR_pipe2 293
+# elif __i386__
+#  define __NR_pipe2 331
+# elif __arm__
+#  define __NR_pipe2 (UV_SYSCALL_BASE + 359)
+# endif
+#endif /* __NR_pipe2 */
+
+#ifndef __NR_recvmmsg
+# if __x86_64__
+#  define __NR_recvmmsg 299
+# elif __i386__
+#  define __NR_recvmmsg 337
+# elif __arm__
+#  define __NR_recvmmsg (UV_SYSCALL_BASE + 365)
+# endif
+#endif /* __NR_recvmsg */
+
+#ifndef __NR_sendmmsg
+# if __x86_64__
+#  define __NR_sendmmsg 307
+# elif __i386__
+#  define __NR_sendmmsg 345
+# elif __arm__
+#  define __NR_recvmmsg (UV_SYSCALL_BASE + 374)
+# endif
+#endif /* __NR_sendmmsg */
+
+#ifndef __NR_utimensat
+# if __x86_64__
+#  define __NR_utimensat 280
+# elif __i386__
+#  define __NR_utimensat 320
+# elif __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__
+  unsigned long args[] = {
+    (unsigned long) fd,
+    (unsigned long) addr,
+    (unsigned long) addrlen,
+    (unsigned long) flags
+  };
+  return syscall(__NR_socketcall, 18 /* SYS_ACCEPT4 */, args);
+#elif __NR_accept4
+  return syscall(__NR_accept4, fd, addr, addrlen, flags);
+#else
+  return errno = ENOSYS, -1;
+#endif
+}
+
+
+int uv__inotify_init(void) {
+#if __NR_inotify_init
+  return syscall(__NR_inotify_init);
+#else
+  return errno = ENOSYS, -1;
+#endif
+}
+
+
+int uv__inotify_init1(int flags) {
+#if __NR_inotify_init1
+  return syscall(__NR_inotify_init1, flags);
+#else
+  return errno = ENOSYS, -1;
+#endif
+}
+
+
+int uv__inotify_add_watch(int fd, const char* path, __u32 mask) {
+#if __NR_inotify_add_watch
+  return syscall(__NR_inotify_add_watch, fd, path, mask);
+#else
+  return errno = ENOSYS, -1;
+#endif
+}
+
+
+int uv__inotify_rm_watch(int fd, __s32 wd) {
+#if __NR_inotify_rm_watch
+  return syscall(__NR_inotify_rm_watch, fd, wd);
+#else
+  return errno = ENOSYS, -1;
+#endif
+}
+
+
+int uv__pipe2(int pipefd[2], int flags) {
+#if __NR_pipe2
+  return syscall(__NR_pipe2, pipefd, flags);
+#else
+  return errno = ENOSYS, -1;
+#endif
+}
+
+
+int uv__sendmmsg(int fd,
+                 struct uv__mmsghdr* mmsg,
+                 unsigned int vlen,
+                 unsigned int flags) {
+#if __NR_sendmmsg
+  return syscall(__NR_sendmmsg, fd, mmsg, vlen, flags);
+#else
+  return errno = ENOSYS, -1;
+#endif
+}
+
+
+int uv__recvmmsg(int fd,
+                 struct uv__mmsghdr* mmsg,
+                 unsigned int vlen,
+                 unsigned int flags,
+                 struct timespec* timeout) {
+#if __NR_recvmmsg
+  return syscall(__NR_recvmmsg, fd, mmsg, vlen, flags, timeout);
+#else
+  return errno = ENOSYS, -1;
+#endif
+}
+
+
+int uv__utimesat(int dirfd,
+                 const char* path,
+                 const struct timespec times[2],
+                 int flags)
+{
+#if __NR_utimensat
+  return syscall(__NR_utimensat, dirfd, path, times, flags);
+#else
+  return errno = ENOSYS, -1;
+#endif
+}
diff --git a/deps/uv/src/unix/linux/syscalls.h b/deps/uv/src/unix/linux/syscalls.h
new file mode 100644 (file)
index 0000000..5d42044
--- /dev/null
@@ -0,0 +1,87 @@
+/* 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.
+ */
+
+#ifndef UV_LINUX_SYSCALL_H_
+#define UV_LINUX_SYSCALL_H_
+
+#undef  _GNU_SOURCE
+#define _GNU_SOURCE
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <linux/types.h>
+
+#define UV__O_NONBLOCK        0x800
+#define UV__O_CLOEXEC         0x80000
+
+#define UV__SOCK_CLOEXEC      UV__O_CLOEXEC
+#define UV__SOCK_NONBLOCK     UV__O_NONBLOCK
+
+#define UV__IN_CLOEXEC        UV__O_CLOEXEC
+#define UV__IN_NONBLOCK       UV__O_NONBLOCK
+
+#define UV__IN_ACCESS         0x001
+#define UV__IN_MODIFY         0x002
+#define UV__IN_ATTRIB         0x004
+#define UV__IN_CLOSE_WRITE    0x008
+#define UV__IN_CLOSE_NOWRITE  0x010
+#define UV__IN_OPEN           0x020
+#define UV__IN_MOVED_FROM     0x040
+#define UV__IN_MOVED_TO       0x080
+#define UV__IN_CREATE         0x100
+#define UV__IN_DELETE         0x200
+#define UV__IN_DELETE_SELF    0x400
+#define UV__IN_MOVE_SELF      0x800
+
+struct uv__inotify_event {
+  __s32 wd;
+  __u32 mask;
+  __u32 cookie;
+  __u32 len;
+  /* char name[0]; */
+};
+
+struct uv__mmsghdr {
+  struct msghdr msg_hdr;
+  unsigned int msg_len;
+};
+
+int uv__accept4(int fd, struct sockaddr* addr, socklen_t* addrlen, int flags);
+int uv__inotify_init(void);
+int uv__inotify_init1(int flags);
+int uv__inotify_add_watch(int fd, const char* path, __u32 mask);
+int uv__inotify_rm_watch(int fd, __s32 wd);
+int uv__pipe2(int pipefd[2], int flags);
+int uv__recvmmsg(int fd,
+                 struct uv__mmsghdr* mmsg,
+                 unsigned int vlen,
+                 unsigned int flags,
+                 struct timespec* timeout);
+int uv__sendmmsg(int fd,
+                 struct uv__mmsghdr* mmsg,
+                 unsigned int vlen,
+                 unsigned int flags);
+int uv__utimesat(int dirfd,
+                 const char* path,
+                 const struct timespec times[2],
+                 int flags);
+
+#endif /* UV_LINUX_SYSCALL_H_ */
diff --git a/deps/uv/src/unix/loop.c b/deps/uv/src/unix/loop.c
new file mode 100644 (file)
index 0000000..5580aba
--- /dev/null
@@ -0,0 +1,58 @@
+/* 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 "tree.h"
+#include "internal.h"
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+
+int uv__loop_init(uv_loop_t* loop, int default_loop) {
+#if HAVE_KQUEUE
+  int flags = EVBACKEND_KQUEUE;
+#else
+  int flags = EVFLAG_AUTO;
+#endif
+  RB_INIT(&loop->uv_ares_handles_);
+  loop->endgame_handles = NULL;
+  loop->ev = (default_loop ? ev_default_loop : ev_loop_new)(flags);
+  ev_set_userdata(loop->ev, loop);
+  eio_channel_init(&loop->uv_eio_channel, loop);
+#if __linux__
+  RB_INIT(&loop->inotify_watchers);
+  loop->inotify_fd = -1;
+#endif
+  return 0;
+}
+
+
+void uv__loop_delete(uv_loop_t* loop) {
+  uv_ares_destroy(loop, loop->channel);
+  ev_loop_destroy(loop->ev);
+#if __linux__
+  if (loop->inotify_fd == -1) return;
+  ev_io_stop(loop->ev, &loop->inotify_read_watcher);
+  close(loop->inotify_fd);
+  loop->inotify_fd = -1;
+#endif
+}
index 3573a57..d085304 100644 (file)
@@ -146,29 +146,19 @@ out:
 }
 
 
-int uv_pipe_cleanup(uv_pipe_t* handle) {
-  int saved_errno;
-  int status;
-
-  saved_errno = errno;
-  status = -1;
-
+void uv__pipe_close(uv_pipe_t* handle) {
   if (handle->pipe_fname) {
     /*
      * Unlink the file system entity before closing the file descriptor.
      * Doing it the other way around introduces a race where our process
      * unlinks a socket with the same name that's just been created by
      * another thread or process.
-     *
-     * This is less of an issue now that we attach a file lock
-     * to the socket but it's still a best practice.
      */
     unlink(handle->pipe_fname);
     free((void*)handle->pipe_fname);
   }
 
-  errno = saved_errno;
-  return status;
+  uv__stream_close((uv_stream_t*)handle);
 }
 
 
diff --git a/deps/uv/src/unix/prepare.c b/deps/uv/src/unix/prepare.c
new file mode 100644 (file)
index 0000000..6c18fbd
--- /dev/null
@@ -0,0 +1,79 @@
+/* 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 "internal.h"
+
+
+static void uv__prepare(EV_P_ ev_prepare* w, int revents) {
+  uv_prepare_t* prepare = container_of(w, uv_prepare_t, prepare_watcher);
+
+  if (prepare->prepare_cb) {
+    prepare->prepare_cb(prepare, 0);
+  }
+}
+
+
+int uv_prepare_init(uv_loop_t* loop, uv_prepare_t* prepare) {
+  uv__handle_init(loop, (uv_handle_t*)prepare, UV_PREPARE);
+  loop->counters.prepare_init++;
+
+  ev_prepare_init(&prepare->prepare_watcher, uv__prepare);
+  prepare->prepare_cb = NULL;
+
+  return 0;
+}
+
+
+int uv_prepare_start(uv_prepare_t* prepare, uv_prepare_cb cb) {
+  int was_active = ev_is_active(&prepare->prepare_watcher);
+
+  prepare->prepare_cb = cb;
+
+  ev_prepare_start(prepare->loop->ev, &prepare->prepare_watcher);
+
+  if (!was_active) {
+    ev_unref(prepare->loop->ev);
+  }
+
+  return 0;
+}
+
+
+int uv_prepare_stop(uv_prepare_t* prepare) {
+  int was_active = ev_is_active(&prepare->prepare_watcher);
+
+  ev_prepare_stop(prepare->loop->ev, &prepare->prepare_watcher);
+
+  if (was_active) {
+    ev_ref(prepare->loop->ev);
+  }
+  return 0;
+}
+
+
+int uv__prepare_active(const uv_prepare_t* handle) {
+  return ev_is_active(&handle->prepare_watcher);
+}
+
+
+void uv__prepare_close(uv_prepare_t* handle) {
+  uv_prepare_stop(handle);
+}
index ffe0145..9a5c76c 100644 (file)
@@ -105,7 +105,7 @@ int uv__make_socketpair(int fds[2], int flags) {
 
 
 int uv__make_pipe(int fds[2], int flags) {
-#if HAVE_SYS_PIPE2
+#if __linux__
   int fl;
 
   fl = O_CLOEXEC;
@@ -113,17 +113,11 @@ int uv__make_pipe(int fds[2], int flags) {
   if (flags & UV__F_NONBLOCK)
     fl |= O_NONBLOCK;
 
-  if (sys_pipe2(fds, fl) == 0)
+  if (uv__pipe2(fds, fl) == 0)
     return 0;
 
   if (errno != ENOSYS)
     return -1;
-
-  /* errno == ENOSYS so maybe the kernel headers lied about
-   * the availability of pipe2(). This can happen if people
-   * build libuv against newer kernel headers than the kernel
-   * they actually run the software on.
-   */
 #endif
 
   if (pipe(fds))
@@ -368,3 +362,8 @@ uv_err_t uv_kill(int pid, int signum) {
     return uv_ok_;
   }
 }
+
+
+void uv__process_close(uv_process_t* handle) {
+  ev_child_stop(handle->loop->ev, &handle->child_watcher);
+}
index fd24caa..ef71fc7 100644 (file)
@@ -1005,3 +1005,20 @@ int uv_is_readable(uv_stream_t* stream) {
 int uv_is_writable(uv_stream_t* stream) {
   return stream->flags & UV_WRITABLE;
 }
+
+
+void uv__stream_close(uv_stream_t* handle) {
+  uv_read_stop(handle);
+  ev_io_stop(handle->loop->ev, &handle->write_watcher);
+
+  close(handle->fd);
+  handle->fd = -1;
+
+  if (handle->accepted_fd >= 0) {
+    close(handle->accepted_fd);
+    handle->accepted_fd = -1;
+  }
+
+  assert(!ev_is_active(&handle->read_watcher));
+  assert(!ev_is_active(&handle->write_watcher));
+}
index 37fdd89..0057e68 100644 (file)
@@ -37,6 +37,7 @@
 #include <sys/time.h>
 #include <unistd.h>
 #include <kstat.h>
+#include <fcntl.h>
 
 #if HAVE_PORTS_FS
 # include <sys/port.h>
@@ -190,7 +191,7 @@ int uv_fs_event_init(uv_loop_t* loop,
 }
 
 
-void uv__fs_event_destroy(uv_fs_event_t* handle) {
+void uv__fs_event_close(uv_fs_event_t* handle) {
   ev_ref(handle->loop->ev);
   ev_io_stop(handle->loop->ev, &handle->event_watcher);
   close(handle->fd);
@@ -213,7 +214,7 @@ int uv_fs_event_init(uv_loop_t* loop,
 }
 
 
-void uv__fs_event_destroy(uv_fs_event_t* handle) {
+void uv__fs_event_close(uv_fs_event_t* handle) {
   UNREACHABLE();
 }
 
@@ -239,28 +240,24 @@ uv_err_t uv_get_process_title(char* buffer, size_t size) {
 
 
 uv_err_t uv_resident_set_memory(size_t* rss) {
-  pid_t pid = getpid();
   psinfo_t psinfo;
-  char pidpath[1024];
-  FILE *f;
+  uv_err_t err;
+  int fd;
 
-  sprintf(pidpath, "/proc/%d/psinfo", (int)pid);
-
-  f = fopen(pidpath, "r");
-  if (!f) return uv__new_sys_error(errno);
-
-  if (fread(&psinfo, sizeof(psinfo_t), 1, f) != 1) {
-    fclose (f);
+  fd = open("/proc/self/psinfo", O_RDONLY);
+  if (fd == -1)
     return uv__new_sys_error(errno);
-  }
 
-  /* XXX correct? */
+  err = uv_ok_;
 
-  *rss = (size_t) psinfo.pr_rssize * 1024;
+  if (read(fd, &psinfo, sizeof(psinfo)) == sizeof(psinfo))
+    *rss = (size_t)psinfo.pr_rssize * 1024;
+  else
+    err = uv__new_sys_error(EINVAL);
 
-  fclose (f);
+  close(fd);
 
-  return uv_ok_;
+  return err;
 }
 
 
diff --git a/deps/uv/src/unix/timer.c b/deps/uv/src/unix/timer.c
new file mode 100644 (file)
index 0000000..6a00229
--- /dev/null
@@ -0,0 +1,127 @@
+/* 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 "internal.h"
+#include <assert.h>
+
+
+static int uv__timer_repeating(const uv_timer_t* timer) {
+  return timer->flags & UV_TIMER_REPEAT;
+}
+
+
+static void uv__timer_cb(EV_P_ ev_timer* w, int revents) {
+  uv_timer_t* timer = container_of(w, uv_timer_t, timer_watcher);
+
+  assert(uv__timer_active(timer));
+
+  if (!uv__timer_repeating(timer)) {
+    timer->flags &= ~UV_TIMER_ACTIVE;
+    ev_ref(EV_A);
+  }
+
+  if (timer->timer_cb) {
+    timer->timer_cb(timer, 0);
+  }
+}
+
+
+int uv_timer_init(uv_loop_t* loop, uv_timer_t* timer) {
+  uv__handle_init(loop, (uv_handle_t*)timer, UV_TIMER);
+  loop->counters.timer_init++;
+
+  ev_init(&timer->timer_watcher, uv__timer_cb);
+
+  return 0;
+}
+
+
+int uv_timer_start(uv_timer_t* timer, uv_timer_cb cb, int64_t timeout,
+    int64_t repeat) {
+  if (uv__timer_active(timer)) {
+    return -1;
+  }
+
+  timer->timer_cb = cb;
+  timer->flags |= UV_TIMER_ACTIVE;
+
+  if (repeat)
+    timer->flags |= UV_TIMER_REPEAT;
+  else
+    timer->flags &= ~UV_TIMER_REPEAT;
+
+  ev_timer_set(&timer->timer_watcher, timeout / 1000.0, repeat / 1000.0);
+  ev_timer_start(timer->loop->ev, &timer->timer_watcher);
+  ev_unref(timer->loop->ev);
+
+  return 0;
+}
+
+
+int uv_timer_stop(uv_timer_t* timer) {
+  if (uv__timer_active(timer)) {
+    ev_ref(timer->loop->ev);
+  }
+
+  timer->flags &= ~(UV_TIMER_ACTIVE | UV_TIMER_REPEAT);
+  ev_timer_stop(timer->loop->ev, &timer->timer_watcher);
+
+  return 0;
+}
+
+
+int uv_timer_again(uv_timer_t* timer) {
+  if (!uv__timer_active(timer)) {
+    uv__set_artificial_error(timer->loop, UV_EINVAL);
+    return -1;
+  }
+
+  assert(uv__timer_repeating(timer));
+  ev_timer_again(timer->loop->ev, &timer->timer_watcher);
+  return 0;
+}
+
+
+void uv_timer_set_repeat(uv_timer_t* timer, int64_t repeat) {
+  assert(timer->type == UV_TIMER);
+  timer->timer_watcher.repeat = repeat / 1000.0;
+
+  if (repeat)
+    timer->flags |= UV_TIMER_REPEAT;
+  else
+    timer->flags &= ~UV_TIMER_REPEAT;
+}
+
+
+int64_t uv_timer_get_repeat(uv_timer_t* timer) {
+  assert(timer->type == UV_TIMER);
+  return (int64_t)(1000 * timer->timer_watcher.repeat);
+}
+
+
+int uv__timer_active(const uv_timer_t* timer) {
+  return timer->flags & UV_TIMER_ACTIVE;
+}
+
+
+void uv__timer_close(uv_timer_t* handle) {
+  uv_timer_stop(handle);
+}
index e1c7621..9c84cef 100644 (file)
@@ -85,7 +85,7 @@ static void uv__udp_stop_write_watcher(uv_udp_t* handle) {
 }
 
 
-void uv__udp_start_close(uv_udp_t* handle) {
+void uv__udp_close(uv_udp_t* handle) {
   uv__udp_stop_write_watcher(handle);
   uv__udp_stop_read_watcher(handle);
   close(handle->fd);
index 2e424a9..c8192bd 100644 (file)
 #include "ares/inet_net_pton.h"
 #include "ares/inet_ntop.h"
 
+#define XX(uc, lc) case UV_##uc: return sizeof(uv_##lc##_t);
+
+size_t uv_handle_size(uv_handle_type type) {
+  switch (type) {
+    UV_HANDLE_TYPE_MAP(XX)
+    default:
+      return -1;
+  }
+}
+
+size_t uv_req_size(uv_req_type type) {
+  switch(type) {
+    UV_REQ_TYPE_MAP(XX)
+    default:
+      return -1;
+  }
+}
+
+#undef XX
 
 size_t uv_strlcpy(char* dst, const char* src, size_t size) {
   size_t n;
index e1f16b6..e82f584 100644 (file)
 
 struct uv_ares_task_s {
   UV_HANDLE_FIELDS
-  UV_ARES_TASK_PRIVATE_FIELDS
+#if _WIN32
+  struct uv_req_s ares_req;
+  SOCKET sock;
+  HANDLE h_wait;
+  WSAEVENT h_event;
+  HANDLE h_close_event;
+#else
+  int sock;
+  ev_io read_watcher;
+  ev_io write_watcher;
+#endif
   RB_ENTRY(uv_ares_task_s) node;
 };
 
index 2e053b0..d19492c 100644 (file)
@@ -154,6 +154,11 @@ void uv_close(uv_handle_t* handle, uv_close_cb cb) {
 }
 
 
+int uv_is_closing(uv_handle_t* handle) {
+  return handle->flags & (UV_HANDLE_CLOSING | UV_HANDLE_CLOSED);
+}
+
+
 void uv_want_endgame(uv_loop_t* loop, uv_handle_t* handle) {
   if (!(handle->flags & UV_HANDLE_ENDGAME_QUEUED)) {
     handle->flags |= UV_HANDLE_ENDGAME_QUEUED;
index 470aed1..d79aa3d 100644 (file)
@@ -150,6 +150,8 @@ int uv_tcp_import(uv_tcp_t* tcp, WSAPROTOCOL_INFOW* socket_protocol_info,
 int uv_tcp_duplicate_socket(uv_tcp_t* handle, int pid,
     LPWSAPROTOCOL_INFOW protocol_info);
 
+void uv_tcp_close(uv_tcp_t* tcp);
+
 
 /*
  * UDP
index 21409ed..51ef604 100644 (file)
@@ -252,10 +252,9 @@ static int uv__bind(uv_tcp_t* handle,
                     int addrsize) {
   DWORD err;
   int r;
-  SOCKET sock;
 
   if (handle->socket == INVALID_SOCKET) {
-    sock = socket(domain, SOCK_STREAM, 0);
+    SOCKET sock = socket(domain, SOCK_STREAM, 0);
     if (sock == INVALID_SOCKET) {
       uv__set_sys_error(handle->loop, WSAGetLastError());
       return -1;
index 1964401..81523c3 100644 (file)
@@ -163,7 +163,6 @@ static int uv__bind(uv_udp_t* handle,
                     int addrsize,
                     unsigned int flags) {
   int r;
-  SOCKET sock;
   DWORD no = 0, yes = 1;
 
   if ((flags & UV_UDP_IPV6ONLY) && domain != AF_INET6) {
@@ -173,7 +172,7 @@ static int uv__bind(uv_udp_t* handle,
   }
 
   if (handle->socket == INVALID_SOCKET) {
-    sock = socket(domain, SOCK_DGRAM, 0);
+    SOCKET sock = socket(domain, SOCK_DGRAM, 0);
     if (sock == INVALID_SOCKET) {
       uv__set_sys_error(handle->loop, WSAGetLastError());
       return -1;
@@ -192,14 +191,14 @@ static int uv__bind(uv_udp_t* handle,
     /* TODO: how to handle errors? This may fail if there is no ipv4 stack */
     /* available, or when run on XP/2003 which have no support for dualstack */
     /* sockets. For now we're silently ignoring the error. */
-    setsockopt(sock,
+    setsockopt(handle->socket,
                IPPROTO_IPV6,
                IPV6_V6ONLY,
                (char*) &no,
                sizeof no);
   }
 
-  r = setsockopt(sock,
+  r = setsockopt(handle->socket,
                  SOL_SOCKET,
                  SO_REUSEADDR,
                  (char*) &yes,
index 9f731ec..68b14fb 100644 (file)
@@ -385,8 +385,70 @@ uv_err_t uv_resident_set_memory(size_t* rss) {
 
 
 uv_err_t uv_uptime(double* uptime) {
-  *uptime = (double)GetTickCount()/1000.0;
-  return uv_ok_;
+  uv_err_t err;
+  PERF_DATA_BLOCK *dataBlock = NULL;
+  PERF_OBJECT_TYPE *objType;
+  PERF_COUNTER_DEFINITION *counterDef;
+  PERF_COUNTER_DEFINITION *counterDefUptime = NULL;
+  DWORD dataSize = 4096;
+  DWORD getSize;
+  LONG lError = ERROR_MORE_DATA;
+  uint64_t upsec;
+  unsigned int i;
+  BYTE *counterData;
+
+  *uptime = 0;
+  
+  while (lError == ERROR_MORE_DATA) {
+    if (dataBlock) {
+      free(dataBlock);
+    }
+    dataBlock = (PERF_DATA_BLOCK*)malloc(dataSize);
+    if (!dataBlock) {
+      uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
+    }
+    getSize = dataSize;
+
+    lError = RegQueryValueExW(HKEY_PERFORMANCE_DATA, "2", NULL, NULL,
+                             (BYTE*)dataBlock, &getSize);
+    if (lError != ERROR_SUCCESS && getSize > 0) {
+      if (wcsncmp(dataBlock->Signature, "PERF", 4) == 0) {
+        break;
+      }
+    } else if (lError != ERROR_SUCCESS && lError != ERROR_MORE_DATA) {
+      err = uv__new_sys_error(GetLastError());
+      goto done;
+    }
+
+    dataSize += 1024;
+  }
+
+  RegCloseKey(HKEY_PERFORMANCE_DATA);
+
+  objType = (PERF_OBJECT_TYPE*)((BYTE*)dataBlock + dataBlock->HeaderLength);
+  counterDef = (PERF_COUNTER_DEFINITION*)((BYTE*)objType + objType->HeaderLength);
+
+  for (i = 0; i < objType->NumCounters; ++i) {
+    if (counterDef->CounterNameTitleIndex == 674) {
+      counterDefUptime = counterDef;
+      break;
+    }
+    counterDef = (PERF_COUNTER_DEFINITION*)((BYTE*)counterDef + counterDef->ByteLength);
+  }
+
+  counterData = (BYTE*)objType + objType->DefinitionLength;
+  counterData += counterDefUptime->CounterOffset;
+
+  upsec = *((uint64_t*)counterData);
+  *uptime = ((objType->PerfTime.QuadPart - upsec) / objType->PerfFreq.QuadPart);
+  err = uv_ok_;
+
+done:
+  if (dataBlock) {
+    free(dataBlock);
+  }
+
+  return err;
 }
 
 
index 96b47f0..970bf1e 100644 (file)
@@ -197,6 +197,7 @@ int ipc_send_recv_helper(void) {
   uv_pipe_open(&ctx.channel, 0);
   ASSERT(uv_is_readable((uv_stream_t*)&ctx.channel));
   ASSERT(uv_is_writable((uv_stream_t*)&ctx.channel));
+  ASSERT(!uv_is_closing((uv_handle_t*)&ctx.channel));
 
   r = uv_read2_start((uv_stream_t*)&ctx.channel, alloc_cb, read2_cb);
   ASSERT(r == 0);
index d70d5b2..1ea0e7f 100644 (file)
@@ -535,6 +535,7 @@ int ipc_helper(int listen_after_write) {
 
   ASSERT(uv_is_readable((uv_stream_t*) &channel));
   ASSERT(uv_is_writable((uv_stream_t*) &channel));
+  ASSERT(!uv_is_closing((uv_handle_t*) &channel));
 
   r = uv_tcp_init(uv_default_loop(), &tcp_server);
   ASSERT(r == 0);
@@ -583,6 +584,7 @@ int ipc_helper_tcp_connection() {
 
   ASSERT(uv_is_readable((uv_stream_t*)&channel));
   ASSERT(uv_is_writable((uv_stream_t*)&channel));
+  ASSERT(!uv_is_closing((uv_handle_t*)&channel));
 
   r = uv_tcp_init(uv_default_loop(), &tcp_server);
   ASSERT(r == 0);
index 245a601..1bdcc3b 100644 (file)
@@ -140,6 +140,7 @@ static void pinger_on_connect(uv_connect_t *req, int status) {
 
   ASSERT(uv_is_readable(req->handle));
   ASSERT(uv_is_writable(req->handle));
+  ASSERT(!uv_is_closing((uv_handle_t *)req->handle));
 
   pinger_write_ping(pinger);
 
index 4a6c511..cc06d42 100644 (file)
@@ -93,4 +93,4 @@ TEST_IMPL(pipe_connect_to_file) {
   ASSERT(connect_cb_called == 1);
 
   return 0;
-}
\ No newline at end of file
+}
index 1e17729..fe7b306 100644 (file)
@@ -44,6 +44,7 @@ TEST_IMPL(platform_output) {
 
   err = uv_uptime(&uptime);
   ASSERT(UV_OK == err.code);
+  ASSERT(uptime > 0);
   fprintf(stderr, "uv_uptime: %f\n", uptime);
 
   err = uv_cpu_info(&cpus, &count);
index 864f7ce..eabbefc 100644 (file)
@@ -57,7 +57,9 @@ static void connect_cb(uv_connect_t* req, int status) {
 
   r = uv_shutdown(&shutdown_req, req->handle, shutdown_cb);
   ASSERT(r == 0);
+  ASSERT(!uv_is_closing((uv_handle_t*) req->handle));
   uv_close((uv_handle_t*) req->handle, close_cb);
+  ASSERT(uv_is_closing((uv_handle_t*) req->handle));
 
   connect_cb_called++;
 }
index 0d6e3b9..d03ea56 100644 (file)
             'include/uv-private/ev.h',
             'include/uv-private/ngx-queue.h',
             'include/uv-private/uv-unix.h',
-            'src/unix/core.c',
-            'src/unix/uv-eio.c',
-            'src/unix/uv-eio.h',
-            'src/unix/fs.c',
-            'src/unix/udp.c',
-            'src/unix/tcp.c',
-            'src/unix/pipe.c',
-            'src/unix/tty.c',
-            'src/unix/stream.c',
+            'src/unix/async.c',
             'src/unix/cares.c',
+            'src/unix/check.c',
+            'src/unix/core.c',
             'src/unix/dl.c',
-            'src/unix/error.c',
-            'src/unix/thread.c',
-            'src/unix/process.c',
-            'src/unix/internal.h',
             'src/unix/eio/ecb.h',
             'src/unix/eio/eio.c',
             'src/unix/eio/xthread.h',
+            'src/unix/error.c',
             'src/unix/ev/ev.c',
             'src/unix/ev/ev_vars.h',
             'src/unix/ev/ev_wrap.h',
             'src/unix/ev/event.h',
+            'src/unix/fs.c',
+            'src/unix/idle.c',
+            'src/unix/internal.h',
+            'src/unix/loop.c',
+            'src/unix/pipe.c',
+            'src/unix/prepare.c',
+            'src/unix/process.c',
+            'src/unix/stream.c',
+            'src/unix/tcp.c',
+            'src/unix/thread.c',
+            'src/unix/timer.c',
+            'src/unix/tty.c',
+            'src/unix/udp.c',
+            'src/unix/uv-eio.c',
+            'src/unix/uv-eio.h',
           ],
           'include_dirs': [ 'src/unix/ev', ],
           'libraries': [ '-lm' ]
             ],
           },
           'defines': [
+            '_DARWIN_USE_64_BIT_INODE=1',
             'EV_CONFIG_H="config_darwin.h"',
             'EIO_CONFIG_H="config_darwin.h"',
           ]
           'sources': [
             'src/unix/linux/core.c',
             'src/unix/linux/inotify.c',
+            'src/unix/linux/syscalls.c',
+            'src/unix/linux/syscalls.h',
           ],
           'defines': [
             'EV_CONFIG_H="config_linux.h"',