Skip to content
This repository
Browse code

deps: upgrade libuv to 1f9bd99

  • Loading branch information...
commit dd1b9477063e39c5d916ebb602947340442d4d50 1 parent 2c97da8
Ben Noordhuis authored September 13, 2012
3  deps/uv/README.md
Source Rendered
@@ -77,6 +77,9 @@ Macintosh users run
77 77
     ./gyp_uv -f xcode
78 78
     xcodebuild -project uv.xcodeproj -configuration Release -target All
79 79
 
  80
+Note for Linux users: compile your project with `-D_GNU_SOURCE` when you
  81
+include `uv.h`. GYP builds take care of that automatically. If you use
  82
+autotools, add a `AC_GNU_SOURCE` declaration to your `configure.ac`.
80 83
 
81 84
 ## Supported Platforms
82 85
 
3  deps/uv/config-unix.mk
@@ -60,6 +60,7 @@ CPPFLAGS += -D_DARWIN_USE_64_BIT_INODE=1
60 60
 LINKFLAGS+=-framework CoreServices
61 61
 OBJS += src/unix/darwin.o
62 62
 OBJS += src/unix/kqueue.o
  63
+OBJS += src/unix/fsevents.o
63 64
 endif
64 65
 
65 66
 ifeq (Linux,$(uname_S))
@@ -91,7 +92,7 @@ endif
91 92
 ifeq (NetBSD,$(uname_S))
92 93
 EV_CONFIG=config_netbsd.h
93 94
 EIO_CONFIG=config_netbsd.h
94  
-LINKFLAGS+=
  95
+LINKFLAGS+=-lkvm
95 96
 OBJS += src/unix/netbsd.o
96 97
 OBJS += src/unix/kqueue.o
97 98
 endif
8  deps/uv/gyp_uv
@@ -60,9 +60,11 @@ if __name__ == '__main__':
60 60
 
61 61
   # There's a bug with windows which doesn't allow this feature.
62 62
   if sys.platform != 'win32':
63  
-    args.extend(['--generator-output', output_dir])
64  
-    args.extend(['-Goutput_dir=' + output_dir])
65  
-    args.extend('-f make'.split())
  63
+    if '-f' not in args:
  64
+      args.extend('-f make'.split())
  65
+    if 'ninja' not in args:
  66
+      args.extend(['-Goutput_dir=' + output_dir])
  67
+      args.extend(['--generator-output', output_dir])
66 68
     (major, minor), is_clang = compiler_version()
67 69
     args.append('-Dgcc_version=%d' % (10 * major + minor))
68 70
     args.append('-Dclang=%d' % int(is_clang))
13  deps/uv/include/uv-private/uv-darwin.h
@@ -29,10 +29,23 @@
29 29
 # define UV_PLATFORM_SEM_T semaphore_t
30 30
 #endif
31 31
 
  32
+#define UV_PLATFORM_LOOP_FIELDS                                               \
  33
+  uv_thread_t cf_thread;                                                      \
  34
+  void* cf_cb;                                                                \
  35
+  void* cf_loop;                                                              \
  36
+  uv_mutex_t cf_mutex;                                                        \
  37
+  uv_sem_t cf_sem;                                                            \
  38
+  ngx_queue_t cf_signals;                                                     \
  39
+
32 40
 #define UV_PLATFORM_FS_EVENT_FIELDS                                           \
33 41
   ev_io event_watcher;                                                        \
34 42
   int fflags;                                                                 \
35 43
   int fd;                                                                     \
  44
+  void* cf_eventstream;                                                       \
  45
+  uv_async_t* cf_cb;                                                          \
  46
+  ngx_queue_t cf_events;                                                      \
  47
+  uv_sem_t cf_sem;                                                            \
  48
+  uv_mutex_t cf_mutex;                                                        \
36 49
 
37 50
 #define UV_STREAM_PRIVATE_PLATFORM_FIELDS                                     \
38 51
   void* select;                                                               \
