upgrade libuv to cb70db1
authorRyan Dahl <ry@tinyclouds.org>
Fri, 16 Dec 2011 21:35:08 +0000 (13:35 -0800)
committerRyan Dahl <ry@tinyclouds.org>
Fri, 16 Dec 2011 21:35:08 +0000 (13:35 -0800)
deps/uv/.travis.yml [new file with mode: 0644]
deps/uv/src/unix/linux.c
deps/uv/src/win/pipe.c
deps/uv/src/win/tcp.c
deps/uv/test/benchmark-thread.c [new file with mode: 0644]
deps/uv/test/test-counters-init.c [new file with mode: 0644]
deps/uv/test/test-platform-output.c [new file with mode: 0644]
deps/uv/test/test-process-title.c [new file with mode: 0644]
deps/uv/test/test-run-once.c [new file with mode: 0644]
deps/uv/test/test-thread.c [new file with mode: 0644]
deps/uv/test/test-util.c [new file with mode: 0644]

diff --git a/deps/uv/.travis.yml b/deps/uv/.travis.yml
new file mode 100644 (file)
index 0000000..f3b176f
--- /dev/null
@@ -0,0 +1,9 @@
+language: node_js
+
+script:
+  - "make test"
+
+notifications:
+  email: false
+  irc:
+    - "irc.freenode.net#libuv"
index d841c49..17e0674 100644 (file)
 
 #include <ifaddrs.h>
 #include <net/if.h>
-#include <sys/inotify.h>
 #include <sys/param.h>
 #include <sys/sysinfo.h>
 #include <unistd.h>
+#include <fcntl.h>
 #include <time.h>
 
 #undef NANOSEC
 #define NANOSEC 1000000000
 
+#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 */
+
 
 static char buf[MAXPATHLEN + 1];
 
@@ -65,6 +149,7 @@ uint64_t uv_hrtime() {
   return (ts.tv_sec * NANOSEC + ts.tv_nsec);
 }
 