1  deps/uv/include/uv-private/uv-unix.h
@@ -137,6 +137,7 @@ typedef struct {
137 137
   uint64_t time;                                                              \
138 138
   void* signal_ctx;                                                           \
139 139
   uv_signal_t child_watcher;                                                  \
  140
+  int emfile_fd;                                                              \
140 141
   UV_PLATFORM_LOOP_FIELDS                                                     \
141 142
 
142 143
 #define UV_REQ_TYPE_PRIVATE /* empty */
1  deps/uv/include/uv.h
@@ -1789,6 +1789,7 @@ UV_EXTERN void uv_once(uv_once_t* guard, void (*callback)(void));
1789 1789
 
1790 1790
 UV_EXTERN int uv_thread_create(uv_thread_t *tid,
1791 1791
     void (*entry)(void *arg), void *arg);
  1792
+UV_EXTERN unsigned long uv_thread_self(void);
1792 1793
 UV_EXTERN int uv_thread_join(uv_thread_t *tid);
1793 1794
 
1794 1795
 /* the presence of these unions force similar struct layout */
2  deps/uv/src/unix/async.c
@@ -31,7 +31,7 @@ static void uv__async_io(uv_loop_t* loop, uv__io_t* handle, int events);
31 31
 
32 32
 
33 33
 __attribute__((always_inline))
34  
-inline static int uv__async_make_pending(volatile sig_atomic_t* ptr) {
  34
+static int uv__async_make_pending(volatile sig_atomic_t* ptr) {
35 35
   /* Do a cheap read first. */
36 36
   if (*ptr)
37 37
     return 1;
2  deps/uv/src/unix/core.c
@@ -463,7 +463,7 @@ int uv__accept(int sockfd) {
463 463
 
464 464
   while (1) {
465 465
 #if __linux__
466  
-    static __read_mostly int no_accept4;
  466
+    static int no_accept4;
467 467
 
468 468
     if (no_accept4)
469 469
       goto skip;
124  deps/uv/src/unix/darwin.c
@@ -43,13 +43,137 @@
43 43
 
44 44
 static char *process_title;
45 45
 
  46
+/* Forward declarations */
  47
+void uv__cf_loop_runner(void* arg);
  48
+void uv__cf_loop_cb(void* arg);
  49
+
  50
+typedef struct uv__cf_loop_signal_s uv__cf_loop_signal_t;
  51
+struct uv__cf_loop_signal_s {
  52
+  void* arg;
  53
+  cf_loop_signal_cb cb;
  54
+  ngx_queue_t member;
  55
+};
  56
+
46 57
 
47 58
 int uv__platform_loop_init(uv_loop_t* loop, int default_loop) {
  59
+  CFRunLoopSourceContext ctx;
  60
+  int r;
  61
+
  62
+  loop->cf_loop = NULL;
  63
+  if ((r = uv_mutex_init(&loop->cf_mutex)))
  64
+    return r;
  65
+  if ((r = uv_sem_init(&loop->cf_sem, 0)))
  66
+    return r;
  67
+  ngx_queue_init(&loop->cf_signals);
  68
+
  69
+  memset(&ctx, 0, sizeof(ctx));
  70
+  ctx.info = loop;
  71
+  ctx.perform = uv__cf_loop_cb;
  72
+  loop->cf_cb = CFRunLoopSourceCreate(NULL, 0, &ctx);
  73
+
  74
+  if ((r = uv_thread_create(&loop->cf_thread, uv__cf_loop_runner, loop)))
  75
+    return r;
  76
+
  77
+  /* Synchronize threads */
  78
+  uv_sem_wait(&loop->cf_sem);
  79
+  assert(((volatile CFRunLoopRef) loop->cf_loop) != NULL);
  80
+
48 81
   return 0;
49 82
 }
50 83
 
51 84
 
52 85
 void uv__platform_loop_delete(uv_loop_t* loop) {
  86
+  ngx_queue_t* item;
  87
+  uv__cf_loop_signal_t* s;
  88
+
  89
+  assert(loop->cf_loop != NULL);
  90
+  CFRunLoopStop(loop->cf_loop);
  91
+  uv_thread_join(&loop->cf_thread);
  92
+  loop->cf_loop = NULL;
  93
+
  94
+  uv_sem_destroy(&loop->cf_sem);
  95
+  uv_mutex_destroy(&loop->cf_mutex);
  96
+
  97
+  /* Free any remaining data */
  98
+  while (!ngx_queue_empty(&loop->cf_signals)) {
  99
+    item = ngx_queue_head(&loop->cf_signals);
  100
+
  101
+    s = ngx_queue_data(item, uv__cf_loop_signal_t, member);
  102
+
  103
+    ngx_queue_remove(item);
  104
+    free(s);
  105
+  }
  106
+}
  107
+
  108
+
  109
+void uv__cf_loop_runner(void* arg) {
  110
+  uv_loop_t* loop;
  111
+
  112
+  loop = arg;
  113
+
  114
+  /* Get thread's loop */
  115
+  *((volatile CFRunLoopRef*)&loop->cf_loop) = CFRunLoopGetCurrent();
  116
+
  117
+  CFRunLoopAddSource(loop->cf_loop,
  118
+                     loop->cf_cb,
  119
+                     kCFRunLoopDefaultMode);
  120
+
  121
+  uv_sem_post(&loop->cf_sem);
  122
+
  123
+  CFRunLoopRun();
  124
+
  125
+  CFRunLoopRemoveSource(loop->cf_loop,
  126
+                        loop->cf_cb,
  127
+                        kCFRunLoopDefaultMode);
  128
+}
  129
+
  130
+
  131
+void uv__cf_loop_cb(void* arg) {
  132
+  uv_loop_t* loop;
  133
+  ngx_queue_t* item;
  134
+  ngx_queue_t split_head;
  135
+  uv__cf_loop_signal_t* s;
  136
+
  137
+  loop = arg;
  138
+
  139
+  uv_mutex_lock(&loop->cf_mutex);
  140
+  ngx_queue_init(&split_head);
  141
+  if (!ngx_queue_empty(&loop->cf_signals)) {
  142
+    ngx_queue_t* split_pos = ngx_queue_next(&loop->cf_signals);
  143
+    ngx_queue_split(&loop->cf_signals, split_pos, &split_head);
  144
+  }
  145
+  uv_mutex_unlock(&loop->cf_mutex);
  146
+
  147
+  while (!ngx_queue_empty(&split_head)) {
  148
+    item = ngx_queue_head(&split_head);
  149
+
  150
+    s = ngx_queue_data(item, uv__cf_loop_signal_t, member);
  151
+    s->cb(s->arg);
  152
+
  153
+    ngx_queue_remove(item);
  154
+    free(s);
  155
+  }
  156
+}
  157
+
  158
+
  159
+void uv__cf_loop_signal(uv_loop_t* loop, cf_loop_signal_cb cb, void* arg) {
  160
+  uv__cf_loop_signal_t* item;
  161
+
  162
+  item = malloc(sizeof(*item));
  163
+  /* XXX: Fail */
  164
+  if (item == NULL)
  165
+    abort();
  166
+
  167
+  item->arg = arg;
  168
+  item->cb = cb;
  169
+
  170
+  uv_mutex_lock(&loop->cf_mutex);
  171
+  ngx_queue_insert_tail(&loop->cf_signals, &item->member);
  172
+  uv_mutex_unlock(&loop->cf_mutex);
  173
+
  174
+  assert(loop->cf_loop != NULL);
  175
+  CFRunLoopSourceSignal(loop->cf_cb);
  176
+  CFRunLoopWakeUp(loop->cf_loop);
53 177
 }
54 178
 
55 179
 
225  deps/uv/src/unix/fsevents.c
... ...
@@ -0,0 +1,225 @@
  1
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
  2
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
  3
+ * of this software and associated documentation files (the "Software"), to
  4
+ * deal in the Software without restriction, including without limitation the
  5
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  6
+ * sell copies of the Software, and to permit persons to whom the Software is
  7
+ * furnished to do so, subject to the following conditions:
  8
+ *
  9
+ * The above copyright notice and this permission notice shall be included in
  10
+ * all copies or substantial portions of the Software.
  11
+ *
  12
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  13
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  14
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  15
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  16
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  17
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  18
+ * IN THE SOFTWARE.
  19
+ */
  20
+
  21
+#include "uv.h"
  22
+#include "internal.h"
  23
+
  24
+#include <assert.h>
  25
+#include <stdlib.h>
  26
+#include <CoreServices/CoreServices.h>
  27
+
  28
+typedef struct uv__fsevents_event_s uv__fsevents_event_t;
  29
+
  30
+struct uv__fsevents_event_s {
  31
+  int events;
  32
+  ngx_queue_t member;
  33
+  char path[1];
  34
+};
  35
+
  36
+
  37
+#define UV__FSEVENTS_WALK(handle, block)                                      \
  38
+    {                                                                         \
  39
+      ngx_queue_t* curr;                                                      \
  40
+      ngx_queue_t split_head;                                                 \
  41
+      uv__fsevents_event_t* event;                                            \
  42
+      uv_mutex_lock(&(handle)->cf_mutex);                                     \
  43
+      ngx_queue_init(&split_head);                                            \
  44
+      if (!ngx_queue_empty(&(handle)->cf_events)) {                           \
  45
+        ngx_queue_t* split_pos = ngx_queue_next(&(handle)->cf_events);        \
  46
+        ngx_queue_split(&(handle)->cf_events, split_pos, &split_head);        \
  47
+      }                                                                       \
  48
+      uv_mutex_unlock(&(handle)->cf_mutex);                                   \
  49
+      while (!ngx_queue_empty(&split_head)) {                                 \
  50
+        curr = ngx_queue_head(&split_head);                                   \
  51
+        /* Invoke callback */                                                 \
  52
+        event = ngx_queue_data(curr, uv__fsevents_event_t, member);           \
  53
+        ngx_queue_remove(curr);                                               \
  54
+        /* Invoke block code, but only if handle wasn't closed */             \
  55
+        if (((handle)->flags & (UV_CLOSING | UV_CLOSED)) == 0)                \
  56
+          block                                                               \
  57
+        /* Free allocated data */                                             \
  58
+        free(event);                                                          \
  59
+      }                                                                       \
  60
+    }
  61
+
  62
+
  63
+void uv__fsevents_cb(uv_async_t* cb, int status) {
  64
+  uv_fs_event_t* handle;
  65
+
  66
+  handle = cb->data;
  67
+
  68
+  UV__FSEVENTS_WALK(handle, {
  69
+    if (handle->fd != -1)
  70
+      handle->cb(handle, event->path, event->events, 0);
  71
+  })
  72
+
  73
+  if ((handle->flags & (UV_CLOSING | UV_CLOSED)) == 0 && handle->fd == -1)
  74
+    uv__fsevents_close(handle);
  75
+}
  76
+
  77
+
  78
+void uv__fsevents_event_cb(ConstFSEventStreamRef streamRef,
  79
+                           void* info,
  80
+                           size_t numEvents,
  81
+                           void* eventPaths,
  82
+                           const FSEventStreamEventFlags eventFlags[],
  83
+                           const FSEventStreamEventId eventIds[]) {
  84
+  size_t i;
  85
+  int len;
  86
+  char** paths;
  87
+  uv_fs_event_t* handle;
  88
+  uv__fsevents_event_t* event;
  89
+  ngx_queue_t add_list;
  90
+
  91
+  handle = info;
  92
+  paths = eventPaths;
  93
+  ngx_queue_init(&add_list);
  94
+
  95
+  for (i = 0; i < numEvents; i++) {
  96
+    /* Ignore system events */
  97
+    if (eventFlags[i] & (kFSEventStreamEventFlagUserDropped |
  98
+                         kFSEventStreamEventFlagKernelDropped |
  99
+                         kFSEventStreamEventFlagEventIdsWrapped |
  100
+                         kFSEventStreamEventFlagHistoryDone |
  101
+                         kFSEventStreamEventFlagMount |
  102
+                         kFSEventStreamEventFlagUnmount)) {
  103
+      continue;
  104
+    }
  105
+
  106
+    /* TODO: Report errors */
  107
+    len = strlen(paths[i]);
  108
+    event = malloc(sizeof(*event) + len);
  109
+    if (event == NULL)
  110
+      break;
  111
+
  112
+    memcpy(event->path, paths[i], len + 1);
  113
+
  114
+    if (eventFlags[i] & kFSEventStreamEventFlagItemModified)
  115
+      event->events = UV_CHANGE;
  116
+    else
  117
+      event->events = UV_RENAME;
  118
+
  119
+    ngx_queue_insert_tail(&add_list, &event->member);
  120
+  }
  121
+  uv_mutex_lock(&handle->cf_mutex);
  122
+  ngx_queue_add(&handle->cf_events, &add_list);
  123
+  uv_mutex_unlock(&handle->cf_mutex);
  124
+
  125
+  uv_async_send(handle->cf_cb);
  126
+}
  127
+
  128
+
  129
+void uv__fsevents_schedule(void* arg) {
  130
+  uv_fs_event_t* handle;
  131
+
  132
+  handle = arg;
  133
+  FSEventStreamScheduleWithRunLoop(handle->cf_eventstream,
  134
+                                   handle->loop->cf_loop,
  135
+                                   kCFRunLoopDefaultMode);
  136
+  FSEventStreamStart(handle->cf_eventstream);
  137
+  uv_sem_post(&handle->cf_sem);
  138
+}
  139
+
  140
+
  141
+int uv__fsevents_init(uv_fs_event_t* handle) {
  142
+  FSEventStreamContext ctx;
  143
+  FSEventStreamRef ref;
  144
+  CFStringRef path;
  145
+  CFArrayRef paths;
  146
+  CFAbsoluteTime latency;
  147
+  FSEventStreamCreateFlags flags;
  148
+
  149
+  /* Initialize context */
  150
+  ctx.version = 0;
  151
+  ctx.info = handle;
  152
+  ctx.retain = NULL;
  153
+  ctx.release = NULL;
  154
+  ctx.copyDescription = NULL;
  155
+
  156
+  /* Initialize paths array */
  157
+  path = CFStringCreateWithCString(NULL,
  158
+                                   handle->filename,
  159
+                                   CFStringGetSystemEncoding());
  160
+  paths = CFArrayCreate(NULL, (const void**)&path, 1, NULL);
  161
+
  162
+  latency = 0.15;
  163
+
  164
+  /* Set appropriate flags */
  165
+  flags = kFSEventStreamCreateFlagFileEvents;
  166
+
  167
+  ref = FSEventStreamCreate(NULL,
  168
+                            &uv__fsevents_event_cb,
  169
+                            &ctx,
  170
+                            paths,
  171
+                            kFSEventStreamEventIdSinceNow,
  172
+                            latency,
  173
+                            flags);
  174
+  handle->cf_eventstream = ref;
  175
+
  176
+  /*
  177
+   * Events will occur in other thread.
  178
+   * Initialize callback for getting them back into event loop's thread
  179
+   */
  180
+  handle->cf_cb = malloc(sizeof(*handle->cf_cb));
  181
+  if (handle->cf_cb == NULL)
  182
+    return uv__set_sys_error(handle->loop, ENOMEM);
  183
+
  184
+  handle->cf_cb->data = handle;
  185
+  uv_async_init(handle->loop, handle->cf_cb, uv__fsevents_cb);
  186
+  handle->cf_cb->flags |= UV__HANDLE_INTERNAL;
  187
+  uv_unref((uv_handle_t*) handle->cf_cb);
  188
+
  189
+  uv_mutex_init(&handle->cf_mutex);
  190
+  uv_sem_init(&handle->cf_sem, 0);
  191
+  ngx_queue_init(&handle->cf_events);
  192
+
  193
+  uv__cf_loop_signal(handle->loop, uv__fsevents_schedule, handle);
  194
+
  195
+  return 0;
  196
+}
  197
+
  198
+
  199
+int uv__fsevents_close(uv_fs_event_t* handle) {
  200
+  if (handle->cf_eventstream == NULL)
  201
+    return -1;
  202
+
  203
+  /* Ensure that event stream was scheduled */
  204
+  uv_sem_wait(&handle->cf_sem);
  205
+
  206
+  /* Stop emitting events */
  207
+  FSEventStreamStop(handle->cf_eventstream);
  208
+
  209
+  /* Release stream */
  210
+  FSEventStreamInvalidate(handle->cf_eventstream);
  211
+  FSEventStreamRelease(handle->cf_eventstream);
  212
+  handle->cf_eventstream = NULL;
  213
+
  214
+  uv_close((uv_handle_t*) handle->cf_cb, (uv_close_cb) free);
  215
+
  216
+  /* Free data in queue */
  217
+  UV__FSEVENTS_WALK(handle, {
  218
+    /* NOP */
  219
+  })
  220
+
  221
+  uv_mutex_destroy(&handle->cf_mutex);
  222
+  uv_sem_destroy(&handle->cf_sem);
  223
+
  224
+  return 0;
  225
+}
40  deps/uv/src/unix/internal.h
@@ -28,12 +28,6 @@
28 28
 #include <assert.h>
29 29
 #include <stdlib.h> /* abort */
30 30
 
31  
-#if defined(__GNUC__)
32  
-# define __read_mostly __attribute__((__section__(".data.read_mostly")))
33  
-#else
34  
-# define __read_mostly
35  
-#endif
36  
-
37 31
 #if defined(__STRICT_ANSI__)
38 32
 # define inline __inline
39 33
 #endif
@@ -108,9 +102,9 @@ enum {
108 102
   UV_LOOP_EIO_INITIALIZED = 1
109 103
 };
110 104
 
111  
-inline static void uv__req_init(uv_loop_t* loop,
112  
-                                uv_req_t* req,
113  
-                                uv_req_type type) {
  105
+__attribute__((unused))
  106
+__attribute__((always_inline))
  107
+static void uv__req_init(uv_loop_t* loop, uv_req_t* req, uv_req_type type) {
114 108
   req->type = type;
115 109
   uv__req_register(loop, req);
116 110
 }
@@ -195,4 +189,32 @@ void uv__udp_finish_close(uv_udp_t* handle);
195 189
 int uv__make_socketpair(int fds[2], int flags);
196 190
 int uv__make_pipe(int fds[2], int flags);
197 191
 
  192
+#if defined(__APPLE__)
  193
+typedef void (*cf_loop_signal_cb)(void*);
  194
+
  195
+void uv__cf_loop_signal(uv_loop_t* loop, cf_loop_signal_cb cb, void* arg);
  196
+
  197
+int uv__fsevents_init(uv_fs_event_t* handle);
  198
+int uv__fsevents_close(uv_fs_event_t* handle);
  199
+
  200
+/* OSX < 10.7 has no file events, polyfill them */
  201
+#if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 1070
  202
+
  203
+static const int kFSEventStreamCreateFlagFileEvents = 0x00000010;
  204
+static const int kFSEventStreamEventFlagItemCreated = 0x00000100;
  205
+static const int kFSEventStreamEventFlagItemRemoved = 0x00000200;
  206
+static const int kFSEventStreamEventFlagItemInodeMetaMod = 0x00000400;
  207
+static const int kFSEventStreamEventFlagItemRenamed = 0x00000800;
  208
+static const int kFSEventStreamEventFlagItemModified = 0x00001000;
  209
+static const int kFSEventStreamEventFlagItemFinderInfoMod = 0x00002000;
  210
+static const int kFSEventStreamEventFlagItemChangeOwner = 0x00004000;
  211
+static const int kFSEventStreamEventFlagItemXattrMod = 0x00008000;
  212
+static const int kFSEventStreamEventFlagItemIsFile = 0x00010000;
  213
+static const int kFSEventStreamEventFlagItemIsDir = 0x00020000;
  214
+static const int kFSEventStreamEventFlagItemIsSymlink = 0x00040000;
  215
+
  216
+#endif /* __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 1070 */
  217
+
  218
+#endif /* defined(__APPLE__) */
  219
+
198 220
 #endif /* UV_UNIX_INTERNAL_H_ */
25  deps/uv/src/unix/kqueue.c
@@ -89,6 +89,9 @@ int uv_fs_event_init(uv_loop_t* loop,
89 89
                      uv_fs_event_cb cb,
90 90
                      int flags) {
91 91
   int fd;
  92
+#if defined(__APPLE__)
  93
+  struct stat statbuf;
  94
+#endif /* defined(__APPLE__) */
92 95
 
93 96
   /* We don't support any flags yet. */
94 97
   assert(!flags);
@@ -105,6 +108,22 @@ int uv_fs_event_init(uv_loop_t* loop,
105 108
   handle->fflags = 0;
106 109
   handle->cb = cb;
107 110
   handle->fd = fd;
  111
+
  112
+#if defined(__APPLE__)
  113
+  /* Nullify field to perform checks later */
  114
+  handle->cf_eventstream = NULL;
  115
+
  116
+  if (fstat(fd, &statbuf))
  117
+    goto fallback;
  118
+  /* FSEvents works only with directories */
  119
+  if (!(statbuf.st_mode & S_IFDIR))
  120
+    goto fallback;
  121
+
  122
+  return uv__fsevents_init(handle);
  123
+
  124
+fallback:
  125
+#endif /* defined(__APPLE__) */
  126
+
108 127
   uv__fs_event_start(handle);
109 128
 
110 129
   return 0;
@@ -112,7 +131,13 @@ int uv_fs_event_init(uv_loop_t* loop,
112 131
 
113 132
 
114 133
 void uv__fs_event_close(uv_fs_event_t* handle) {
  134
+#if defined(__APPLE__)
  135
+  if (uv__fsevents_close(handle))
  136
+    uv__fs_event_stop(handle);
  137
+#else
115 138
   uv__fs_event_stop(handle);
  139
+#endif /* defined(__APPLE__) */
  140
+
116 141
   uv__handle_stop(handle);
117 142
   free(handle->filename);
118 143
   close(handle->fd);
6  deps/uv/src/unix/loop.c
@@ -51,6 +51,7 @@ int uv__loop_init(uv_loop_t* loop, int default_loop) {
51 51
   loop->time = uv_hrtime() / 1000000;
52 52
   loop->async_pipefd[0] = -1;
53 53
   loop->async_pipefd[1] = -1;
  54
+  loop->emfile_fd = -1;
54 55
   loop->ev = (default_loop ? ev_default_loop : ev_loop_new)(flags);
55 56
   ev_set_userdata(loop->ev, loop);
56 57
   eio_channel_init(&loop->uv_eio_channel, loop);
@@ -73,4 +74,9 @@ void uv__loop_delete(uv_loop_t* loop) {
73 74
   uv__platform_loop_delete(loop);
74 75
   uv__signal_unregister(loop);
75 76
   ev_loop_destroy(loop->ev);
  77
+
  78
+  if (loop->emfile_fd != -1) {
  79
+    close(loop->emfile_fd);
  80
+    loop->emfile_fd = -1;
  81
+  }
76 82
 }
244  deps/uv/src/unix/netbsd.c
@@ -19,11 +19,21 @@
19 19
  */
20 20
 
21 21
 #include "uv.h"
  22
+#include "internal.h"
22 23
 
23 24
 #include <assert.h>
24 25
 #include <string.h>
25 26
 #include <errno.h>
26 27
 
  28
+#include <kvm.h>
  29
+#include <paths.h>
  30
+#include <ifaddrs.h>
  31
+#include <unistd.h>
  32
+#include <time.h>
  33
+#include <stdlib.h>
  34
+#include <fcntl.h>
  35
+
  36
+#include <net/if.h>
27 37
 #include <sys/resource.h>
28 38
 #include <sys/types.h>
29 39
 #include <sys/sysctl.h>
@@ -34,6 +44,8 @@
34 44
 #undef NANOSEC
35 45
 #define NANOSEC ((uint64_t) 1e9)
36 46
 
  47
+static char *process_title;
  48
+
37 49
 
38 50
 int uv__platform_loop_init(uv_loop_t* loop, int default_loop) {
39 51
   return 0;
@@ -50,18 +62,20 @@ uint64_t uv_hrtime(void) {
50 62
   return (((uint64_t) ts.tv_sec) * NANOSEC + ts.tv_nsec);
51 63
 }
52 64
 
  65
+
53 66
 void uv_loadavg(double avg[3]) {
54 67
   struct loadavg info;
55 68
   size_t size = sizeof(info);
56 69
   int which[] = {CTL_VM, VM_LOADAVG};
57 70
 
58  
-  if (sysctl(which, 2, &info, &size, NULL, 0) < 0) return;
  71
+  if (sysctl(which, 2, &info, &size, NULL, 0) == -1) return;
59 72
 
60 73
   avg[0] = (double) info.ldavg[0] / info.fscale;
61 74
   avg[1] = (double) info.ldavg[1] / info.fscale;
62 75
   avg[2] = (double) info.ldavg[2] / info.fscale;
63 76
 }
64 77
 
  78
+
65 79
 int uv_exepath(char* buffer, size_t* size) {
66 80
   int mib[4];
67 81
   size_t cb;
@@ -78,7 +92,7 @@ int uv_exepath(char* buffer, size_t* size) {
78 92
   mib[3] = KERN_PROC_ARGV;
79 93
 
80 94
   cb = *size;
81  
-  if (sysctl(mib, 4, buffer, &cb, NULL, 0) < 0) {
  95
+  if (sysctl(mib, 4, buffer, &cb, NULL, 0) == -1) {
82 96
     *size = 0;
83 97
     return -1;
84 98
   }
@@ -87,18 +101,20 @@ int uv_exepath(char* buffer, size_t* size) {
87 101
   return 0;
88 102
 }
89 103
 
  104
+
90 105
 uint64_t uv_get_free_memory(void) {
91 106
   struct uvmexp info;
92 107
   size_t size = sizeof(info);
93 108
   int which[] = {CTL_VM, VM_UVMEXP};
94 109
 
95  
-  if (sysctl(which, 2, &info, &size, NULL, 0) < 0) {
  110
+  if (sysctl(which, 2, &info, &size, NULL, 0) == -1) {
96 111
     return -1;
97 112
   }
98 113
 
99 114
   return (uint64_t) info.free * sysconf(_SC_PAGESIZE);
100 115
 }
101 116
 
  117
+
102 118
 uint64_t uv_get_total_memory(void) {
103 119
 #if defined(HW_PHYSMEM64)
104 120
   uint64_t info;
@@ -109,9 +125,229 @@ uint64_t uv_get_total_memory(void) {
109 125
 #endif
110 126
   size_t size = sizeof(info);
111 127
 
112  
-  if (sysctl(which, 2, &info, &size, NULL, 0) < 0) {
  128
+  if (sysctl(which, 2, &info, &size, NULL, 0) == -1) {
113 129
     return -1;
114 130
   }
115 131
 
116 132
   return (uint64_t) info;
117 133
 }
  134
+
  135
+
  136
+char** uv_setup_args(int argc, char** argv) {
  137
+  process_title = argc ? strdup(argv[0]) : NULL;
  138
+  return argv;
  139
+}
  140
+
  141
+
  142
+uv_err_t uv_set_process_title(const char* title) {
  143
+  if (process_title) free(process_title);
  144
+
  145
+  process_title = strdup(title);
  146
+  setproctitle("%s", title);
  147
+
  148
+  return uv_ok_;
  149
+}
  150
+
  151
+
  152
+uv_err_t uv_get_process_title(char* buffer, size_t size) {
  153
+  if (process_title) {
  154
+    strncpy(buffer, process_title, size);
  155
+  } else {
  156
+    if (size > 0) {
  157
+      buffer[0] = '\0';
  158
+    }
  159
+  }
  160
+
  161
+  return uv_ok_;
  162
+}
  163
+
  164
+
  165
+uv_err_t uv_resident_set_memory(size_t* rss) {
  166
+  kvm_t *kd = NULL;
  167
+  struct kinfo_proc2 *kinfo = NULL;
  168
+  pid_t pid;
  169
+  int nprocs;
  170
+  int max_size = sizeof(struct kinfo_proc2);
  171
+  int page_size;
  172
+
  173
+  page_size = getpagesize();
  174
+  pid = getpid();
  175
+
  176
+  kd = kvm_open(NULL, NULL, NULL, KVM_NO_FILES, "kvm_open");
  177
+
  178
+  if (kd == NULL) goto error;
  179
+
  180
+  kinfo = kvm_getproc2(kd, KERN_PROC_PID, pid, max_size, &nprocs);
  181
+  if (kinfo == NULL) goto error;
  182
+
  183
+  *rss = kinfo->p_vm_rssize * page_size;
  184
+
  185
+  kvm_close(kd);
  186
+
  187
+  return uv_ok_;
  188
+
  189
+error:
  190
+  if (kd) kvm_close(kd);
  191
+  return uv__new_sys_error(errno);
  192
+}
  193
+
  194
+
  195
+uv_err_t uv_uptime(double* uptime) {
  196
+  time_t now;
  197
+  struct timeval info;
  198
+  size_t size = sizeof(info);
  199
+  static int which[] = {CTL_KERN, KERN_BOOTTIME};
  200
+
  201
+  if (sysctl(which, 2, &info, &size, NULL, 0) == -1) {
  202
+    return uv__new_sys_error(errno);
  203
+  }
  204
+
  205
+  now = time(NULL);
  206
+
  207
+  *uptime = (double)(now - info.tv_sec);
  208
+  return uv_ok_;
  209
+}
  210
+
  211
+
  212
+uv_err_t uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
  213
+  unsigned int ticks = (unsigned int)sysconf(_SC_CLK_TCK);
  214
+  unsigned int multiplier = ((uint64_t)1000L / ticks);
  215
+  unsigned int cur = 0;
  216
+  uv_cpu_info_t* cpu_info;
  217
+  u_int64_t* cp_times;
  218
+  char model[512];
  219
+  u_int64_t cpuspeed;
  220
+  int numcpus;
  221
+  size_t size;
  222
+  int i;
  223
+
  224
+  size = sizeof(model);
  225
+  if (sysctlbyname("machdep.cpu_brand", &model, &size, NULL, 0) == -1 &&
  226
+      sysctlbyname("hw.model", &model, &size, NULL, 0) == -1) {
  227
+    return uv__new_sys_error(errno);
  228
+  }
  229
+
  230
+  size = sizeof(numcpus);
  231
+  if (sysctlbyname("hw.ncpu", &numcpus, &size, NULL, 0) == -1) {
  232
+    return uv__new_sys_error(errno);
  233
+  }
  234
+  *count = numcpus;
  235
+
  236
+  /* Only i386 and amd64 have machdep.tsc_freq */
  237
+  size = sizeof(cpuspeed);
  238
+  if (sysctlbyname("machdep.tsc_freq", &cpuspeed, &size, NULL, 0) == -1) {
  239
+    cpuspeed = 0;
  240
+  }
  241
+
  242
+  size = numcpus * CPUSTATES * sizeof(*cp_times);
  243
+  cp_times = malloc(size);
  244
+  if (cp_times == NULL) {
  245
+    return uv__new_artificial_error(UV_ENOMEM);
  246
+  }
  247
+  if (sysctlbyname("kern.cp_time", cp_times, &size, NULL, 0) == -1) {
  248
+    return uv__new_sys_error(errno);
  249
+  }
  250
+
  251
+  *cpu_infos = malloc(numcpus * sizeof(**cpu_infos));
  252
+  if (!(*cpu_infos)) {
  253
+    free(cp_times);
  254
+    free(*cpu_infos);
  255
+    return uv__new_artificial_error(UV_ENOMEM);
  256
+  }
  257
+
  258
+  for (i = 0; i < numcpus; i++) {
  259
+    cpu_info = &(*cpu_infos)[i];
  260
+    cpu_info->cpu_times.user = (uint64_t)(cp_times[CP_USER+cur]) * multiplier;
  261
+    cpu_info->cpu_times.nice = (uint64_t)(cp_times[CP_NICE+cur]) * multiplier;
  262
+    cpu_info->cpu_times.sys = (uint64_t)(cp_times[CP_SYS+cur]) * multiplier;
  263
+    cpu_info->cpu_times.idle = (uint64_t)(cp_times[CP_IDLE+cur]) * multiplier;
  264
+    cpu_info->cpu_times.irq = (uint64_t)(cp_times[CP_INTR+cur]) * multiplier;
  265
+    cpu_info->model = strdup(model);
  266
+    cpu_info->speed = (int)(cpuspeed/(uint64_t) 1e6);
  267
+    cur += CPUSTATES;
  268
+  }
  269
+  free(cp_times);
  270
+  return uv_ok_;
  271
+}
  272
+
  273
+void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) {
  274
+  int i;
  275
+
  276
+  for (i = 0; i < count; i++) {
  277
+    free(cpu_infos[i].model);
  278
+  }
  279
+
  280
+  free(cpu_infos);
  281
+}
  282
+
  283
+
  284
+uv_err_t uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
  285
+  struct ifaddrs *addrs;
  286
+  struct ifaddrs *ent;
  287
+  uv_interface_address_t* address;
  288
+
  289
+  if (getifaddrs(&addrs) != 0) {
  290
+    return uv__new_sys_error(errno);
  291
+  }
  292
+
  293
+  *count = 0;
  294
+
  295
+  /* Count the number of interfaces */
  296
+  for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
  297
+    if (!(ent->ifa_flags & IFF_UP && ent->ifa_flags & IFF_RUNNING) ||
  298
+        (ent->ifa_addr == NULL) ||
  299
+        (ent->ifa_addr->sa_family != PF_INET)) {
  300
+      continue;
  301
+    }
  302
+    (*count)++;
  303
+  }
  304
+
  305
+  *addresses = malloc(*count * sizeof(**addresses));
  306
+
  307
+  if (!(*addresses)) {
  308
+    return uv__new_artificial_error(UV_ENOMEM);
  309
+  }
  310
+
  311
+  address = *addresses;
  312
+
  313
+  for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
  314
+    if (!(ent->ifa_flags & IFF_UP && ent->ifa_flags & IFF_RUNNING)) {
  315
+      continue;
  316
+    }
  317
+
  318
+    if (ent->ifa_addr == NULL) {
  319
+      continue;
  320
+    }
  321
+
  322
+    if (ent->ifa_addr->sa_family != PF_INET) {
  323
+      continue;
  324
+    }
  325
+
  326
+    address->name = strdup(ent->ifa_name);
  327
+
  328
+    if (ent->ifa_addr->sa_family == AF_INET6) {
  329
+      address->address.address6 = *((struct sockaddr_in6 *)ent->ifa_addr);
  330
+    } else {
  331
+      address->address.address4 = *((struct sockaddr_in *)ent->ifa_addr);
  332
+    }
  333
+
  334
+    address->is_internal = !!(ent->ifa_flags & IFF_LOOPBACK) ? 1 : 0;
  335
+
  336
+    address++;
  337
+  }
  338
+
  339
+  freeifaddrs(addrs);
  340
+
  341
+  return uv_ok_;
  342
+}
  343
+
  344
+
  345
+void uv_free_interface_addresses(uv_interface_address_t* addresses, int count) {
  346
+  int i;
  347
+
  348
+  for (i = 0; i < count; i++) {
  349
+    free(addresses[i].name);
  350
+  }
  351
+
  352
+  free(addresses);
  353
+}
4  deps/uv/src/unix/process.c
@@ -117,7 +117,7 @@ static void uv__chld(uv_signal_t* handle, int signum) {
117 117
 
118 118
 int uv__make_socketpair(int fds[2], int flags) {
119 119
 #if __linux__
120  
-  static __read_mostly int no_cloexec;
  120
+  static int no_cloexec;
121 121
 
122 122
   if (no_cloexec)
123 123
     goto skip;
@@ -153,7 +153,7 @@ int uv__make_socketpair(int fds[2], int flags) {
153 153
 
154 154
 int uv__make_pipe(int fds[2], int flags) {
155 155
 #if __linux__
156  
-  static __read_mostly int no_pipe2;
  156
+  static int no_pipe2;
157 157
 
158 158
   if (no_pipe2)
159 159
     goto skip;
135  deps/uv/src/unix/stream.c
@@ -62,6 +62,29 @@ static void uv__read(uv_stream_t* stream);
62 62
 static void uv__stream_io(uv_loop_t* loop, uv__io_t* w, int events);
63 63
 
64 64
 
  65
+/* Used by the accept() EMFILE party trick. */
  66
+static int uv__open_cloexec(const char* path, int flags) {
  67
+  int fd;
  68
+
  69
+#if defined(__linux__)
  70
+  fd = open(path, flags | UV__O_CLOEXEC);
  71
+  if (fd != -1)
  72
+    return fd;
  73
+
  74
+  if (errno != EINVAL)
  75
+    return -1;
  76
+
  77
+  /* O_CLOEXEC not supported. */
  78
+#endif
  79
+
  80
+  fd = open(path, flags);
  81
+  if (fd != -1)
  82
+    uv__cloexec(fd, 1);
  83
+
  84
+  return fd;
  85
+}
  86
+
  87
+
65 88
 static size_t uv__buf_count(uv_buf_t bufs[], int bufcnt) {
66 89
   size_t total = 0;
67 90
   int i;
@@ -90,6 +113,9 @@ void uv__stream_init(uv_loop_t* loop,
90 113
   ngx_queue_init(&stream->write_completed_queue);
91 114
   stream->write_queue_size = 0;
92 115
 
  116
+  if (loop->emfile_fd == -1)
  117
+    loop->emfile_fd = uv__open_cloexec("/", O_RDONLY);
  118
+
93 119
 #if defined(__APPLE__)
94 120
   stream->select = NULL;
95 121
 #endif /* defined(__APPLE_) */
@@ -370,10 +396,56 @@ static void uv__next_accept(uv_idle_t* idle, int status) {
370 396
 }
371 397
 
372 398
 
  399
+/* Implements a best effort approach to mitigating accept() EMFILE errors.
  400
+ * We have a spare file descriptor stashed away that we close to get below
  401
+ * the EMFILE limit. Next, we accept all pending connections and close them
  402
+ * immediately to signal the clients that we're overloaded - and we are, but
  403
+ * we still keep on trucking.
  404
+ *
  405
+ * There is one caveat: it's not reliable in a multi-threaded environment.
  406
+ * The file descriptor limit is per process. Our party trick fails if another
  407
+ * thread opens a file or creates a socket in the time window between us
  408
+ * calling close() and accept().
  409
+ */
  410
+static int uv__emfile_trick(uv_loop_t* loop, int accept_fd) {
  411
+  int fd;
  412
+  int r;
  413
+
  414
+  if (loop->emfile_fd == -1)
  415
+    return -1;
  416
+
  417
+  close(loop->emfile_fd);
  418
+
  419
+  for (;;) {
  420
+    fd = uv__accept(accept_fd);
  421
+
  422
+    if (fd != -1) {
  423
+      close(fd);
  424
+      continue;
  425
+    }
  426
+
  427
+    if (errno == EINTR)
  428
+      continue;
  429
+
  430
+    if (errno == EAGAIN || errno == EWOULDBLOCK)
  431
+      r = 0;
  432
+    else
  433
+      r = -1;
  434
+
  435
+    loop->emfile_fd = uv__open_cloexec("/", O_RDONLY);
  436
+
  437
+    return r;
  438
+  }
  439
+}
  440
+
  441
+
373 442
 void uv__server_io(uv_loop_t* loop, uv__io_t* w, int events) {
  443
+  static int use_emfile_trick = -1;
  444
+  uv_stream_t* stream;
374 445
   int fd;
375  
-  uv_stream_t* stream = container_of(w, uv_stream_t, read_watcher);
  446
+  int r;
376 447
 
  448
+  stream = container_of(w, uv_stream_t, read_watcher);
377 449
   assert(events == UV__IO_READ);
378 450
   assert(!(stream->flags & UV_CLOSING));
379 451
 
@@ -389,31 +461,48 @@ void uv__server_io(uv_loop_t* loop, uv__io_t* w, int events) {
389 461
     assert(stream->accepted_fd < 0);
390 462
     fd = uv__accept(stream->fd);
391 463
 
392  
-    if (fd < 0) {
393  
-      if (errno == EAGAIN || errno == EWOULDBLOCK) {
394  
-        /* No problem. */
395  
-        return;
396  
-      } else if (errno == EMFILE) {
397  
-        /* TODO special trick. unlock reserved socket, accept, close. */
398  
-        return;
399  
-      } else if (errno == ECONNABORTED) {
400  
-        /* ignore */
  464
+    if (fd == -1) {
  465
+      switch (errno) {
  466
+#if EWOULDBLOCK != EAGAIN
  467
+      case EWOULDBLOCK:
  468
+#endif
  469
+      case EAGAIN:
  470
+        return; /* Not an error. */
  471
+
  472
+      case ECONNABORTED:
  473
+        continue; /* Ignore. */
  474
+
  475
+      case EMFILE:
  476
+      case ENFILE:
  477
+        if (use_emfile_trick == -1) {
  478
+          const char* val = getenv("UV_ACCEPT_EMFILE_TRICK");
  479
+          use_emfile_trick = (val == NULL || atoi(val) != 0);
  480
+        }
  481
+
  482
+        if (use_emfile_trick) {
  483
+          SAVE_ERRNO(r = uv__emfile_trick(loop, stream->fd));
  484
+          if (r == 0)
  485
+            continue;
  486
+        }
  487
+
  488
+        /* Fall through. */
  489
+
  490
+      default:
  491
+        uv__set_sys_error(loop, errno);
  492
+        stream->connection_cb(stream, -1);
401 493
         continue;
402  
-      } else {
403  
-        uv__set_sys_error(stream->loop, errno);
404  
-        stream->connection_cb((uv_stream_t*)stream, -1);
405  
-      }
406  
-    } else {
407  
-      stream->accepted_fd = fd;
408  
-      stream->connection_cb(stream, 0);
409  
-
410  
-      if (stream->accepted_fd != -1 ||
411  
-          (stream->type == UV_TCP && stream->flags == UV_TCP_SINGLE_ACCEPT)) {
412  
-        /* The user hasn't yet accepted called uv_accept() */
413  
-        uv__io_stop(stream->loop, &stream->read_watcher);
414  
-        break;
415 494
       }
416 495
     }
  496
+
  497
+    stream->accepted_fd = fd;
  498
+    stream->connection_cb(stream, 0);
  499
+
  500
+    if (stream->accepted_fd != -1 ||
  501
+        (stream->type == UV_TCP && stream->flags == UV_TCP_SINGLE_ACCEPT)) {
  502
+      /* The user hasn't yet accepted called uv_accept() */
  503
+      uv__io_stop(loop, &stream->read_watcher);
  504
+      break;
  505
+    }
417 506
   }
418 507
 
419 508
   if (stream->fd != -1 &&
6  deps/uv/src/unix/tcp.c
@@ -247,6 +247,7 @@ int uv_tcp_listen(uv_tcp_t* tcp, int backlog, uv_connection_cb cb) {
247 247
 
248 248
   if (uv_idle_init(tcp->loop, tcp->idle_handle))
249 249
     abort();
  250
+  tcp->idle_handle->flags |= UV__HANDLE_INTERNAL;
250 251
 
251 252
   tcp->flags |= UV_TCP_SINGLE_ACCEPT;
252 253
 
@@ -331,7 +332,10 @@ int uv__tcp_keepalive(uv_tcp_t* handle, int enable, unsigned int delay) {
331 332
   }
332 333
 #endif
333 334
 
334  
-#ifdef TCP_KEEPALIVE
  335
+  /* Solaris/SmartOS, if you don't support keep-alive,
  336
+   * then don't advertise it in your system headers...
  337
+   */
  338
+#if defined(TCP_KEEPALIVE) && !defined(__sun)
335 339
   if (enable && setsockopt(handle->fd,
336 340
                            IPPROTO_TCP,
337 341
                            TCP_KEEPALIVE,
9  deps/uv/src/uv-common.c
@@ -314,6 +314,15 @@ int uv_thread_create(uv_thread_t *tid, void (*entry)(void *arg), void *arg) {
314 314
 }
315 315
 
316 316
 
  317
+unsigned long uv_thread_self(void) {
  318
+#ifdef _WIN32
  319
+  return (unsigned long) GetCurrentThreadId();
  320
+#else
  321
+  return (unsigned long) pthread_self();
  322
+#endif
  323
+}
  324
+
  325
+
317 326
 void uv_walk(uv_loop_t* loop, uv_walk_cb walk_cb, void* arg) {
318 327
   ngx_queue_t* q;
319 328
   uv_handle_t* h;
1  deps/uv/src/win/error.c
@@ -144,6 +144,7 @@ uv_err_code uv_translate_sys_error(int sys_errno) {
144 144
     case ERROR_BAD_PIPE:                    return UV_EPIPE;
145 145
     case ERROR_NO_DATA:                     return UV_EPIPE;
146 146
     case ERROR_PIPE_NOT_CONNECTED:          return UV_EPIPE;
  1