+
 void uv_loadavg(double avg[3]) {
   struct sysinfo info;
 
@@ -87,141 +172,16 @@ int uv_exepath(char* buffer, size_t* size) {
   return 0;
 }
 
+
 uint64_t uv_get_free_memory(void) {
   return (uint64_t) sysconf(_SC_PAGESIZE) * sysconf(_SC_AVPHYS_PAGES);
 }
 
+
 uint64_t uv_get_total_memory(void) {
   return (uint64_t) sysconf(_SC_PAGESIZE) * sysconf(_SC_PHYS_PAGES);
 }
 
-static int new_inotify_fd(void) {
-#if defined(IN_NONBLOCK) && defined(IN_CLOEXEC)
-  return inotify_init1(IN_NONBLOCK | IN_CLOEXEC);
-#else
-  int fd;
-
-  if ((fd = inotify_init()) == -1)
-    return -1;
-
-  if (uv__cloexec(fd, 1) || uv__nonblock(fd, 1)) {
-    SAVE_ERRNO(uv__close(fd));
-    fd = -1;
-  }
-
-  return fd;
-#endif
-}
-
-
-static void uv__inotify_read(EV_P_ ev_io* w, int revents) {
-  struct inotify_event* e;
-  uv_fs_event_t* handle;
-  const char* filename;
-  ssize_t size;
-  int events;
-  char *p;
-  /* needs to be large enough for sizeof(inotify_event) + strlen(filename) */
-  char buf[4096];
-
-  handle = container_of(w, uv_fs_event_t, read_watcher);
-
-  do {
-    do {
-      size = read(handle->fd, buf, sizeof buf);
-    }
-    while (size == -1 && errno == EINTR);
-
-    if (size == -1) {
-      assert(errno == EAGAIN || errno == EWOULDBLOCK);
-      break;
-    }
-
-    assert(size > 0); /* pre-2.6.21 thing, size=0 == read buffer too small */
-
-    /* Now we have one or more inotify_event structs. */
-    for (p = buf; p < buf + size; p += sizeof(*e) + e->len) {
-      e = (void*)p;
-
-      events = 0;
-      if (e->mask & (IN_ATTRIB|IN_MODIFY))
-        events |= UV_CHANGE;
-      if (e->mask & ~(IN_ATTRIB|IN_MODIFY))
-        events |= UV_RENAME;
-
-      /* inotify does not return the filename when monitoring a single file
-       * for modifications. Repurpose the filename for API compatibility.
-       * I'm not convinced this is a good thing, maybe it should go.
-       */
-      filename = e->len ? e->name : basename_r(handle->filename);
-
-      handle->cb(handle, filename, events, 0);
-
-      if (handle->fd == -1)
-        break;
-    }
-  }
-  while (handle->fd != -1); /* handle might've been closed by callback */
-}
-
-
-int uv_fs_event_init(uv_loop_t* loop,
-                     uv_fs_event_t* handle,
-                     const char* filename,
-                     uv_fs_event_cb cb,
-                     int flags) {
-  int events;
-  int fd;
-
-  loop->counters.fs_event_init++;
-
-  /* We don't support any flags yet. */
-  assert(!flags);
-
-  /*
-   * TODO share a single inotify fd across the event loop?
-   * We'll run into fs.inotify.max_user_instances if we
-   * keep creating new inotify fds.
-   */
-  if ((fd = new_inotify_fd()) == -1) {
-    uv__set_sys_error(loop, errno);
-    return -1;
-  }
-
-  events = IN_ATTRIB
-         | IN_CREATE
-         | IN_MODIFY
-         | IN_DELETE
-         | IN_DELETE_SELF
-         | IN_MOVED_FROM
-         | IN_MOVED_TO;
-
-  if (inotify_add_watch(fd, filename, events) == -1) {
-    uv__set_sys_error(loop, errno);
-    uv__close(fd);
-    return -1;
-  }
-
-  uv__handle_init(loop, (uv_handle_t*)handle, UV_FS_EVENT);
-  handle->filename = strdup(filename); /* this should go! */
-  handle->cb = cb;
-  handle->fd = fd;
-
-  ev_io_init(&handle->read_watcher, uv__inotify_read, fd, EV_READ);
-  ev_io_start(loop->ev, &handle->read_watcher);
-
-  return 0;
-}
-
-
-void uv__fs_event_destroy(uv_fs_event_t* handle) {
-  ev_io_stop(handle->loop->ev, &handle->read_watcher);
-  uv__close(handle->fd);
-  handle->fd = -1;
-  free(handle->filename);
-  handle->filename = NULL;
-}
-
 
 char** uv_setup_args(int argc, char** argv) {
   char **new_argv;
@@ -294,6 +254,7 @@ uv_err_t uv_resident_set_memory(size_t* rss) {
   FILE* f;
   int itmp;
   char ctmp;
+  unsigned int utmp;
   size_t page_size = getpagesize();
   char *cbuf;
   int foundExeEnd;
@@ -331,15 +292,15 @@ uv_err_t uv_resident_set_memory(size_t* rss) {
   /* TTY owner process group */
   if (fscanf (f, "%d ", &itmp) == 0) goto error; /* coverity[secure_coding] */
   /* Flags */
-  if (fscanf (f, "%u ", &itmp) == 0) goto error; /* coverity[secure_coding] */
+  if (fscanf (f, "%u ", &utmp) == 0) goto error; /* coverity[secure_coding] */
   /* Minor faults (no memory page) */
-  if (fscanf (f, "%u ", &itmp) == 0) goto error; /* coverity[secure_coding] */
+  if (fscanf (f, "%u ", &utmp) == 0) goto error; /* coverity[secure_coding] */
   /* Minor faults, children */
-  if (fscanf (f, "%u ", &itmp) == 0) goto error; /* coverity[secure_coding] */
+  if (fscanf (f, "%u ", &utmp) == 0) goto error; /* coverity[secure_coding] */
   /* Major faults (memory page faults) */
-  if (fscanf (f, "%u ", &itmp) == 0) goto error; /* coverity[secure_coding] */
+  if (fscanf (f, "%u ", &utmp) == 0) goto error; /* coverity[secure_coding] */
   /* Major faults, children */
-  if (fscanf (f, "%u ", &itmp) == 0) goto error; /* coverity[secure_coding] */
+  if (fscanf (f, "%u ", &utmp) == 0) goto error; /* coverity[secure_coding] */
   /* utime */
   if (fscanf (f, "%d ", &itmp) == 0) goto error; /* coverity[secure_coding] */
   /* stime */
@@ -353,27 +314,27 @@ uv_err_t uv_resident_set_memory(size_t* rss) {
   /* 'nice' value */
   if (fscanf (f, "%d ", &itmp) == 0) goto error; /* coverity[secure_coding] */
   /* jiffies until next timeout */
-  if (fscanf (f, "%u ", &itmp) == 0) goto error; /* coverity[secure_coding] */
+  if (fscanf (f, "%u ", &utmp) == 0) goto error; /* coverity[secure_coding] */
   /* jiffies until next SIGALRM */
-  if (fscanf (f, "%u ", &itmp) == 0) goto error; /* coverity[secure_coding] */
+  if (fscanf (f, "%u ", &utmp) == 0) goto error; /* coverity[secure_coding] */
   /* start time (jiffies since system boot) */
   if (fscanf (f, "%d ", &itmp) == 0) goto error; /* coverity[secure_coding] */
 
   /* Virtual memory size */
-  if (fscanf (f, "%u ", &itmp) == 0) goto error; /* coverity[secure_coding] */
+  if (fscanf (f, "%u ", &utmp) == 0) goto error; /* coverity[secure_coding] */
 
   /* Resident set size */
-  if (fscanf (f, "%u ", &itmp) == 0) goto error; /* coverity[secure_coding] */
-  *rss = (size_t) itmp * page_size;
+  if (fscanf (f, "%u ", &utmp) == 0) goto error; /* coverity[secure_coding] */
+  *rss = (size_t) utmp * page_size;
 
   /* rlim */
-  if (fscanf (f, "%u ", &itmp) == 0) goto error; /* coverity[secure_coding] */
+  if (fscanf (f, "%u ", &utmp) == 0) goto error; /* coverity[secure_coding] */
   /* Start of text */
-  if (fscanf (f, "%u ", &itmp) == 0) goto error; /* coverity[secure_coding] */
+  if (fscanf (f, "%u ", &utmp) == 0) goto error; /* coverity[secure_coding] */
   /* End of text */
-  if (fscanf (f, "%u ", &itmp) == 0) goto error; /* coverity[secure_coding] */
+  if (fscanf (f, "%u ", &utmp) == 0) goto error; /* coverity[secure_coding] */
   /* Start of stack */
-  if (fscanf (f, "%u ", &itmp) == 0) goto error; /* coverity[secure_coding] */
+  if (fscanf (f, "%u ", &utmp) == 0) goto error; /* coverity[secure_coding] */
 
   fclose (f);
   return uv_ok_;
@@ -408,7 +369,7 @@ uv_err_t uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
   unsigned int ticks = (unsigned int)sysconf(_SC_CLK_TCK),
                multiplier = ((uint64_t)1000L / ticks), cpuspeed;
   int numcpus = 0, i = 0;
-  unsigned long long ticks_user, ticks_sys, ticks_idle, ticks_nice, ticks_intr;
+  unsigned long ticks_user, ticks_sys, ticks_idle, ticks_nice, ticks_intr;
   char line[512], speedPath[256], model[512];
   FILE *fpStat = fopen("/proc/stat", "r");
   FILE *fpModel = fopen("/proc/cpuinfo", "r");
@@ -450,7 +411,7 @@ uv_err_t uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
         break;
       }
 
-      sscanf(line, "%*s %llu %llu %llu %llu %*llu %llu",
+      sscanf(line, "%*s %lu %lu %lu %lu %*s %lu",
              &ticks_user, &ticks_nice, &ticks_sys, &ticks_idle, &ticks_intr);
       snprintf(speedPath, sizeof(speedPath),
                "/sys/devices/system/cpu/cpu%u/cpufreq/cpuinfo_max_freq", i);
@@ -572,3 +533,152 @@ void uv_free_interface_addresses(uv_interface_address_t* addresses,
 
   free(addresses);
 }
+
+#if HAVE_INOTIFY_INIT || HAVE_INOTIFY_INIT1
+
+static int new_inotify_fd(void) {
+#if HAVE_INOTIFY_INIT1
+  return inotify_init1(IN_NONBLOCK | IN_CLOEXEC);
+#else
+  int fd;
+
+  if ((fd = inotify_init()) == -1)
+    return -1;
+
+  if (uv__cloexec(fd, 1) || uv__nonblock(fd, 1)) {
+    SAVE_ERRNO(uv__close(fd));
+    fd = -1;
+  }
+
+  return fd;
+#endif
+}
+
+
+static void uv__inotify_read(EV_P_ ev_io* w, int revents) {
+  struct inotify_event* e;
+  uv_fs_event_t* handle;
+  const char* filename;
+  ssize_t size;
+  int events;
+  char *p;
+  /* needs to be large enough for sizeof(inotify_event) + strlen(filename) */
+  char buf[4096];
+
+  handle = container_of(w, uv_fs_event_t, read_watcher);
+
+  do {
+    do {
+      size = read(handle->fd, buf, sizeof buf);
+    }
+    while (size == -1 && errno == EINTR);
+
+    if (size == -1) {
+      assert(errno == EAGAIN || errno == EWOULDBLOCK);
+      break;
+    }
+
+    assert(size > 0); /* pre-2.6.21 thing, size=0 == read buffer too small */
+
+    /* Now we have one or more inotify_event structs. */
+    for (p = buf; p < buf + size; p += sizeof(*e) + e->len) {
+      e = (void*)p;
+
+      events = 0;
+      if (e->mask & (IN_ATTRIB|IN_MODIFY))
+        events |= UV_CHANGE;
+      if (e->mask & ~(IN_ATTRIB|IN_MODIFY))
+        events |= UV_RENAME;
+
+      /* inotify does not return the filename when monitoring a single file
+       * for modifications. Repurpose the filename for API compatibility.
+       * I'm not convinced this is a good thing, maybe it should go.
+       */
+      filename = e->len ? (const char*) (e + 1) : basename_r(handle->filename);
+
+      handle->cb(handle, filename, events, 0);
+
+      if (handle->fd == -1)
+        break;
+    }
+  }
+  while (handle->fd != -1); /* handle might've been closed by callback */
+}
+
+
+int uv_fs_event_init(uv_loop_t* loop,
+                     uv_fs_event_t* handle,
+                     const char* filename,
+                     uv_fs_event_cb cb,
+                     int flags) {
+  int events;
+  int fd;
+
+  loop->counters.fs_event_init++;
+
+  /* We don't support any flags yet. */
+  assert(!flags);
+
+  /*
+   * TODO share a single inotify fd across the event loop?
+   * We'll run into fs.inotify.max_user_instances if we
+   * keep creating new inotify fds.
+   */
+  if ((fd = new_inotify_fd()) == -1) {
+    uv__set_sys_error(loop, errno);
+    return -1;
+  }
+
+  events = IN_ATTRIB
+         | IN_CREATE
+         | IN_MODIFY
+         | IN_DELETE
+         | IN_DELETE_SELF
+         | IN_MOVED_FROM
+         | IN_MOVED_TO;
+
+  if (inotify_add_watch(fd, filename, events) == -1) {
+    uv__set_sys_error(loop, errno);
+    uv__close(fd);
+    return -1;
+  }
+
+  uv__handle_init(loop, (uv_handle_t*)handle, UV_FS_EVENT);
+  handle->filename = strdup(filename); /* this should go! */
+  handle->cb = cb;
+  handle->fd = fd;
+
+  ev_io_init(&handle->read_watcher, uv__inotify_read, fd, EV_READ);
+  ev_io_start(loop->ev, &handle->read_watcher);
+
+  return 0;
+}
+
+
+void uv__fs_event_destroy(uv_fs_event_t* handle) {
+  ev_io_stop(handle->loop->ev, &handle->read_watcher);
+  uv__close(handle->fd);
+  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) {
+  assert(0 && "unreachable");
+  abort();
+}
+
+#endif /* HAVE_INOTIFY_INIT || HAVE_INOTIFY_INIT1 */
index 3bbfa83..5c20fe4 100644 (file)
@@ -1047,7 +1047,7 @@ static int uv_pipe_write_impl(uv_loop_t* loop, uv_write_t* req,
         ipc_header_req = (uv_write_t*)&handle->ipc_header_write_req;
       } else {
         ipc_header_req = (uv_write_t*)malloc(sizeof(uv_write_t));
-        if (!handle->accept_reqs) {
+        if (!ipc_header_req) {
           uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
         }
       }
index dee7787..7965f73 100644 (file)
@@ -822,7 +822,8 @@ void uv_process_tcp_read_req(uv_loop_t* loop, uv_tcp_t* handle,
 
   if (!REQ_SUCCESS(req)) {
     /* An error occurred doing the read. */
-    if ((handle->flags & UV_HANDLE_READING)) {
+    if ((handle->flags & UV_HANDLE_READING) ||
+        !(handle->flags & UV_HANDLE_ZERO_READ)) {
       handle->flags &= ~UV_HANDLE_READING;
       buf = (handle->flags & UV_HANDLE_ZERO_READ) ?
             uv_buf_init(NULL, 0) : handle->read_buffer;
diff --git a/deps/uv/test/benchmark-thread.c b/deps/uv/test/benchmark-thread.c
new file mode 100644 (file)
index 0000000..cc7fd93
--- /dev/null
@@ -0,0 +1,64 @@
+/* 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 NUM_THREADS (100 * 1000)
+
+static volatile int num_threads;
+
+
+static void thread_entry(void* arg) {
+  ASSERT(arg == (void *) 42);
+  num_threads++;
+  /* FIXME write barrier? */
+}
+
+
+BENCHMARK_IMPL(thread_create) {
+  uint64_t start_time;
+  double duration;
+  uv_thread_t tid;
+  int i, r;
+
+  start_time = uv_hrtime();
+
+  for (i = 0; i < NUM_THREADS; i++) {
+    r = uv_thread_create(&tid, thread_entry, (void *) 42);
+    ASSERT(r == 0);
+
+    r = uv_thread_join(&tid);
+    ASSERT(r == 0);
+  }
+
+  duration = (uv_hrtime() - start_time) / 1e9;
+
+  ASSERT(num_threads == NUM_THREADS);
+
+  printf("%d threads created in %.2f seconds (%.0f/s)\n",
+      NUM_THREADS, duration, NUM_THREADS / duration);
+
+  return 0;
+}
diff --git a/deps/uv/test/test-counters-init.c b/deps/uv/test/test-counters-init.c
new file mode 100644 (file)
index 0000000..423d349
--- /dev/null
@@ -0,0 +1,216 @@
+/* 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.
+ */
+#define UNIX (defined(__unix__) || defined(__POSIX__) || defined(__APPLE__))
+#include "task.h"
+#include "uv.h"
+#include <fcntl.h>
+
+#if UNIX
+#include <unistd.h> /* unlink, rmdir, etc. */
+#else
+# include <direct.h>
+# include <io.h>
+# define unlink _unlink
+# define rmdir _rmdir
+# define stat _stati64
+# define open _open
+# define write _write
+# define lseek _lseek
+# define close _close
+#endif
+
+static char exepath[1024];
+static size_t exepath_size = 1024;
+static char* args[3];
+static uv_fs_t open_req;
+static uv_tcp_t tcp;
+static uv_udp_t udp;
+static uv_pipe_t uvpipe;
+static uv_tty_t tty;
+static uv_prepare_t prepare;
+static uv_check_t check;
+static uv_idle_t idle;
+static uv_async_t async;
+static uv_timer_t timer;
+static uv_fs_event_t fs_event;
+static uv_process_t process;
+static uv_process_options_t options;
+static uv_fs_t fs_req;
+
+static void exit_cb(uv_process_t* process, int exit_status, int term_signal) {
+  ASSERT(exit_status == 1);
+  ASSERT(term_signal == 0);
+  uv_close((uv_handle_t*)process, NULL);
+}
+
+static void init_process_options(char* test, uv_exit_cb exit_cb) {
+  int r = uv_exepath(exepath, &exepath_size);
+  ASSERT(r == 0);
+  exepath[exepath_size] = '\0';
+  args[0] = exepath;
+  args[1] = test;
+  args[2] = NULL;
+  options.file = exepath;
+  options.args = args;
+  options.exit_cb = exit_cb;
+}
+
+static void create_dir(uv_loop_t* loop, const char* name) {
+  int r;
+  uv_fs_t req;
+  r = uv_fs_rmdir(loop, &req, name, NULL);
+  r = uv_fs_mkdir(loop, &req, name, 0755, NULL);
+  ASSERT(r == 0);
+  uv_fs_req_cleanup(&req);
+}
+
+static void create_cb(uv_fs_t* req) {
+  ASSERT(req == &open_req);
+  ASSERT(req->fs_type == UV_FS_OPEN);
+  ASSERT(req->result != -1);
+  uv_fs_req_cleanup(req);
+  unlink("test_file");
+}
+
+TEST_IMPL(counters_init) {
+  int r;
+  int eio_init_prev;
+  int req_init_prev;
+  int handle_init_prev;
+  int stream_init_prev;
+  int tcp_init_prev;
+  int udp_init_prev;
+  int pipe_init_prev;
+  int tty_init_prev;
+  int prepare_init_prev;
+  int check_init_prev;
+  int idle_init_prev;
+  int async_init_prev;
+  int timer_init_prev;
+  int process_init_prev;
+  int fs_event_init_prev;
+
+  /* req_init and eio_init test by uv_fs_open() */
+  unlink("test_file");
+  req_init_prev = uv_default_loop()->counters.req_init;
+  eio_init_prev = uv_default_loop()->counters.eio_init;
+  r = uv_fs_open(uv_default_loop(), &open_req, "test_file", O_WRONLY | O_CREAT,
+                 S_IREAD | S_IWRITE, create_cb);
+  ASSERT(r == 0);
+  ASSERT(open_req.result == 0);
+  ASSERT(uv_default_loop()->counters.req_init == ++req_init_prev);
+#ifndef _WIN32
+  ASSERT(uv_default_loop()->counters.eio_init == ++eio_init_prev);
+#endif
+
+  /* tcp_init, stream_init and handle_init test by uv_tcp_init() */
+  tcp_init_prev = uv_default_loop()->counters.tcp_init;
+  stream_init_prev = uv_default_loop()->counters.stream_init;
+  handle_init_prev = uv_default_loop()->counters.handle_init;
+  r = uv_tcp_init(uv_default_loop(), &tcp);
+  ASSERT(r == 0);
+  ASSERT(uv_default_loop()->counters.tcp_init == ++tcp_init_prev);
+  ASSERT(uv_default_loop()->counters.stream_init == ++stream_init_prev);
+  ASSERT(uv_default_loop()->counters.handle_init == ++handle_init_prev);
+  uv_close((uv_handle_t*)&tcp, NULL);
+
+  /* udp_init test by uv_udp_init() */
+  udp_init_prev = uv_default_loop()->counters.udp_init;
+  r = uv_udp_init(uv_default_loop(), &udp);
+  ASSERT(r == 0);
+  ASSERT(uv_default_loop()->counters.udp_init == ++udp_init_prev);
+  uv_close((uv_handle_t*)&udp, NULL);
+
+  /* pipe_init uv_pipe_init() */
+  pipe_init_prev = uv_default_loop()->counters.pipe_init;
+  uv_pipe_init(uv_default_loop(), &uvpipe, 0);
+  ASSERT(r == 0);
+  ASSERT(uv_default_loop()->counters.pipe_init == ++pipe_init_prev);
+  uv_close((uv_handle_t*)&uvpipe, NULL);
+
+  /* tty_init test by uv_tty_init()*/
+  tty_init_prev = uv_default_loop()->counters.tty_init;
+  r = uv_tty_init(uv_default_loop(), &tty, 1, 0);
+  /* uv_tty_init() always returns -1 in run_test in Windows
+     so that we avoid to check return value.
+   */
+#ifndef _WIN32
+  ASSERT(r == 0);
+  uv_close((uv_handle_t*)&tty, NULL);
+#endif
+  ASSERT(uv_default_loop()->counters.tty_init == ++tty_init_prev);
+
+  /* prepare_init test by uv_prepare_init() */
+  prepare_init_prev = uv_default_loop()->counters.prepare_init;
+  r = uv_prepare_init(uv_default_loop(), &prepare);
+  ASSERT(r == 0);
+  ASSERT(uv_default_loop()->counters.prepare_init == ++prepare_init_prev);
+  uv_close((uv_handle_t*)&prepare, NULL);
+
+  /* check_init test by uv_check_init() */
+  check_init_prev = uv_default_loop()->counters.check_init;
+  r = uv_check_init(uv_default_loop(), &check);
+  ASSERT(r == 0);
+  ASSERT(uv_default_loop()->counters.check_init == ++check_init_prev);
+  uv_close((uv_handle_t*)&check, NULL);
+
+  /* idle_init test by uv_idle_init() */
+  idle_init_prev = uv_default_loop()->counters.idle_init;
+  r = uv_idle_init(uv_default_loop(), &idle);
+  ASSERT(r == 0);
+  ASSERT(uv_default_loop()->counters.idle_init == ++idle_init_prev);
+  uv_close((uv_handle_t*)&idle, NULL);
+
+  /* async_init test by uv_async_init() */
+  async_init_prev = uv_default_loop()->counters.async_init;
+  r = uv_async_init(uv_default_loop(), &async, NULL);
+  ASSERT(r == 0);
+  ASSERT(uv_default_loop()->counters.async_init == ++async_init_prev);
+  uv_close((uv_handle_t*)&async, NULL);
+
+  /* timer_init test by uv_timer_init() */
+  timer_init_prev = uv_default_loop()->counters.timer_init;
+  r = uv_timer_init(uv_default_loop(), &timer);
+  ASSERT(r == 0);
+  ASSERT(uv_default_loop()->counters.timer_init == ++timer_init_prev);
+  uv_close((uv_handle_t*)&timer, NULL);
+
+  /* process_init test by uv_spawn() */
+  process_init_prev = uv_default_loop()->counters.process_init;
+  init_process_options("spawn_helper1", exit_cb);
+  r = uv_spawn(uv_default_loop(), &process, options);
+  ASSERT(r == 0);
+  ASSERT(uv_default_loop()->counters.process_init == ++process_init_prev);
+  r = uv_run(uv_default_loop());
+  ASSERT(r == 0);
+
+  /* fs_event_init test by uv_fs_event_init() */
+  create_dir(uv_default_loop(), "watch_dir");
+  fs_event_init_prev = uv_default_loop()->counters.fs_event_init;
+  r = uv_fs_event_init(uv_default_loop(), &fs_event, "watch_dir", NULL, 0);
+  ASSERT(r == 0);
+  ASSERT(uv_default_loop()->counters.fs_event_init == ++fs_event_init_prev);
+  r = uv_fs_rmdir(uv_default_loop(), &fs_req, "watch_dir", NULL);
+  ASSERT(r == 0);
+  uv_fs_req_cleanup(&fs_req);
+
+  return 0;
+}
diff --git a/deps/uv/test/test-platform-output.c b/deps/uv/test/test-platform-output.c
new file mode 100644 (file)
index 0000000..99c0551
--- /dev/null
@@ -0,0 +1,83 @@
+/* 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 <string.h>
+
+
+TEST_IMPL(platform_output) {
+  char buffer[512];
+  size_t rss;
+  double uptime;
+  uv_cpu_info_t* cpus;
+  uv_interface_address_t* interfaces;
+  int count;
+  int i;
+  uv_err_t err;
+
+  err = uv_get_process_title(buffer, sizeof(buffer));
+  ASSERT(UV_OK == err.code);
+  fprintf(stderr, "uv_get_process_title: %s\n", buffer);
+
+  err = uv_resident_set_memory(&rss);
+  ASSERT(UV_OK == err.code);
+  fprintf(stderr, "uv_resident_set_memory: %d\n", rss);
+
+  err = uv_uptime(&uptime);
+  ASSERT(UV_OK == err.code);
+  fprintf(stderr, "uv_uptime: %f\n", uptime);
+
+  err = uv_cpu_info(&cpus, &count);
+  ASSERT(UV_OK == err.code);
+
+  fprintf(stderr, "uv_cpu_info:\n");
+  for (i = 0; i < count; i++) {
+    fprintf(stderr, "  model: %s\n", cpus[i].model);
+    fprintf(stderr, "  speed: %d\n", cpus[i].speed);
+    fprintf(stderr, "  times.sys: %llu\n", cpus[i].cpu_times.sys);
+    fprintf(stderr, "  times.user: %llu\n", cpus[i].cpu_times.user);
+    fprintf(stderr, "  times.idle: %llu\n", cpus[i].cpu_times.idle);
+    fprintf(stderr, "  times.irq: %llu\n", cpus[i].cpu_times.irq);
+    fprintf(stderr, "  times.nice: %llu\n", cpus[i].cpu_times.nice);
+  }
+  uv_free_cpu_info(cpus, count);
+
+  err = uv_interface_addresses(&interfaces, &count);
+  ASSERT(UV_OK == err.code);
+
+  fprintf(stderr, "uv_interface_addresses:\n");
+  for (i = 0; i < count; i++) {
+    fprintf(stderr, "  name: %s\n", interfaces[i].name);
+    fprintf(stderr, "  internal: %d\n", interfaces[i].is_internal);
+
+    if (interfaces[i].address.address4.sin_family == AF_INET) {
+      uv_ip4_name(&interfaces[i].address.address4, buffer, sizeof(buffer));
+    } else if (interfaces[i].address.address4.sin_family == AF_INET6) {
+      uv_ip6_name(&interfaces[i].address.address6, buffer, sizeof(buffer));
+    }
+
+    fprintf(stderr, "  address: %s\n", buffer);
+  }
+  uv_free_interface_addresses(interfaces, count);
+
+  return 0;
+}
diff --git a/deps/uv/test/test-process-title.c b/deps/uv/test/test-process-title.c
new file mode 100644 (file)
index 0000000..59fceda
--- /dev/null
@@ -0,0 +1,42 @@
+/* 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 <string.h>
+
+TEST_IMPL(process_title) {
+  char buffer[512];
+  uv_err_t err;
+
+  err = uv_get_process_title(buffer, sizeof(buffer));
+  ASSERT(UV_OK == err.code);
+
+  err = uv_set_process_title("new title");
+  ASSERT(UV_OK == err.code);
+
+  err = uv_get_process_title(buffer, sizeof(buffer));
+  ASSERT(UV_OK == err.code);
+
+  ASSERT(strcmp(buffer, "new title") == 0);
+
+  return 0;
+}
diff --git a/deps/uv/test/test-run-once.c b/deps/uv/test/test-run-once.c
new file mode 100644 (file)
index 0000000..c03ab88
--- /dev/null
@@ -0,0 +1,44 @@
+/* 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 idle_counter = 0;
+
+static void idle_cb(uv_idle_t* handle, int status) {
+  ASSERT(handle != NULL);
+  ASSERT(status == 0);
+  idle_counter ++;
+}
+
+
+TEST_IMPL(run_once) {
+  int n;
+  uv_idle_t h;
+  uv_idle_init(uv_default_loop(), &h);
+  uv_idle_start(&h, idle_cb);
+  for (n = 0; n < 500; n++) {
+    uv_run_once(uv_default_loop());
+  }
+  ASSERT(n == 500);
+  return 0;
+}
diff --git a/deps/uv/test/test-thread.c b/deps/uv/test/test-thread.c
new file mode 100644 (file)
index 0000000..61aa55a
--- /dev/null
@@ -0,0 +1,51 @@
+/* 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>
+
+
+static volatile int thread_called;
+
+
+static void thread_entry(void* arg) {
+  ASSERT(arg == (void *) 42);
+  thread_called++;
+}
+
+
+TEST_IMPL(thread_create) {
+  uv_thread_t tid;
+  int r;
+
+  r = uv_thread_create(&tid, thread_entry, (void *) 42);
+  ASSERT(r == 0);
+
+  r = uv_thread_join(&tid);
+  ASSERT(r == 0);
+
+  ASSERT(thread_called == 1);
+
+  return 0;
+}
diff --git a/deps/uv/test/test-util.c b/deps/uv/test/test-util.c
new file mode 100644 (file)
index 0000000..d61d3b1
--- /dev/null
@@ -0,0 +1,97 @@
+/* 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 <string.h>
+
+#define memeq(a, b, c) (memcmp((a), (b), (c)) == 0)
+
+
+TEST_IMPL(strlcpy) {
+  size_t r;
+
+  {
+    char dst[2] = "A";
+    r = uv_strlcpy(dst, "", 0);
+    ASSERT(r == 0);
+    ASSERT(memeq(dst, "A", 1));
+  }
+
+  {
+    char dst[2] = "A";
+    r = uv_strlcpy(dst, "B", 1);
+    ASSERT(r == 0);
+    ASSERT(memeq(dst, "", 1));
+  }
+
+  {
+    char dst[2] = "A";
+    r = uv_strlcpy(dst, "B", 2);
+    ASSERT(r == 1);
+    ASSERT(memeq(dst, "B", 2));
+  }
+
+  {
+    char dst[3] = "AB";
+    r = uv_strlcpy(dst, "CD", 3);
+    ASSERT(r == 2);
+    ASSERT(memeq(dst, "CD", 3));
+  }
+
+  return 0;
+}
+
+
+TEST_IMPL(strlcat) {
+  size_t r;
+
+  {
+    char dst[2] = "A";
+    r = uv_strlcat(dst, "B", 1);
+    ASSERT(r == 1);
+    ASSERT(memeq(dst, "A", 2));
+  }
+
+  {
+    char dst[2] = "A";
+    r = uv_strlcat(dst, "B", 2);
+    ASSERT(r == 1);
+    ASSERT(memeq(dst, "A", 2));
+  }
+
+  {
+    char dst[3] = "A";
+    r = uv_strlcat(dst, "B", 3);
+    ASSERT(r == 2);
+    ASSERT(memeq(dst, "AB", 3));
+  }
+
+  {
+    char dst[5] = "AB";
+    r = uv_strlcat(dst, "CD", 5);
+    ASSERT(r == 4);
+    ASSERT(memeq(dst, "ABCD", 5));
+  }
+
+  return 0;
+}