deps: update libuv to v0.11.26
authorFedor Indutny <fedor@indutny.com>
Fri, 27 Jun 2014 00:44:36 +0000 (04:44 +0400)
committerFedor Indutny <fedor@indutny.com>
Fri, 27 Jun 2014 00:44:36 +0000 (04:44 +0400)
62 files changed:
deps/uv/.mailmap
deps/uv/AUTHORS
deps/uv/CONTRIBUTING.md
deps/uv/ChangeLog
deps/uv/Makefile.am
deps/uv/Makefile.mingw
deps/uv/README.md
deps/uv/configure.ac
deps/uv/include/uv-bsd.h
deps/uv/include/uv-darwin.h
deps/uv/include/uv-errno.h
deps/uv/include/uv-linux.h
deps/uv/include/uv-sunos.h
deps/uv/include/uv-unix.h
deps/uv/include/uv-version.h
deps/uv/include/uv-win.h
deps/uv/include/uv.h
deps/uv/src/heap-inl.h
deps/uv/src/inet.c
deps/uv/src/unix/async.c
deps/uv/src/unix/core.c
deps/uv/src/unix/darwin.c
deps/uv/src/unix/dl.c
deps/uv/src/unix/freebsd.c
deps/uv/src/unix/getnameinfo.c [new file with mode: 0644]
deps/uv/src/unix/kqueue.c
deps/uv/src/unix/linux-inotify.c
deps/uv/src/unix/openbsd.c
deps/uv/src/unix/stream.c
deps/uv/src/unix/sunos.c
deps/uv/src/unix/thread.c
deps/uv/src/unix/threadpool.c
deps/uv/src/unix/udp.c
deps/uv/src/uv-common.c
deps/uv/src/win/core.c
deps/uv/src/win/dl.c
deps/uv/src/win/fs-event.c
deps/uv/src/win/fs.c
deps/uv/src/win/getaddrinfo.c
deps/uv/src/win/getnameinfo.c [new file with mode: 0644]
deps/uv/src/win/handle-inl.h
deps/uv/src/win/internal.h
deps/uv/src/win/pipe.c
deps/uv/src/win/poll.c
deps/uv/src/win/process.c
deps/uv/src/win/req-inl.h
deps/uv/src/win/tcp.c
deps/uv/src/win/thread.c
deps/uv/src/win/tty.c
deps/uv/src/win/udp.c
deps/uv/src/win/util.c
deps/uv/test/test-barrier.c
deps/uv/test/test-fs.c
deps/uv/test/test-getnameinfo.c [new file with mode: 0644]
deps/uv/test/test-ip6-addr.c
deps/uv/test/test-list.h
deps/uv/test/test-poll-closesocket.c [new file with mode: 0644]
deps/uv/test/test-spawn.c
deps/uv/test/test-threadpool-cancel.c
deps/uv/test/test-udp-options.c
deps/uv/uv.gyp
deps/uv/vcbuild.bat

index 533e101..89c1ade 100644 (file)
@@ -15,6 +15,7 @@ Keno Fischer <kenof@stanford.edu> <kfischer@college.harvard.edu>
 Maciej Małecki <maciej.malecki@notimplemented.org> <me@mmalecki.com>
 Marc Schlaich <marc.schlaich@googlemail.com> <marc.schlaich@gmail.com>
 Rasmus Christian Pedersen <ruysch@outlook.com>
+Rasmus Christian Pedersen <zerhacken@yahoo.com> <ruysch@outlook.com>
 Rasmus Pedersen <ruysch@outlook.com> <zerhacken@yahoo.com>
 Robert Mustacchi <rm@joyent.com> <rm@fingolfin.org>
 Ryan Dahl <ryan@joyent.com> <ry@tinyclouds.org>
index cb47cee..e3de576 100644 (file)
@@ -139,3 +139,10 @@ Norio Kobota <nori.0428@gmail.com>
 李港平 <chopdown@gmail.com>
 Chernyshev Viacheslav <astellar@ro.ru>
 Stephen von Takach <steve@advancedcontrol.com.au>
+JD Ballard <jd@pixelandline.com>
+Luka Perkov <luka.perkov@sartura.hr>
+Ryan Cole <ryan@rycole.com>
+HungMingWu <u9089000@gmail.com>
+Jay Satiro <raysatiro@yahoo.com>
+Leith Bade <leith@leithalweapon.geek.nz>
+Peter Atashian <retep998@gmail.com>
index 960a945..28a32ba 100644 (file)
@@ -142,11 +142,8 @@ Bug fixes and features should come with tests.  Add your tests in the
 Look at other tests to see how they should be structured (license boilerplate,
 the way entry points are declared, etc.).
 
-```
-$ make test
-```
-
-Make sure that there are no test regressions.
+Check README.md file to find out how to run the test suite and make sure that
+there are no test regressions.
 
 ### PUSH
 
@@ -163,15 +160,7 @@ feature branch.  Post a comment in the pull request afterwards; GitHub does
 not send out notifications when you add commits.
 
 
-### CONTRIBUTOR LICENSE AGREEMENT
-
-The current state of affairs is that, in order to get a patch accepted, you need
-to sign Node.js's [contributor license agreement][]. You only need to do that
-once.
-
-
 [issue tracker]: https://github.com/joyent/libuv/issues
 [libuv mailing list]: http://groups.google.com/group/libuv
 [IRC]: http://webchat.freelibuv.net/?channels=libuv
 [Google C/C++ style guide]: http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml
-[contributor license agreement]: http://nodejs.org/cla.html
index 907af36..50d3989 100644 (file)
@@ -1,4 +1,41 @@
-2014.05.02, Version 0.11.25 (Unstable)
+2014.06.28, Version 0.11.26 (Unstable)
+
+Changes since version 0.11.25:
+
+* windows: add VT100 codes ?25l and ?25h (JD Ballard)
+
+* windows: add invert ANSI (7 / 27) emulation (JD Ballard)
+
+* unix: fix handling error on UDP socket creation (Saúl Ibarra Corretgé)
+
+* unix, windows: getnameinfo implementation (Rasmus Pedersen)
+
+* heap: fix `heap_remove()` (Fedor Indutny)
+
+* unix, windows: fix parsing scoped IPv6 addresses (Saúl Ibarra Corretgé)
+
+* windows: fix handling closed socket while poll handle is closing (Saúl Ibarra
+  Corretgé)
+
+* thread: barrier functions (Ben Noordhuis)
+
+* windows: fix PYTHON environment variable usage (Jay Satiro)
+
+* unix, windows: return system error on EAI_SYSTEM (Saúl Ibarra Corretgé)
+
+* windows: fix handling closed socket while poll handle is closing (Saúl Ibarra
+  Corretgé)
+
+* unix: don't run i/o callbacks after prepare callbacks (Saúl Ibarra Corretgé)
+
+* windows: add tty unicode support for input (Peter Atashian)
+
+* header: introduce `uv_loop_size()` (Andrius Bentkus)
+
+* darwin: invoke `mach_timebase_info` only once (Fedor Indutny)
+
+
+2014.05.02, Version 0.11.25 (Unstable), 2acd544cff7142e06aa3b09ec64b4a33dd9ab996
 
 Changes since version 0.11.24:
 
@@ -33,8 +70,6 @@ Changes since version 0.11.23:
 
 * inet: allow scopeid in uv_inet_pton (Fedor Indutny)
 
-* win: always leave crit section in get_proc_title (Fedor Indutny)
-
 
 2014.04.07, Version 0.11.23 (Unstable), e54de537efcacd593f36fcaaf8b4cb9e64313275
 
@@ -77,25 +112,6 @@ Changes since version 0.11.22:
 * unix: fix setting written size on uv_wd (Saúl Ibarra Corretgé)
 
 
-2014.04.07, Version 0.10.26 (Stable), d864907611c25ec986c5e77d4d6d6dee88f26926
-
-Changes since version 0.10.25:
-
-* process: don't close stdio fds during spawn (Tonis Tiigi)
-
-* build, windows: do not fail on Windows SDK Prompt (Marc Schlaich)
-
-* build, windows: fix x64 configuration issue (Marc Schlaich)
-
-* win: fix buffer leak on error in pipe.c (Fedor Indutny)
-
-* kqueue: invalidate fd in uv_fs_event_t (Fedor Indutny)
-
-* linux: always deregister closing fds from epoll (Geoffry Song)
-
-* error: add ENXIO for O_NONBLOCK FIFO open() (Fedor Indutny)
-
-
 2014.03.11, Version 0.11.22 (Unstable), cd0c19b1d3c56acf0ade7687006e12e75fbda36d
 
 Changes since version 0.11.21:
@@ -225,6 +241,34 @@ Changes since version 0.11.18:
 * linux: fix C99/C++ comment (Fedor Indutny)
 
 
+2014.05.02, Version 0.10.27 (Stable), 6e24ce23b1e7576059f85a608eca13b766458a01
+
+Changes since version 0.10.26:
+
+* windows: fix console signal handler refcount (Saúl Ibarra Corretgé)
+
+* win: always leave crit section in get_proc_title (Fedor Indutny)
+
+
+2014.04.07, Version 0.10.26 (Stable), d864907611c25ec986c5e77d4d6d6dee88f26926
+
+Changes since version 0.10.25:
+
+* process: don't close stdio fds during spawn (Tonis Tiigi)
+
+* build, windows: do not fail on Windows SDK Prompt (Marc Schlaich)
+
+* build, windows: fix x64 configuration issue (Marc Schlaich)
+
+* win: fix buffer leak on error in pipe.c (Fedor Indutny)
+
+* kqueue: invalidate fd in uv_fs_event_t (Fedor Indutny)
+
+* linux: always deregister closing fds from epoll (Geoffry Song)
+
+* error: add ENXIO for O_NONBLOCK FIFO open() (Fedor Indutny)
+
+
 2014.02.19, Version 0.10.25 (Stable), d778dc588507588b12b9f9d2905078db542ed751
 
 Changes since version 0.10.24:
index 41833c9..ebcd8db 100644 (file)
@@ -51,6 +51,7 @@ libuv_la_SOURCES += src/win/async.c \
                     src/win/fs-event.c \
                     src/win/fs.c \
                     src/win/getaddrinfo.c \
+                    src/win/getnameinfo.c \
                     src/win/handle.c \
                     src/win/handle-inl.h \
                     src/win/internal.h \
@@ -86,6 +87,7 @@ libuv_la_SOURCES += src/unix/async.c \
                    src/unix/dl.c \
                    src/unix/fs.c \
                    src/unix/getaddrinfo.c \
+                   src/unix/getnameinfo.c \
                    src/unix/internal.h \
                    src/unix/loop-watcher.c \
                    src/unix/loop.c \
@@ -138,6 +140,7 @@ test_run_tests_SOURCES = test/blackhole-server.c \
                          test/test-get-loadavg.c \
                          test/test-get-memory.c \
                          test/test-getaddrinfo.c \
+                         test/test-getnameinfo.c \
                          test/test-getsockname.c \
                          test/test-hrtime.c \
                          test/test-idle.c \
@@ -163,6 +166,7 @@ test_run_tests_SOURCES = test/blackhole-server.c \
                          test/test-pipe-server-close.c \
                          test/test-platform-output.c \
                          test/test-poll-close.c \
+                         test/test-poll-closesocket.c \
                          test/test-poll.c \
                          test/test-process-title.c \
                          test/test-ref.c \
@@ -238,8 +242,10 @@ libuv_la_SOURCES += src/unix/aix.c
 endif
 
 if ANDROID
-include_HEADERS += include/android-ifaddrs.h
-libuv_la_SOURCES += src/unix/android-ifaddrs.c
+include_HEADERS += include/android-ifaddrs.h \
+                   include/pthread-fixes.h
+libuv_la_SOURCES += src/unix/android-ifaddrs.c \
+                    src/unix/pthread-fixes.c
 endif
 
 if DARWIN
index af84c75..a0b7cc9 100644 (file)
@@ -51,6 +51,7 @@ OBJS = src/fs-poll.o \
        src/win/fs-event.o \
        src/win/fs.o \
        src/win/getaddrinfo.o \
+       src/win/getnameinfo.o \
        src/win/handle.o \
        src/win/loop-watcher.o \
        src/win/pipe.o \
index 00b539c..e0e7359 100644 (file)
@@ -66,10 +66,9 @@ To build with autotools:
 
 ### Windows
 
-First, Python 2.6 or 2.7 must be installed as it is required by [GYP][].
-
-Also, the directory for the preferred Python executable must be specified
-by the `PYTHON` or `Path` environment variables.
+First, [Python][] 2.6 or 2.7 must be installed as it is required by [GYP][].
+If python is not in your path set the environment variable `PYTHON` to its
+location. For example: `set PYTHON=C:\Python27\python.exe`
 
 To build with Visual Studio, launch a git shell (e.g. Cmd or PowerShell)
 and run vcbuild.bat which will checkout the GYP code into build/gyp and
@@ -139,5 +138,6 @@ See the [guidelines for contributing][].
 
 [node.js]: http://nodejs.org/
 [GYP]: http://code.google.com/p/gyp/
+[Python]: https://www.python.org/downloads/
 [Visual Studio Express 2010]: http://www.microsoft.com/visualstudio/eng/products/visual-studio-2010-express
 [guidelines for contributing]: https://github.com/joyent/libuv/blob/master/CONTRIBUTING.md
index 078c717..0423c8c 100644 (file)
@@ -13,7 +13,7 @@
 # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 
 AC_PREREQ(2.57)
-AC_INIT([libuv], [0.11.25], [https://github.com/joyent/libuv/issues])
+AC_INIT([libuv], [0.11.26], [https://github.com/joyent/libuv/issues])
 AC_CONFIG_MACRO_DIR([m4])
 m4_include([m4/libuv-extra-automake-flags.m4])
 m4_include([m4/as_case.m4])
index 3458d5d..2d72b3d 100644 (file)
@@ -31,6 +31,4 @@
 
 #define UV_HAVE_KQUEUE 1
 
-#define UV_PLATFORM_HAS_IP6_LINK_LOCAL_ADDRESS
-
 #endif /* UV_BSD_H */
index 24bc35b..d226415 100644 (file)
@@ -58,6 +58,4 @@
 
 #define UV_HAVE_KQUEUE 1
 
-#define UV_PLATFORM_HAS_IP6_LINK_LOCAL_ADDRESS
-
 #endif /* UV_DARWIN_H */
index 0981834..00b4860 100644 (file)
@@ -39,7 +39,6 @@
 #define UV__EAI_OVERFLOW    (-3009)
 #define UV__EAI_SERVICE     (-3010)
 #define UV__EAI_SOCKTYPE    (-3011)
-#define UV__EAI_SYSTEM      (-3012) /* TODO(bnoordhuis) Return system error. */
 #define UV__EAI_BADHINTS    (-3013)
 #define UV__EAI_PROTOCOL    (-3014)
 
index 62ebfe2..9b38405 100644 (file)
@@ -31,6 +31,4 @@
   void* watchers[2];                                                          \
   int wd;                                                                     \
 
-#define UV_PLATFORM_HAS_IP6_LINK_LOCAL_ADDRESS
-
 #endif /* UV_LINUX_H */
index c4cd83d..0421664 100644 (file)
@@ -41,6 +41,4 @@
 
 #endif /* defined(PORT_SOURCE_FILE) */
 
-#define UV_PLATFORM_HAS_IP6_LINK_LOCAL_ADDRESS
-
 #endif /* UV_SUNOS_H */
index 40c4989..d59d743 100644 (file)
 # include "uv-bsd.h"
 #endif
 
+#ifndef NI_MAXHOST
+# define NI_MAXHOST 1025
+#endif
+
+#ifndef NI_MAXSERV
+# define NI_MAXSERV 32
+#endif
+
 #ifndef UV_IO_PRIVATE_PLATFORM_FIELDS
 # define UV_IO_PRIVATE_PLATFORM_FIELDS /* empty */
 #endif
@@ -281,6 +289,15 @@ typedef struct {
   struct addrinfo* res;                                                       \
   int retcode;
 
+#define UV_GETNAMEINFO_PRIVATE_FIELDS                                         \
+  struct uv__work work_req;                                                   \
+  uv_getnameinfo_cb getnameinfo_cb;                                           \
+  struct sockaddr_storage storage;                                            \
+  int flags;                                                                  \
+  char host[NI_MAXHOST];                                                      \
+  char service[NI_MAXSERV];                                                   \
+  int retcode;
+
 #define UV_PROCESS_PRIVATE_FIELDS                                             \
   void* queue[2];                                                             \
   int status;                                                                 \
index bd69f6c..6f8e080 100644 (file)
@@ -32,7 +32,7 @@
 
 #define UV_VERSION_MAJOR 0
 #define UV_VERSION_MINOR 11
-#define UV_VERSION_PATCH 25
+#define UV_VERSION_PATCH 26
 #define UV_VERSION_IS_RELEASE 1
 
 #endif /* UV_VERSION_H */
index 211c593..2f24dfe 100644 (file)
@@ -528,6 +528,14 @@ RB_HEAD(uv_timer_tree_s, uv_timer_s);
   struct addrinfoW* res;                                                      \
   int retcode;
 
+#define UV_GETNAMEINFO_PRIVATE_FIELDS                                         \
+  uv_getnameinfo_cb getnameinfo_cb;                                           \
+  struct sockaddr_storage storage;                                            \
+  int flags;                                                                  \
+  char host[NI_MAXHOST];                                                      \
+  char service[NI_MAXSERV];                                                   \
+  int retcode;
+
 #define UV_PROCESS_PRIVATE_FIELDS                                             \
   struct uv_process_exit_s {                                                  \
     UV_REQ_FIELDS                                                             \
@@ -587,4 +595,3 @@ int uv_utf16_to_utf8(const WCHAR* utf16Buffer, size_t utf16Size,
 int uv_utf8_to_utf16(const char* utf8Buffer, WCHAR* utf16Buffer,
     size_t utf16Size);
 
-#define UV_PLATFORM_HAS_IP6_LINK_LOCAL_ADDRESS
index d456626..ef2f840 100644 (file)
@@ -83,7 +83,6 @@ extern "C" {
   XX(EAI_PROTOCOL, "resolved protocol is unknown")                            \
   XX(EAI_SERVICE, "service not available for socket type")                    \
   XX(EAI_SOCKTYPE, "socket type not supported")                               \
-  XX(EAI_SYSTEM, "system error")                                              \
   XX(EALREADY, "connection already in progress")                              \
   XX(EBADF, "bad file descriptor")                                            \
   XX(EBUSY, "resource busy or locked")                                        \
@@ -167,6 +166,7 @@ extern "C" {
   XX(FS, fs)                                                                  \
   XX(WORK, work)                                                              \
   XX(GETADDRINFO, getaddrinfo)                                                \
+  XX(GETNAMEINFO, getnameinfo)                                                \
 
 typedef enum {
 #define XX(code, _) UV_ ## code = UV__ ## code,
@@ -216,6 +216,7 @@ typedef struct uv_signal_s uv_signal_t;
 /* Request types. */
 typedef struct uv_req_s uv_req_t;
 typedef struct uv_getaddrinfo_s uv_getaddrinfo_t;
+typedef struct uv_getnameinfo_s uv_getnameinfo_t;
 typedef struct uv_shutdown_s uv_shutdown_t;
 typedef struct uv_write_s uv_write_t;
 typedef struct uv_connect_s uv_connect_t;
@@ -288,6 +289,11 @@ UV_EXTERN uv_loop_t* uv_loop_new(void);
 UV_EXTERN void uv_loop_delete(uv_loop_t*);
 
 /*
+ * Returns size of the loop struct, useful for dynamic lookup with FFI
+ */
+UV_EXTERN size_t uv_loop_size(void);
+
+/*
  * This function runs the event loop. It will act differently depending on the
  * specified mode:
  *  - UV_RUN_DEFAULT: Runs the event loop until the reference count drops to
@@ -297,7 +303,9 @@ UV_EXTERN void uv_loop_delete(uv_loop_t*);
  *    or requests left), or non-zero if more events are expected (meaning you
  *    should run the event loop again sometime in the future).
  *  - UV_RUN_NOWAIT: Poll for new events once but don't block if there are no
- *    pending events.
+ *    pending events. Returns zero when done (no active handles
+ *    or requests left), or non-zero if more events are expected (meaning you
+ *    should run the event loop again sometime in the future).
  */
 UV_EXTERN int uv_run(uv_loop_t*, uv_run_mode mode);
 
@@ -419,6 +427,10 @@ typedef void (*uv_after_work_cb)(uv_work_t* req, int status);
 typedef void (*uv_getaddrinfo_cb)(uv_getaddrinfo_t* req,
                                   int status,
                                   struct addrinfo* res);
+typedef void (*uv_getnameinfo_cb)(uv_getnameinfo_t* req,
+                                  int status,
+                                  const char* hostname,
+                                  const char* service);
 
 typedef struct {
   long tv_sec;
@@ -1451,6 +1463,33 @@ UV_EXTERN int uv_getaddrinfo(uv_loop_t* loop,
 UV_EXTERN void uv_freeaddrinfo(struct addrinfo* ai);
 
 
+/*
+* uv_getnameinfo_t is a subclass of uv_req_t
+*
+* Request object for uv_getnameinfo.
+*/
+struct uv_getnameinfo_s {
+  UV_REQ_FIELDS
+  /* read-only */
+  uv_loop_t* loop;
+  UV_GETNAMEINFO_PRIVATE_FIELDS
+};
+
+/*
+ * Asynchronous getnameinfo.
+ *
+ * Returns 0 on success or an error code < 0 on failure.
+ *
+ * If successful, your callback gets called sometime in the future with the
+ * lookup result.
+ */
+UV_EXTERN int uv_getnameinfo(uv_loop_t* loop,
+                             uv_getnameinfo_t* req,
+                             uv_getnameinfo_cb getnameinfo_cb,
+                             const struct sockaddr* addr,
+                             int flags);
+
+
 /* uv_spawn() options */
 typedef enum {
   UV_IGNORE         = 0x00,
@@ -2124,7 +2163,7 @@ UV_EXTERN int uv_dlsym(uv_lib_t* lib, const char* name, void** ptr);
 /*
  * Returns the last uv_dlopen() or uv_dlsym() error message.
  */
-UV_EXTERN const char* uv_dlerror(uv_lib_t* lib);
+UV_EXTERN const char* uv_dlerror(const uv_lib_t* lib);
 
 /*
  * The mutex functions return 0 on success or an error code < 0
@@ -2164,6 +2203,19 @@ UV_EXTERN int uv_cond_init(uv_cond_t* cond);
 UV_EXTERN void uv_cond_destroy(uv_cond_t* cond);
 UV_EXTERN void uv_cond_signal(uv_cond_t* cond);
 UV_EXTERN void uv_cond_broadcast(uv_cond_t* cond);
+
+/*
+ * Same goes for the barrier functions.  Note that uv_barrier_wait() returns
+ * a value > 0 to an arbitrarily chosen "serializer" thread to facilitate
+ * cleanup, i.e.:
+ *
+ *   if (uv_barrier_wait(&barrier) > 0)
+ *     uv_barrier_destroy(&barrier);
+ */
+UV_EXTERN int uv_barrier_init(uv_barrier_t* barrier, unsigned int count);
+UV_EXTERN void uv_barrier_destroy(uv_barrier_t* barrier);
+UV_EXTERN int uv_barrier_wait(uv_barrier_t* barrier);
+
 /* Waits on a condition variable without a timeout.
  *
  * Note:
@@ -2182,10 +2234,6 @@ UV_EXTERN void uv_cond_wait(uv_cond_t* cond, uv_mutex_t* mutex);
 UV_EXTERN int uv_cond_timedwait(uv_cond_t* cond, uv_mutex_t* mutex,
     uint64_t timeout);
 
-UV_EXTERN int uv_barrier_init(uv_barrier_t* barrier, unsigned int count);
-UV_EXTERN void uv_barrier_destroy(uv_barrier_t* barrier);
-UV_EXTERN void uv_barrier_wait(uv_barrier_t* barrier);
-
 /* Runs a function once and only once. Concurrent calls to uv_once() with the
  * same guard will block all callers except one (it's unspecified which one).
  * The guard should be initialized statically with the UV_ONCE_INIT macro.
@@ -2204,8 +2252,14 @@ UV_EXTERN void uv_key_delete(uv_key_t* key);
 UV_EXTERN void* uv_key_get(uv_key_t* key);
 UV_EXTERN void uv_key_set(uv_key_t* key, void* value);
 
-UV_EXTERN int uv_thread_create(uv_thread_t *tid,
-    void (*entry)(void *arg), void *arg);
+/*
+ * Callback that is invoked to initialize thread execution.
+ *
+ * `arg` is the same value that was passed to uv_thread_create().
+ */
+typedef void (*uv_thread_cb)(void* arg);
+
+UV_EXTERN int uv_thread_create(uv_thread_t* tid, uv_thread_cb entry, void* arg);
 UV_EXTERN unsigned long uv_thread_self(void);
 UV_EXTERN int uv_thread_join(uv_thread_t *tid);
 
@@ -2246,6 +2300,7 @@ struct uv_loop_s {
 #undef UV_ASYNC_PRIVATE_FIELDS
 #undef UV_TIMER_PRIVATE_FIELDS
 #undef UV_GETADDRINFO_PRIVATE_FIELDS
+#undef UV_GETNAMEINFO_PRIVATE_FIELDS
 #undef UV_FS_REQ_PRIVATE_FIELDS
 #undef UV_WORK_PRIVATE_FIELDS
 #undef UV_FS_EVENT_PRIVATE_FIELDS
index 907abe6..1e2ed60 100644 (file)
@@ -227,6 +227,13 @@ HEAP_EXPORT(void heap_remove(struct heap* heap,
       break;
     heap_node_swap(heap, child, smallest);
   }
+
+  /* Walk up the subtree and check that each parent is less than the node
+   * this is required, because `max` node is not guaranteed to be the
+   * actual maximum in tree
+   */
+  while (child->parent != NULL && less_than(child, child->parent))
+    heap_node_swap(heap, child->parent, child);
 }
 
 HEAP_EXPORT(void heap_dequeue(struct heap* heap, heap_compare_fn less_than)) {
index 9220de6..c948b2e 100644 (file)
@@ -27,6 +27,9 @@
 #include "uv.h"
 #include "uv-common.h"
 
+#define UV__INET_ADDRSTRLEN         16
+#define UV__INET6_ADDRSTRLEN        46
+
 
 static int inet_ntop4(const unsigned char *src, char *dst, size_t size);
 static int inet_ntop6(const unsigned char *src, char *dst, size_t size);
@@ -49,7 +52,7 @@ int uv_inet_ntop(int af, const void* src, char* dst, size_t size) {
 
 static int inet_ntop4(const unsigned char *src, char *dst, size_t size) {
   static const char fmt[] = "%u.%u.%u.%u";
-  char tmp[sizeof "255.255.255.255"];
+  char tmp[UV__INET_ADDRSTRLEN];
   int l;
 
 #ifndef _WIN32
@@ -74,7 +77,7 @@ static int inet_ntop6(const unsigned char *src, char *dst, size_t size) {
    * Keep this in mind if you think this function should have been coded
    * to use pointer overlays.  All the world's not a VAX.
    */
-  char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"], *tp;
+  char tmp[UV__INET6_ADDRSTRLEN], *tp;
   struct { int base, len; } best, cur;
   unsigned int words[sizeof(struct in6_addr) / sizeof(uint16_t)];
   int i;
@@ -156,11 +159,27 @@ static int inet_ntop6(const unsigned char *src, char *dst, size_t size) {
 
 
 int uv_inet_pton(int af, const char* src, void* dst) {
+  if (src == NULL || dst == NULL)
+    return UV_EINVAL;
+
   switch (af) {
   case AF_INET:
     return (inet_pton4(src, dst));
-  case AF_INET6:
-    return (inet_pton6(src, dst));
+  case AF_INET6: {
+    int len;
+    char tmp[UV__INET6_ADDRSTRLEN], *s, *p;
+    s = (char*) src;
+    p = strchr(src, '%');
+    if (p != NULL) {
+      s = tmp;
+      len = p - src;
+      if (len > UV__INET6_ADDRSTRLEN-1)
+        return UV_EINVAL;
+      memcpy(s, src, len);
+      s[len] = '\0';
+    }
+    return inet_pton6(s, dst);
+  }
   default:
     return UV_EAFNOSUPPORT;
   }
@@ -225,7 +244,7 @@ static int inet_pton6(const char *src, unsigned char *dst) {
   curtok = src;
   seen_xdigits = 0;
   val = 0;
-  while ((ch = *src++) != '\0' && ch != '%') {
+  while ((ch = *src++) != '\0') {
     const char *pch;
 
     if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL)
@@ -256,19 +275,7 @@ static int inet_pton6(const char *src, unsigned char *dst) {
       continue;
     }
     if (ch == '.' && ((tp + sizeof(struct in_addr)) <= endp)) {
-      int err;
-
-      /* Scope id present, parse ipv4 addr without it */
-      pch = strchr(curtok, '%');
-      if (pch != NULL) {
-        char tmp[sizeof "255.255.255.255"];
-
-        memcpy(tmp, curtok, pch - curtok);
-        curtok = tmp;
-        src = pch;
-      }
-
-      err = inet_pton4(curtok, tp);
+      int err = inet_pton4(curtok, tp);
       if (err == 0) {
         tp += sizeof(struct in_addr);
         seen_xdigits = 0;
index 5ef787c..b794ea6 100644 (file)
@@ -231,7 +231,7 @@ int uv__async_start(uv_loop_t* loop, struct uv__async* wa, uv__async_cb cb) {
 
       snprintf(buf, sizeof(buf), "/proc/self/fd/%d", pipefd[0]);
       fd = uv__open_cloexec(buf, O_RDWR);
-      if (fd != -1) {
+      if (fd >= 0) {
         uv__close(pipefd[0]);
         uv__close(pipefd[1]);
         pipefd[0] = fd;
index 9680a2d..402bb00 100644 (file)
@@ -283,9 +283,9 @@ int uv_run(uv_loop_t* loop, uv_run_mode mode) {
 
     uv__update_time(loop);
     uv__run_timers(loop);
+    uv__run_pending(loop);
     uv__run_idle(loop);
     uv__run_prepare(loop);
-    uv__run_pending(loop);
 
     timeout = 0;
     if ((mode & UV_RUN_NOWAIT) == 0)
index bc282e7..c9a45ed 100644 (file)
@@ -53,9 +53,11 @@ void uv__platform_loop_delete(uv_loop_t* loop) {
 
 
 uint64_t uv__hrtime(uv_clocktype_t type) {
-  mach_timebase_info_data_t info;
+  static mach_timebase_info_data_t info;
 
-  if (mach_timebase_info(&info) != KERN_SUCCESS)
+  if ((ACCESS_ONCE(uint32_t, info.numer) == 0 ||
+       ACCESS_ONCE(uint32_t, info.denom) == 0) &&
+      mach_timebase_info(&info) != KERN_SUCCESS)
     abort();
 
   return mach_absolute_time() * info.numer / info.denom;
index cbffe4a..ad45fc8 100644 (file)
@@ -59,7 +59,7 @@ int uv_dlsym(uv_lib_t* lib, const char* name, void** ptr) {
 }
 
 
-const char* uv_dlerror(uv_lib_t* lib) {
+const char* uv_dlerror(const uv_lib_t* lib) {
   return lib->errmsg ? lib->errmsg : "no error";
 }
 
index dcae244..d59e377 100644 (file)
@@ -298,7 +298,7 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
 
   for (i = 0; i < numcpus; i++) {
     cpu_info = &(*cpu_infos)[i];
-    
+
     cpu_info->cpu_times.user = (uint64_t)(cp_times[CP_USER+cur]) * multiplier;
     cpu_info->cpu_times.nice = (uint64_t)(cp_times[CP_NICE+cur]) * multiplier;
     cpu_info->cpu_times.sys = (uint64_t)(cp_times[CP_SYS+cur]) * multiplier;
diff --git a/deps/uv/src/unix/getnameinfo.c b/deps/uv/src/unix/getnameinfo.c
new file mode 100644 (file)
index 0000000..c3fb983
--- /dev/null
@@ -0,0 +1,114 @@
+/* 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 <assert.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "uv.h"
+#include "internal.h"
+
+
+static void uv__getnameinfo_work(struct uv__work* w) {
+  uv_getnameinfo_t* req;
+  int err;
+  socklen_t salen;
+
+  req = container_of(w, uv_getnameinfo_t, work_req);
+
+  if (req->storage.ss_family == AF_INET)
+    salen = sizeof(struct sockaddr_in);
+  else if (req->storage.ss_family == AF_INET6)
+    salen = sizeof(struct sockaddr_in6);
+  else
+    abort();
+
+  err = getnameinfo((struct sockaddr*) &req->storage,
+                    salen,
+                    req->host,
+                    sizeof(req->host),
+                    req->service,
+                    sizeof(req->service),
+                    req->flags);
+  req->retcode = uv__getaddrinfo_translate_error(err);
+}
+
+static void uv__getnameinfo_done(struct uv__work* w, int status) {
+  uv_getnameinfo_t* req;
+  char* host;
+  char* service;
+
+  req = container_of(w, uv_getnameinfo_t, work_req);
+  uv__req_unregister(req->loop, req);
+  host = service = NULL;
+
+  if (status == -ECANCELED) {
+    assert(req->retcode == 0);
+    req->retcode = UV_EAI_CANCELED;
+  } else if (req->retcode == 0) {
+    host = req->host;
+    service = req->service;
+  }
+
+  req->getnameinfo_cb(req, req->retcode, host, service);
+}
+
+/*
+* Entry point for getnameinfo
+* return 0 if a callback will be made
+* return error code if validation fails
+*/
+int uv_getnameinfo(uv_loop_t* loop,
+                   uv_getnameinfo_t* req,
+                   uv_getnameinfo_cb getnameinfo_cb,
+                   const struct sockaddr* addr,
+                   int flags) {
+  if (req == NULL || getnameinfo_cb == NULL || addr == NULL)
+    return UV_EINVAL;
+
+  if (addr->sa_family == AF_INET) {
+    memcpy(&req->storage,
+           addr,
+           sizeof(struct sockaddr_in));
+  } else if (addr->sa_family == AF_INET6) {
+    memcpy(&req->storage,
+           addr,
+           sizeof(struct sockaddr_in6));
+  } else {
+    return UV_EINVAL;
+  }
+
+  uv__req_init(loop, (uv_req_t*)req, UV_GETNAMEINFO);
+
+  req->getnameinfo_cb = getnameinfo_cb;
+  req->flags = flags;
+  req->type = UV_GETNAMEINFO;
+  req->loop = loop;
+  req->retcode = 0;
+
+  uv__work_submit(loop,
+                  &req->work_req,
+                  uv__getnameinfo_work,
+                  uv__getnameinfo_done);
+
+  return 0;
+}
index 7706417..b4f9f5d 100644 (file)
@@ -377,7 +377,7 @@ fallback:
 
 int uv_fs_event_stop(uv_fs_event_t* handle) {
   if (!uv__is_active(handle))
-    return -EINVAL;
+    return 0;
 
   uv__handle_stop(handle);
 
index 20bc173..2ecc5eb 100644 (file)
@@ -231,7 +231,7 @@ int uv_fs_event_stop(uv_fs_event_t* handle) {
   struct watcher_list* w;
 
   if (!uv__is_active(handle))
-    return -EINVAL;
+    return 0;
 
   w = find_watcher(handle->loop, handle->wd);
   assert(w != NULL);
index f052d80..75ba921 100644 (file)
@@ -267,7 +267,7 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
     }
 
     cpu_info = &(*cpu_infos)[i];
-    
+
     cpu_info->cpu_times.user = (uint64_t)(info[CP_USER]) * multiplier;
     cpu_info->cpu_times.nice = (uint64_t)(info[CP_NICE]) * multiplier;
     cpu_info->cpu_times.sys = (uint64_t)(info[CP_SYS]) * multiplier;
index ac943ec..43334f0 100644 (file)
@@ -444,6 +444,7 @@ void uv__stream_destroy(uv_stream_t* stream) {
  */
 static int uv__emfile_trick(uv_loop_t* loop, int accept_fd) {
   int err;
+  int emfile_fd;
 
   if (loop->emfile_fd == -1)
     return -EMFILE;
@@ -457,7 +458,10 @@ static int uv__emfile_trick(uv_loop_t* loop, int accept_fd) {
       uv__close(err);
   } while (err >= 0 || err == -EINTR);
 
-  SAVE_ERRNO(loop->emfile_fd = uv__open_cloexec("/", O_RDONLY));
+  emfile_fd = uv__open_cloexec("/", O_RDONLY);
+  if (emfile_fd >= 0)
+    loop->emfile_fd = emfile_fd;
+
   return err;
 }
 
index b8a39c7..a630dba 100644 (file)
@@ -431,7 +431,7 @@ int uv_fs_event_start(uv_fs_event_t* handle,
 
 int uv_fs_event_stop(uv_fs_event_t* handle) {
   if (!uv__is_active(handle))
-    return -EINVAL;
+    return 0;
 
   if (handle->fd == PORT_FIRED || handle->fd == PORT_LOADED) {
     port_dissociate(handle->loop->fs_fd,
index f2ce082..522426f 100644 (file)
@@ -399,7 +399,9 @@ void uv_barrier_destroy(uv_barrier_t* barrier) {
 }
 
 
-void uv_barrier_wait(uv_barrier_t* barrier) {
+int uv_barrier_wait(uv_barrier_t* barrier) {
+  int serial_thread;
+
   uv_mutex_lock(&barrier->mutex);
   if (++barrier->count == barrier->n) {
     uv_sem_wait(&barrier->turnstile2);
@@ -411,7 +413,8 @@ void uv_barrier_wait(uv_barrier_t* barrier) {
   uv_sem_post(&barrier->turnstile1);
 
   uv_mutex_lock(&barrier->mutex);
-  if (--barrier->count == 0) {
+  serial_thread = (--barrier->count == 0);
+  if (serial_thread) {
     uv_sem_wait(&barrier->turnstile1);
     uv_sem_post(&barrier->turnstile2);
   }
@@ -419,6 +422,7 @@ void uv_barrier_wait(uv_barrier_t* barrier) {
 
   uv_sem_wait(&barrier->turnstile2);
   uv_sem_post(&barrier->turnstile2);
+  return serial_thread;
 }
 
 #else /* !(defined(__APPLE__) && defined(__MACH__)) */
@@ -434,10 +438,11 @@ void uv_barrier_destroy(uv_barrier_t* barrier) {
 }
 
 
-void uv_barrier_wait(uv_barrier_t* barrier) {
+int uv_barrier_wait(uv_barrier_t* barrier) {
   int r = pthread_barrier_wait(barrier);
   if (r && r != PTHREAD_BARRIER_SERIAL_THREAD)
     abort();
+  return r == PTHREAD_BARRIER_SERIAL_THREAD;
 }
 
 #endif /* defined(__APPLE__) && defined(__MACH__) */
index f2eb1cb..1868724 100644 (file)
@@ -268,6 +268,10 @@ int uv_cancel(uv_req_t* req) {
     loop =  ((uv_getaddrinfo_t*) req)->loop;
     wreq = &((uv_getaddrinfo_t*) req)->work_req;
     break;
+  case UV_GETNAMEINFO:
+    loop = ((uv_getnameinfo_t*) req)->loop;
+    wreq = &((uv_getnameinfo_t*) req)->work_req;
+    break;
   case UV_WORK:
     loop =  ((uv_work_t*) req)->loop;
     wreq = &((uv_work_t*) req)->work_req;
index 206c65d..9556bd7 100644 (file)
@@ -320,9 +320,10 @@ int uv__udp_bind(uv_udp_t* handle,
 
   fd = handle->io_watcher.fd;
   if (fd == -1) {
-    fd = uv__socket(addr->sa_family, SOCK_DGRAM, 0);
-    if (fd == -1)
-      return -errno;
+    err = uv__socket(addr->sa_family, SOCK_DGRAM, 0);
+    if (err < 0)
+      return err;
+    fd = err;
     handle->io_watcher.fd = fd;
   }
 
@@ -628,7 +629,6 @@ int uv_udp_set_multicast_loop(uv_udp_t* handle, int on) {
 }
 
 int uv_udp_set_multicast_interface(uv_udp_t* handle, const char* interface_addr) {
-  int err;
   struct sockaddr_storage addr_st;
   struct sockaddr_in* addr4;
   struct sockaddr_in6* addr6;
@@ -654,9 +654,6 @@ int uv_udp_set_multicast_interface(uv_udp_t* handle, const char* interface_addr)
   }
 
   if (addr_st.ss_family == AF_INET) {
-    err = uv__udp_maybe_deferred_bind(handle, AF_INET, UV_UDP_REUSEADDR);
-    if (err)
-      return err;
     if (setsockopt(handle->io_watcher.fd,
                    IPPROTO_IP,
                    IP_MULTICAST_IF,
@@ -665,9 +662,6 @@ int uv_udp_set_multicast_interface(uv_udp_t* handle, const char* interface_addr)
       return -errno;
     }
   } else if (addr_st.ss_family == AF_INET6) {
-    err = uv__udp_maybe_deferred_bind(handle, AF_INET6, UV_UDP_REUSEADDR);
-    if (err)
-      return err;
     if (setsockopt(handle->io_watcher.fd,
                    IPPROTO_IPV6,
                    IPV6_MULTICAST_IF,
index 96f66d6..d9553c9 100644 (file)
@@ -35,7 +35,7 @@
 #include <stdlib.h> /* malloc */
 #include <string.h> /* memset */
 
-#if defined(UV_PLATFORM_HAS_IP6_LINK_LOCAL_ADDRESS) && !defined(_WIN32)
+#if !defined(_WIN32)
 # include <net/if.h> /* if_nametoindex */
 #endif
 
@@ -67,6 +67,11 @@ size_t uv_req_size(uv_req_type type) {
 #undef XX
 
 
+size_t uv_loop_size(void) {
+  return sizeof(uv_loop_t);
+}
+
+
 uv_buf_t uv_buf_init(char* base, unsigned int len) {
   uv_buf_t buf;
   buf.base = base;
@@ -107,17 +112,14 @@ int uv_ip4_addr(const char* ip, int port, struct sockaddr_in* addr) {
 
 
 int uv_ip6_addr(const char* ip, int port, struct sockaddr_in6* addr) {
-#if defined(UV_PLATFORM_HAS_IP6_LINK_LOCAL_ADDRESS)
   char address_part[40];
   size_t address_part_size;
   const char* zone_index;
-#endif
 
   memset(addr, 0, sizeof(*addr));
   addr->sin6_family = AF_INET6;
   addr->sin6_port = htons(port);
 
-#if defined(UV_PLATFORM_HAS_IP6_LINK_LOCAL_ADDRESS)
   zone_index = strchr(ip, '%');
   if (zone_index != NULL) {
     address_part_size = zone_index - ip;
@@ -136,7 +138,6 @@ int uv_ip6_addr(const char* ip, int port, struct sockaddr_in6* addr) {
     addr->sin6_scope_id = if_nametoindex(zone_index);
 #endif
   }
-#endif
 
   return uv_inet_pton(AF_INET6, ip, &addr->sin6_addr);
 }
@@ -437,7 +438,7 @@ int uv__getaddrinfo_translate_error(int sys_err) {
   case EAI_SOCKTYPE: return UV_EAI_SOCKTYPE;
 #endif
 #if defined(EAI_SYSTEM)
-  case EAI_SYSTEM: return UV_EAI_SYSTEM;
+  case EAI_SYSTEM: return -errno;
 #endif
   }
   assert(!"unknown EAI_* error code");
index f749ba9..540fb5f 100644 (file)
@@ -53,15 +53,15 @@ __declspec( thread ) int uv__crt_assert_enabled = TRUE;
 static int uv__crt_dbg_report_handler(int report_type, char *message, int *ret_val) {
   if (uv__crt_assert_enabled || report_type != _CRT_ASSERT)
     return FALSE;
-  
+
   if (ret_val) {
     /* Set ret_val to 0 to continue with normal execution. */
     /* Set ret_val to 1 to trigger a breakpoint. */
 
-    if(IsDebuggerPresent())     
-      *ret_val = 1;  
+    if(IsDebuggerPresent())
+      *ret_val = 1;
     else
-      *ret_val = 0;  
+      *ret_val = 0;
   }
 
   /* Don't call _CrtDbgReport. */
index d5b8f7c..2ef1f6c 100644 (file)
@@ -64,7 +64,7 @@ int uv_dlsym(uv_lib_t* lib, const char* name, void** ptr) {
 }
 
 
-const char* uv_dlerror(uv_lib_t* lib) {
+const char* uv_dlerror(const uv_lib_t* lib) {
   return lib->errmsg ? lib->errmsg : "no error";
 }
 
index f3de575..7ad99a8 100644 (file)
@@ -290,7 +290,7 @@ error:
 
 int uv_fs_event_stop(uv_fs_event_t* handle) {
   if (!uv__is_active(handle))
-    return UV_EINVAL;
+    return 0;
 
   if (handle->dir_handle != INVALID_HANDLE_VALUE) {
     CloseHandle(handle->dir_handle);
index 273ec39..f31c0a2 100644 (file)
@@ -553,7 +553,7 @@ void fs__read(uv_fs_t* req) {
   VERIFY_FD(fd, req);
 
   handle = uv__get_osfhandle(fd);
-  
+
   if (handle == INVALID_HANDLE_VALUE) {
     SET_REQ_WIN32_ERROR(req, ERROR_INVALID_HANDLE);
     return;
index fb4ab0a..b87a933 100644 (file)
@@ -113,8 +113,7 @@ void uv_process_getaddrinfo_req(uv_loop_t* loop, uv_getaddrinfo_t* req) {
       if (addrinfow_ptr->ai_canonname != NULL) {
         name_len = uv_utf16_to_utf8(addrinfow_ptr->ai_canonname, -1, NULL, 0);
         if (name_len == 0) {
-          /* FIXME(bnoordhuis) Retain GetLastError(). */
-          err = UV_EAI_SYSTEM;
+          err = uv_translate_sys_error(GetLastError());
           goto complete;
         }
         addrinfo_len += ALIGNED_SIZE(name_len);
diff --git a/deps/uv/src/win/getnameinfo.c b/deps/uv/src/win/getnameinfo.c
new file mode 100644 (file)
index 0000000..48eb16d
--- /dev/null
@@ -0,0 +1,138 @@
+/* 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 <assert.h>
+#include <malloc.h>
+#include <stdio.h>
+
+#include "uv.h"
+#include "internal.h"
+#include "req-inl.h"
+
+
+/* getnameinfo worker thread implementation */
+static DWORD WINAPI getnameinfo_thread_proc(void* parameter) {
+  uv_getnameinfo_t* req = (uv_getnameinfo_t*)parameter;
+  uv_loop_t* loop = req->loop;
+  WCHAR host[NI_MAXHOST];
+  WCHAR service[NI_MAXSERV];
+  int ret = 0;
+
+  assert(req != NULL);
+
+  ret = GetNameInfoW((struct sockaddr*)&req->storage,
+                     sizeof(req->storage),
+                     host,
+                     sizeof(host),
+                     service,
+                     sizeof(service),
+                     req->flags);
+  req->retcode = uv__getaddrinfo_translate_error(ret);
+
+  /* convert results to UTF-8 */
+  WideCharToMultiByte(CP_UTF8,
+                      0,
+                      host,
+                      -1,
+                      req->host,
+                      sizeof(req->host),
+                      NULL,
+                      NULL);
+
+  WideCharToMultiByte(CP_UTF8,
+                      0,
+                      service,
+                      -1,
+                      req->service,
+                      sizeof(req->service),
+                      NULL,
+                      NULL);
+
+  /* post getnameinfo completed */
+  POST_COMPLETION_FOR_REQ(loop, req);
+
+  return 0;
+}
+
+
+/*
+* Called from uv_run when complete.
+*/
+void uv_process_getnameinfo_req(uv_loop_t* loop, uv_getnameinfo_t* req) {
+  char* host;
+  char* service;
+
+  if (req->retcode == 0) {
+    host = req->host;
+    service = req->service;
+  } else {
+    host = NULL;
+    service = NULL;
+  }
+
+  uv__req_unregister(loop, req);
+  req->getnameinfo_cb(req, req->retcode, host, service);
+}
+
+
+/*
+* Entry point for getnameinfo
+* return 0 if a callback will be made
+* return error code if validation fails
+*/
+int uv_getnameinfo(uv_loop_t* loop,
+                   uv_getnameinfo_t* req,
+                   uv_getnameinfo_cb getnameinfo_cb,
+                   const struct sockaddr* addr,
+                   int flags) {
+  if (req == NULL || getnameinfo_cb == NULL || addr == NULL)
+    return UV_EINVAL;
+
+  if (addr->sa_family == AF_INET) {
+    memcpy(&req->storage,
+           addr,
+           sizeof(struct sockaddr_in));
+  } else if (addr->sa_family == AF_INET6) {
+    memcpy(&req->storage,
+           addr,
+           sizeof(struct sockaddr_in6));
+  } else {
+    return UV_EINVAL;
+  }
+
+  uv_req_init(loop, (uv_req_t*)req);
+
+  req->getnameinfo_cb = getnameinfo_cb;
+  req->flags = flags;
+  req->type = UV_GETNAMEINFO;
+  req->loop = loop;
+
+  /* Ask thread to run. Treat this as a long operation. */
+  if (QueueUserWorkItem(&getnameinfo_thread_proc,
+                        req,
+                        WT_EXECUTELONGFUNCTION) == 0) {
+    return uv_translate_sys_error(GetLastError());
+  }
+
+  uv__req_register(loop, req);
+
+  return 0;
+}
index 5776eb7..8d0334c 100644 (file)
@@ -168,7 +168,7 @@ INLINE static HANDLE uv__get_osfhandle(int fd)
   /* But  it also correctly checks the FD and returns INVALID_HANDLE_VALUE */
   /* for invalid FDs in release builds (or if you let the assert continue).  */
   /* So this wrapper function disables asserts when calling _get_osfhandle. */
-  
+
   HANDLE handle;
   UV_BEGIN_DISABLE_CRT_ASSERT();
   handle = (HANDLE) _get_osfhandle(fd);
index 45ce177..83c4a66 100644 (file)
@@ -43,7 +43,7 @@ extern __declspec( thread ) int uv__crt_assert_enabled;
   {                                                             \
     int uv__saved_crt_assert_enabled = uv__crt_assert_enabled;  \
     uv__crt_assert_enabled = FALSE;
-  
+
 
 #define UV_END_DISABLE_CRT_ASSERT()                             \
     uv__crt_assert_enabled = uv__saved_crt_assert_enabled;      \
@@ -292,6 +292,12 @@ void uv_process_getaddrinfo_req(uv_loop_t* loop, uv_getaddrinfo_t* req);
 
 
 /*
+* Getnameinfo
+*/
+void uv_process_getnameinfo_req(uv_loop_t* loop, uv_getnameinfo_t* req);
+
+
+/*
  * FS
  */
 void uv_fs_init();
index 394faeb..2fcedde 100644 (file)
@@ -115,7 +115,7 @@ static void uv_pipe_connection_init(uv_pipe_t* handle) {
 }
 
 
-static HANDLE open_named_pipe(WCHAR* name, DWORD* duplex_flags) {
+static HANDLE open_named_pipe(const WCHAR* name, DWORD* duplex_flags) {
   HANDLE pipeHandle;
 
   /*
index 1786c40..bf37399 100644 (file)
@@ -187,7 +187,8 @@ static void uv__fast_poll_process_poll_req(uv_loop_t* loop, uv_poll_t* handle,
     if (afd_poll_info->Handles[0].Events & AFD_POLL_LOCAL_CLOSE) {
       /* Stop polling. */
       handle->events = 0;
-      uv__handle_stop(handle);
+      if (uv__is_active(handle))
+        uv__handle_stop(handle);
     }
 
     if (events != 0) {
index d52c837..7a85858 100644 (file)
@@ -430,11 +430,10 @@ WCHAR* quote_cmd_arg(const WCHAR *source, WCHAR *target) {
   int quote_hit;
   WCHAR* start;
 
-  /*
-   * Check if the string must be quoted;
-   * if unnecessary, don't do it, it may only confuse older programs.
-   */
   if (len == 0) {
+    /* Need double quotation for empty argument */
+    *(target++) = L'"';
+    *(target++) = L'"';
     return target;
   }
 
@@ -965,7 +964,7 @@ int uv_spawn(uv_loop_t* loop,
 
   /* Spawn succeeded */
   /* Beyond this point, failure is reported asynchronously. */
-  
+
   process->process_handle = info.hProcess;
   process->pid = info.dwProcessId;
 
@@ -1011,8 +1010,8 @@ int uv_spawn(uv_loop_t* loop,
 
   CloseHandle(info.hThread);
 
-  assert(!err);  
-  
+  assert(!err);
+
   /* Make the handle active. It will remain active until the exit callback */
   /* iis made or the handle is closed, whichever happens first. */
   uv__handle_start(process);
index 353fe90..cbc2ba8 100644 (file)
@@ -199,6 +199,10 @@ INLINE static void uv_process_reqs(uv_loop_t* loop) {
         uv_process_getaddrinfo_req(loop, (uv_getaddrinfo_t*) req);
         break;
 
+      case UV_GETNAMEINFO:
+        uv_process_getnameinfo_req(loop, (uv_getnameinfo_t*)req);
+        break;
+
       case UV_PROCESS_EXIT:
         uv_process_proc_exit(loop, (uv_process_t*) req->data);
         break;
index 9d1c767..ccd7a11 100644 (file)
@@ -244,7 +244,7 @@ static int uv_tcp_try_bind(uv_tcp_t* handle,
 
   if (handle->socket == INVALID_SOCKET) {
     SOCKET sock;
-    
+
     /* Cannot set IPv6-only mode on non-IPv6 socket. */
     if ((flags & UV_TCP_IPV6ONLY) && addr->sa_family != AF_INET6)
       return ERROR_INVALID_PARAMETER;
@@ -810,7 +810,6 @@ int uv_tcp_write(uv_loop_t* loop,
   req->type = UV_WRITE;
   req->handle = (uv_stream_t*) handle;
   req->cb = cb;
-  memset(&req->overlapped, 0, sizeof(req->overlapped));
 
   /* Prepare the overlapped structure. */
   memset(&(req->overlapped), 0, sizeof(req->overlapped));
index 5178f8f..ccc5579 100644 (file)
@@ -660,7 +660,9 @@ void uv_barrier_destroy(uv_barrier_t* barrier) {
 }
 
 
-void uv_barrier_wait(uv_barrier_t* barrier) {
+int uv_barrier_wait(uv_barrier_t* barrier) {
+  int serial_thread;
+
   uv_mutex_lock(&barrier->mutex);
   if (++barrier->count == barrier->n) {
     uv_sem_wait(&barrier->turnstile2);
@@ -672,7 +674,8 @@ void uv_barrier_wait(uv_barrier_t* barrier) {
   uv_sem_post(&barrier->turnstile1);
 
   uv_mutex_lock(&barrier->mutex);
-  if (--barrier->count == 0) {
+  serial_thread = (--barrier->count == 0);
+  if (serial_thread) {
     uv_sem_wait(&barrier->turnstile1);
     uv_sem_post(&barrier->turnstile2);
   }
@@ -680,6 +683,7 @@ void uv_barrier_wait(uv_barrier_t* barrier) {
 
   uv_sem_wait(&barrier->turnstile2);
   uv_sem_post(&barrier->turnstile2);
+  return serial_thread;
 }
 
 
index 7840fb2..87e3eb5 100644 (file)
@@ -48,6 +48,8 @@
 #define ANSI_IN_STRING        0x40
 #define ANSI_BACKSLASH_SEEN   0x80
 
+#define MAX_INPUT_BUFFER_LENGTH 8192
+
 
 static void uv_tty_update_virtual_window(CONSOLE_SCREEN_BUFFER_INFO* info);
 
@@ -303,6 +305,8 @@ static DWORD CALLBACK uv_tty_line_read_thread(void* data) {
   uv_tty_t* handle;
   uv_req_t* req;
   DWORD bytes, read_bytes;
+  WCHAR utf16[MAX_INPUT_BUFFER_LENGTH / 3];
+  DWORD chars, read_chars;
 
   assert(data);
 
@@ -314,18 +318,29 @@ static DWORD CALLBACK uv_tty_line_read_thread(void* data) {
   assert(handle->read_line_buffer.len > 0);
 
   /* ReadConsole can't handle big buffers. */
-  if (handle->read_line_buffer.len < 8192) {
+  if (handle->read_line_buffer.len < MAX_INPUT_BUFFER_LENGTH) {
     bytes = handle->read_line_buffer.len;
   } else {
-    bytes = 8192;
+    bytes = MAX_INPUT_BUFFER_LENGTH;
   }
 
-  /* Todo: Unicode */
-  if (ReadConsoleA(handle->read_line_handle,
-                   (void*) handle->read_line_buffer.base,
-                   bytes,
-                   &read_bytes,
+  /* At last, unicode! */
+  /* One utf-16 codeunit never takes more than 3 utf-8 codeunits to encode */
+  chars = bytes / 3;
+
+  if (ReadConsoleW(handle->read_line_handle,
+                   (void*) utf16,
+                   chars,
+                   &read_chars,
                    NULL)) {
+    read_bytes = WideCharToMultiByte(CP_UTF8,
+                                     0,
+                                     utf16,
+                                     read_chars,
+                                     handle->read_line_buffer.base,
+                                     bytes,
+                                     NULL,
+                                     NULL);
     SET_REQ_SUCCESS(req);
     req->overlapped.InternalHigh = read_bytes;
   } else {
@@ -1117,6 +1132,14 @@ static int uv_tty_clear(uv_tty_t* handle, int dir, char entire_screen,
   return 0;
 }
 
+#define FLIP_FGBG                                                             \
+    do {                                                                      \
+      WORD fg = info.wAttributes & 0xF;                                       \
+      WORD bg = info.wAttributes & 0xF0;                                      \
+      info.wAttributes &= 0xFF00;                                             \
+      info.wAttributes |= fg << 4;                                            \
+      info.wAttributes |= bg >> 4;                                            \
+    } while (0)
 
 static int uv_tty_set_style(uv_tty_t* handle, DWORD* error) {
   unsigned short argc = handle->ansi_csi_argc;
@@ -1126,6 +1149,7 @@ static int uv_tty_set_style(uv_tty_t* handle, DWORD* error) {
 
   char fg_color = -1, bg_color = -1;
   char fg_bright = -1, bg_bright = -1;
+  char inverse = -1;
 
   if (argc == 0) {
     /* Reset mode */
@@ -1133,6 +1157,7 @@ static int uv_tty_set_style(uv_tty_t* handle, DWORD* error) {
     bg_color = 0;
     fg_bright = 0;
     bg_bright = 0;
+    inverse = 0;
   }
 
   for (i = 0; i < argc; i++) {
@@ -1144,6 +1169,7 @@ static int uv_tty_set_style(uv_tty_t* handle, DWORD* error) {
       bg_color = 0;
       fg_bright = 0;
       bg_bright = 0;
+      inverse = 0;
 
     } else if (arg == 1) {
       /* Foreground bright on */
@@ -1158,6 +1184,10 @@ static int uv_tty_set_style(uv_tty_t* handle, DWORD* error) {
       /* Background bright on */
       bg_bright = 1;
 
+    } else if (arg == 7) {
+      /* Inverse: on */
+      inverse = 1;
+
     } else if (arg == 21 || arg == 22) {
       /* Foreground bright off */
       fg_bright = 0;
@@ -1166,6 +1196,10 @@ static int uv_tty_set_style(uv_tty_t* handle, DWORD* error) {
       /* Background bright off */
       bg_bright = 0;
 
+    } else if (arg == 27) {
+      /* Inverse: off */
+      inverse = 0;
+
     } else if (arg >= 30 && arg <= 37) {
       /* Set foreground color */
       fg_color = arg - 30;
@@ -1198,7 +1232,7 @@ static int uv_tty_set_style(uv_tty_t* handle, DWORD* error) {
   }
 
   if (fg_color == -1 && bg_color == -1 && fg_bright == -1 &&
-      bg_bright == -1) {
+      bg_bright == -1 && inverse == -1) {
     /* Nothing changed */
     return 0;
   }
@@ -1208,6 +1242,10 @@ static int uv_tty_set_style(uv_tty_t* handle, DWORD* error) {
     return -1;
   }
 
+  if ((info.wAttributes & COMMON_LVB_REVERSE_VIDEO) > 0) {
+    FLIP_FGBG;
+  }
+
   if (fg_color != -1) {
     info.wAttributes &= ~(FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
     if (fg_color & 1) info.wAttributes |= FOREGROUND_RED;
@@ -1238,6 +1276,18 @@ static int uv_tty_set_style(uv_tty_t* handle, DWORD* error) {
     }
   }
 
+  if (inverse != -1) {
+    if (inverse) {
+      info.wAttributes |= COMMON_LVB_REVERSE_VIDEO;
+    } else {
+      info.wAttributes &= ~COMMON_LVB_REVERSE_VIDEO;
+    }
+  }
+
+  if ((info.wAttributes & COMMON_LVB_REVERSE_VIDEO) > 0) {
+    FLIP_FGBG;
+  }
+
   if (!SetConsoleTextAttribute(handle->handle, info.wAttributes)) {
     *error = GetLastError();
     return -1;
@@ -1316,6 +1366,25 @@ static int uv_tty_restore_state(uv_tty_t* handle,
   return 0;
 }
 
+static int uv_tty_set_cursor_visibility(uv_tty_t* handle,
+                                        BOOL visible,
+                                        DWORD* error) {
+  CONSOLE_CURSOR_INFO cursor_info;
+
+  if (!GetConsoleCursorInfo(handle->handle, &cursor_info)) {
+    *error = GetLastError();
+    return -1;
+  }
+
+  cursor_info.bVisible = visible;
+
+  if (!SetConsoleCursorInfo(handle->handle, &cursor_info)) {
+    *error = GetLastError();
+    return -1;
+  }
+
+  return 0;
+}
 
 static int uv_tty_write_bufs(uv_tty_t* handle,
                              const uv_buf_t bufs[],
@@ -1527,6 +1596,13 @@ static int uv_tty_write_bufs(uv_tty_t* handle,
               continue;
             }
 
+          } else if (utf8_codepoint == '?' && !(ansi_parser_state & ANSI_IN_ARG) &&
+                     handle->ansi_csi_argc == 0) {
+            /* Ignores '?' if it is the first character after CSI[ */
+            /* This is an extension character from the VT100 codeset */
+            /* that is supported and used by most ANSI terminals today. */
+            continue;
+
           } else if (utf8_codepoint >= '@' && utf8_codepoint <= '~' &&
                      (handle->ansi_csi_argc > 0 || utf8_codepoint != '[')) {
             int x, y, d;
@@ -1629,6 +1705,24 @@ static int uv_tty_write_bufs(uv_tty_t* handle,
                 FLUSH_TEXT();
                 uv_tty_restore_state(handle, 0, error);
                 break;
+
+              case 'l':
+                /* Hide the cursor */
+                if (handle->ansi_csi_argc == 1 &&
+                    handle->ansi_csi_argv[0] == 25) {
+                  FLUSH_TEXT();
+                  uv_tty_set_cursor_visibility(handle, 0, error);
+                }
+                break;
+
+              case 'h':
+                /* Show the cursor */
+                if (handle->ansi_csi_argc == 1 &&
+                    handle->ansi_csi_argv[0] == 25) {
+                  FLUSH_TEXT();
+                  uv_tty_set_cursor_visibility(handle, 1, error);
+                }
+                break;
             }
 
             /* Sequence ended - go back to normal state. */
index 8719fa7..8658904 100644 (file)
@@ -662,7 +662,6 @@ int uv_udp_set_membership(uv_udp_t* handle,
 
 
 int uv_udp_set_multicast_interface(uv_udp_t* handle, const char* interface_addr) {
-  int err;
   struct sockaddr_storage addr_st;
   struct sockaddr_in* addr4;
   struct sockaddr_in6* addr6;
@@ -687,13 +686,10 @@ int uv_udp_set_multicast_interface(uv_udp_t* handle, const char* interface_addr)
     return UV_EINVAL;
   }
 
+  if (!(handle->flags & UV_HANDLE_BOUND))
+    return UV_EBADF;
+
   if (addr_st.ss_family == AF_INET) {
-    err = uv_udp_maybe_bind(handle,
-                            (const struct sockaddr*) &uv_addr_ip4_any_,
-                            sizeof(uv_addr_ip4_any_),
-                            UV_UDP_REUSEADDR);
-    if (err)
-      return uv_translate_sys_error(err);
     if (setsockopt(handle->socket,
                    IPPROTO_IP,
                    IP_MULTICAST_IF,
@@ -702,12 +698,6 @@ int uv_udp_set_multicast_interface(uv_udp_t* handle, const char* interface_addr)
       return uv_translate_sys_error(WSAGetLastError());
     }
   } else if (addr_st.ss_family == AF_INET6) {
-    err = uv_udp_maybe_bind(handle,
-                            (const struct sockaddr*) &uv_addr_ip6_any_,
-                            sizeof(uv_addr_ip6_any_),
-                            UV_UDP_REUSEADDR);
-    if (err)
-      return uv_translate_sys_error(err);
     if (setsockopt(handle->socket,
                    IPPROTO_IPV6,
                    IPV6_MULTICAST_IF,
@@ -726,15 +716,9 @@ int uv_udp_set_multicast_interface(uv_udp_t* handle, const char* interface_addr)
 
 int uv_udp_set_broadcast(uv_udp_t* handle, int value) {
   BOOL optval = (BOOL) value;
-  int err;
 
-  /* If the socket is unbound, bind to inaddr_any. */
-  err = uv_udp_maybe_bind(handle,
-                          (const struct sockaddr*) &uv_addr_ip4_any_,
-                          sizeof(uv_addr_ip4_any_),
-                          0);
-  if (err)
-    return uv_translate_sys_error(err);
+  if (!(handle->flags & UV_HANDLE_BOUND))
+    return UV_EBADF;
 
   if (setsockopt(handle->socket,
                  SOL_SOCKET,
@@ -774,19 +758,13 @@ int uv_udp_open(uv_udp_t* handle, uv_os_sock_t sock) {
 #define SOCKOPT_SETTER(name, option4, option6, validate)                      \
   int uv_udp_set_##name(uv_udp_t* handle, int value) {                        \
     DWORD optval = (DWORD) value;                                             \
-    int err;                                                                  \
                                                                               \
     if (!(validate(value))) {                                                 \
       return UV_EINVAL;                                                       \
     }                                                                         \
                                                                               \
-    /* If the socket is unbound, bind to inaddr_any. */                       \
-    err = uv_udp_maybe_bind(handle,                                           \
-                            (const struct sockaddr*) &uv_addr_ip4_any_,       \
-                            sizeof(uv_addr_ip4_any_),                         \
-                            0);                                               \
-    if (err)                                                                  \
-      return uv_translate_sys_error(err);                                     \
+    if (!(handle->flags & UV_HANDLE_BOUND))                                   \
+      return UV_EBADF;                                                        \
                                                                               \
     if (!(handle->flags & UV_HANDLE_IPV6)) {                                  \
       /* Set IPv4 socket option */                                            \
index d4173c5..a56fbea 100644 (file)
@@ -314,8 +314,7 @@ uint64_t uv_get_free_memory(void) {
   MEMORYSTATUSEX memory_status;
   memory_status.dwLength = sizeof(memory_status);
 
-  if(!GlobalMemoryStatusEx(&memory_status))
-  {
+  if (!GlobalMemoryStatusEx(&memory_status)) {
      return -1;
   }
 
@@ -327,8 +326,7 @@ uint64_t uv_get_total_memory(void) {
   MEMORYSTATUSEX memory_status;
   memory_status.dwLength = sizeof(memory_status);
 
-  if(!GlobalMemoryStatusEx(&memory_status))
-  {
+  if (!GlobalMemoryStatusEx(&memory_status)) {
     return -1;
   }
 
@@ -388,7 +386,7 @@ int uv_set_process_title(const char* title) {
   if (!length) {
     err = GetLastError();
     goto done;
-  };
+  }
 
   /* If the title must be truncated insert a \0 terminator there */
   if (length > MAX_TITLE_LENGTH) {
index 97df704..25a55d6 100644 (file)
@@ -29,6 +29,8 @@ typedef struct {
   uv_barrier_t barrier;
   int delay;
   volatile int posted;
+  int main_barrier_wait_rval;
+  int worker_barrier_wait_rval;
 } worker_config;
 
 
@@ -38,7 +40,11 @@ static void worker(void* arg) {
   if (c->delay)
     uv_sleep(c->delay);
 
-  uv_barrier_wait(&c->barrier);
+  c->worker_barrier_wait_rval = uv_barrier_wait(&c->barrier);
+  if (c->worker_barrier_wait_rval == 1) {
+    uv_barrier_destroy(&c->barrier);
+    ASSERT(c->main_barrier_wait_rval == 0);
+  }
 }
 
 
@@ -47,15 +53,22 @@ TEST_IMPL(barrier_1) {
   worker_config wc;
 
   memset(&wc, 0, sizeof(wc));
+  wc.main_barrier_wait_rval = -1;
+  wc.worker_barrier_wait_rval = -1;
 
   ASSERT(0 == uv_barrier_init(&wc.barrier, 2));
   ASSERT(0 == uv_thread_create(&thread, worker, &wc));
 
   uv_sleep(100);
-  uv_barrier_wait(&wc.barrier);
+
+  wc.main_barrier_wait_rval = uv_barrier_wait(&wc.barrier);
+  if (wc.main_barrier_wait_rval == 1) {
+    uv_barrier_destroy(&wc.barrier);
+    ASSERT(wc.worker_barrier_wait_rval == 0);
+  }
 
   ASSERT(0 == uv_thread_join(&thread));
-  uv_barrier_destroy(&wc.barrier);
+  ASSERT(1 == (wc.main_barrier_wait_rval ^ wc.worker_barrier_wait_rval));
 
   return 0;
 }
@@ -67,14 +80,20 @@ TEST_IMPL(barrier_2) {
 
   memset(&wc, 0, sizeof(wc));
   wc.delay = 100;
+  wc.main_barrier_wait_rval = -1;
+  wc.worker_barrier_wait_rval = -1;
 
   ASSERT(0 == uv_barrier_init(&wc.barrier, 2));
   ASSERT(0 == uv_thread_create(&thread, worker, &wc));
 
-  uv_barrier_wait(&wc.barrier);
+  wc.main_barrier_wait_rval = uv_barrier_wait(&wc.barrier);
+  if (wc.main_barrier_wait_rval == 1) {
+    uv_barrier_destroy(&wc.barrier);
+    ASSERT(wc.worker_barrier_wait_rval == 0);
+  }
 
   ASSERT(0 == uv_thread_join(&thread));
-  uv_barrier_destroy(&wc.barrier);
+  ASSERT(1 == (wc.main_barrier_wait_rval ^ wc.worker_barrier_wait_rval));
 
   return 0;
 }
@@ -85,14 +104,20 @@ TEST_IMPL(barrier_3) {
   worker_config wc;
 
   memset(&wc, 0, sizeof(wc));
+  wc.main_barrier_wait_rval = -1;
+  wc.worker_barrier_wait_rval = -1;
 
   ASSERT(0 == uv_barrier_init(&wc.barrier, 2));
   ASSERT(0 == uv_thread_create(&thread, worker, &wc));
 
-  uv_barrier_wait(&wc.barrier);
+  wc.main_barrier_wait_rval = uv_barrier_wait(&wc.barrier);
+  if (wc.main_barrier_wait_rval == 1) {
+    uv_barrier_destroy(&wc.barrier);
+    ASSERT(wc.worker_barrier_wait_rval == 0);
+  }
 
   ASSERT(0 == uv_thread_join(&thread));
-  uv_barrier_destroy(&wc.barrier);
+  ASSERT(1 == (wc.main_barrier_wait_rval ^ wc.worker_barrier_wait_rval));
 
   return 0;
 }
index 306ec6b..40c7726 100644 (file)
 # include <io.h>
 # define unlink _unlink
 # define rmdir _rmdir
-# define stat _stati64
 # define open _open
 # define write _write
-# define lseek _lseek
 # define close _close
+# ifndef stat
+#  define stat _stati64
+# endif
+# ifndef lseek
+#   define lseek _lseek
+# endif
 #endif
 
 #define TOO_LONG_NAME_LENGTH 65536
diff --git a/deps/uv/test/test-getnameinfo.c b/deps/uv/test/test-getnameinfo.c
new file mode 100644 (file)
index 0000000..1ea0f3a
--- /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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+
+static const char* address_ip4 = "127.0.0.1";
+static const char* address_ip6 = "::1";
+static const int port = 80;
+
+static struct sockaddr_in addr4;
+static struct sockaddr_in6 addr6;
+static uv_getnameinfo_t req;
+
+static void getnameinfo_req(uv_getnameinfo_t* handle,
+                            int status,
+                            const char* hostname,
+                            const char* service) {
+  ASSERT(handle != NULL);
+  ASSERT(status == 0);
+  ASSERT(hostname != NULL);
+  ASSERT(service != NULL);
+}
+
+TEST_IMPL(getnameinfo_basic_ip4) {
+  int r;
+
+  r = uv_ip4_addr(address_ip4, port, &addr4);
+  ASSERT(r == 0);
+
+  r = uv_getnameinfo(uv_default_loop(),
+                     &req,
+                     &getnameinfo_req,
+                     (const struct sockaddr*)&addr4,
+                     0);
+  ASSERT(r == 0);
+
+  uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+
+  MAKE_VALGRIND_HAPPY();
+  return 0;
+}
+
+TEST_IMPL(getnameinfo_basic_ip6) {
+  int r;
+
+  r = uv_ip6_addr(address_ip6, port, &addr6);
+  ASSERT(r == 0);
+
+  r = uv_getnameinfo(uv_default_loop(),
+                     &req,
+                     &getnameinfo_req,
+                     (const struct sockaddr*)&addr6,
+                     0);
+  ASSERT(r == 0);
+
+  uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+
+  MAKE_VALGRIND_HAPPY();
+  return 0;
+}
index 0d2606e..cf8491f 100644 (file)
@@ -32,7 +32,6 @@
 
 
 TEST_IMPL(ip6_addr_link_local) {
-#ifdef UV_PLATFORM_HAS_IP6_LINK_LOCAL_ADDRESS
   char string_address[INET6_ADDRSTRLEN];
   uv_interface_address_t* addresses;
   uv_interface_address_t* address;
@@ -93,9 +92,6 @@ TEST_IMPL(ip6_addr_link_local) {
 
   MAKE_VALGRIND_HAPPY();
   return 0;
-#else
-  RETURN_SKIP("Qualified link-local addresses are not supported.");
-#endif
 }
 
 
@@ -107,6 +103,7 @@ TEST_IMPL(ip6_addr_link_local) {
     X("fe80::2acf:daff:fedd:342a")                                            \
     X("fe80:0:0:0:2acf:daff:fedd:342a")                                       \
     X("fe80:0:0:0:2acf:daff:1.2.3.4")                                         \
+    X("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")                        \
 
 #define BAD_ADDR_LIST(X)                                                      \
     X(":::1")                                                                 \
@@ -114,6 +111,7 @@ TEST_IMPL(ip6_addr_link_local) {
     X("fe80:0:0:0:2acf:daff:fedd:342a:5678")                                  \
     X("fe80:0:0:0:2acf:daff:abcd:1.2.3.4")                                    \
     X("fe80:0:0:2acf:daff:1.2.3.4.5")                                         \
+    X("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255.255")                    \
 
 #define TEST_GOOD(ADDR)                                                       \
     ASSERT(0 == uv_inet_pton(AF_INET6, ADDR, &addr));                         \
index 5bb8f67..15c2e4e 100644 (file)
@@ -93,6 +93,7 @@ TEST_DECLARE   (udp_dgram_too_big)
 TEST_DECLARE   (udp_dual_stack)
 TEST_DECLARE   (udp_ipv6_only)
 TEST_DECLARE   (udp_options)
+TEST_DECLARE   (udp_no_autobind)
 TEST_DECLARE   (udp_open)
 TEST_DECLARE   (pipe_bind_error_addrinuse)
 TEST_DECLARE   (pipe_bind_error_addrnotavail)
@@ -162,6 +163,8 @@ TEST_DECLARE   (hrtime)
 TEST_DECLARE   (getaddrinfo_fail)
 TEST_DECLARE   (getaddrinfo_basic)
 TEST_DECLARE   (getaddrinfo_concurrent)
+TEST_DECLARE   (getnameinfo_basic_ip4)
+TEST_DECLARE   (getnameinfo_basic_ip6)
 TEST_DECLARE   (getsockname_tcp)
 TEST_DECLARE   (getsockname_udp)
 TEST_DECLARE   (fail_always)
@@ -226,6 +229,7 @@ TEST_DECLARE   (threadpool_queue_work_simple)
 TEST_DECLARE   (threadpool_queue_work_einval)
 TEST_DECLARE   (threadpool_multiple_event_loops)
 TEST_DECLARE   (threadpool_cancel_getaddrinfo)
+TEST_DECLARE   (threadpool_cancel_getnameinfo)
 TEST_DECLARE   (threadpool_cancel_work)
 TEST_DECLARE   (threadpool_cancel_fs)
 TEST_DECLARE   (threadpool_cancel_single)
@@ -237,9 +241,12 @@ TEST_DECLARE   (dlerror)
 TEST_DECLARE   (poll_duplex)
 TEST_DECLARE   (poll_unidirectional)
 TEST_DECLARE   (poll_close)
+
 TEST_DECLARE   (ip4_addr)
 TEST_DECLARE   (ip6_addr_link_local)
+
 #ifdef _WIN32
+TEST_DECLARE   (poll_closesocket)
 TEST_DECLARE   (spawn_detect_pipe_name_collisions_on_windows)
 TEST_DECLARE   (argument_escaping)
 TEST_DECLARE   (environment_creation)
@@ -363,6 +370,7 @@ TASK_LIST_START
   TEST_ENTRY  (udp_dual_stack)
   TEST_ENTRY  (udp_ipv6_only)
   TEST_ENTRY  (udp_options)
+  TEST_ENTRY  (udp_no_autobind)
   TEST_ENTRY  (udp_multicast_interface)
   TEST_ENTRY  (udp_multicast_interface6)
   TEST_ENTRY  (udp_multicast_join)
@@ -470,6 +478,9 @@ TASK_LIST_START
   TEST_ENTRY  (getaddrinfo_basic)
   TEST_ENTRY  (getaddrinfo_concurrent)
 
+  TEST_ENTRY  (getnameinfo_basic_ip4)
+  TEST_ENTRY  (getnameinfo_basic_ip6)
+
   TEST_ENTRY  (getsockname_tcp)
   TEST_ENTRY  (getsockname_udp)
 
@@ -499,6 +510,7 @@ TASK_LIST_START
   TEST_ENTRY  (kill)
 
 #ifdef _WIN32
+  TEST_ENTRY  (poll_closesocket)
   TEST_ENTRY  (spawn_detect_pipe_name_collisions_on_windows)
   TEST_ENTRY  (argument_escaping)
   TEST_ENTRY  (environment_creation)
@@ -560,6 +572,7 @@ TASK_LIST_START
   TEST_ENTRY  (threadpool_queue_work_einval)
   TEST_ENTRY  (threadpool_multiple_event_loops)
   TEST_ENTRY  (threadpool_cancel_getaddrinfo)
+  TEST_ENTRY  (threadpool_cancel_getnameinfo)
   TEST_ENTRY  (threadpool_cancel_work)
   TEST_ENTRY  (threadpool_cancel_fs)
   TEST_ENTRY  (threadpool_cancel_single)
diff --git a/deps/uv/test/test-poll-closesocket.c b/deps/uv/test/test-poll-closesocket.c
new file mode 100644 (file)
index 0000000..4db74a0
--- /dev/null
@@ -0,0 +1,89 @@
+/* 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.
+ */
+
+#ifdef _WIN32
+
+#include <errno.h>
+
+#include "uv.h"
+#include "task.h"
+
+uv_os_sock_t sock;
+uv_poll_t handle;
+
+static int close_cb_called = 0;
+
+
+static void close_cb(uv_handle_t* h) {
+  close_cb_called++;
+}
+
+
+static void poll_cb(uv_poll_t* h, int status, int events) {
+  int r;
+
+  ASSERT(status == 0);
+  ASSERT(h == &handle);
+
+  r = uv_poll_start(&handle, UV_READABLE, poll_cb);
+  ASSERT(r == 0);
+
+  closesocket(sock);
+  uv_close((uv_handle_t*) &handle, close_cb);
+
+}
+
+
+TEST_IMPL(poll_closesocket) {
+  struct WSAData wsa_data;
+  int r;
+  unsigned long on;
+  struct sockaddr_in addr;
+
+  r = WSAStartup(MAKEWORD(2, 2), &wsa_data);
+  ASSERT(r == 0);
+
+  sock = socket(AF_INET, SOCK_STREAM, 0);
+  ASSERT(sock != INVALID_SOCKET);
+  on = 1;
+  r = ioctlsocket(sock, FIONBIO, &on);
+  ASSERT(r == 0);
+
+  r = uv_ip4_addr("127.0.0.1", TEST_PORT, &addr);
+  ASSERT(r == 0);
+
+  r = connect(sock, (const struct sockaddr*) &addr, sizeof addr);
+  ASSERT(r != 0);
+  ASSERT(WSAGetLastError() == WSAEWOULDBLOCK);
+
+  r = uv_poll_init_socket(uv_default_loop(), &handle, sock);
+  ASSERT(r == 0);
+  r = uv_poll_start(&handle, UV_WRITABLE, poll_cb);
+  ASSERT(r == 0);
+
+  uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+
+  ASSERT(close_cb_called == 1);
+
+  MAKE_VALGRIND_HAPPY();
+  return 0;
+}
+#endif
index 0f4389f..c75f1ca 100644 (file)
@@ -808,6 +808,7 @@ WCHAR* quote_cmd_arg(const WCHAR *source, WCHAR *target);
 
 TEST_IMPL(argument_escaping) {
   const WCHAR* test_str[] = {
+    L"",
     L"HelloWorld",
     L"Hello World",
     L"Hello\"World",
index a349876..d852e48 100644 (file)
@@ -46,7 +46,6 @@ static unsigned work_cb_called;
 static unsigned done_cb_called;
 static unsigned done2_cb_called;
 static unsigned timer_cb_called;
-static unsigned getaddrinfo_cb_called;
 
 
 static void work_cb(uv_work_t* req) {
@@ -125,7 +124,16 @@ static void getaddrinfo_cb(uv_getaddrinfo_t* req,
   ASSERT(status == UV_EAI_CANCELED);
   ASSERT(res == NULL);
   uv_freeaddrinfo(res);  /* Should not crash. */
-  getaddrinfo_cb_called++;
+}
+
+
+static void getnameinfo_cb(uv_getnameinfo_t* handle,
+                           int status,
+                           const char* hostname,
+                           const char* service) {
+  ASSERT(status == UV_EAI_CANCELED);
+  ASSERT(hostname == NULL);
+  ASSERT(service == NULL);
 }
 
 
@@ -202,6 +210,44 @@ TEST_IMPL(threadpool_cancel_getaddrinfo) {
 }
 
 
+TEST_IMPL(threadpool_cancel_getnameinfo) {
+  uv_getnameinfo_t reqs[4];
+  struct sockaddr_in addr4;
+  struct cancel_info ci;
+  uv_loop_t* loop;
+  int r;
+
+  r = uv_ip4_addr("127.0.0.1", 80, &addr4);
+  ASSERT(r == 0);
+
+  INIT_CANCEL_INFO(&ci, reqs);
+  loop = uv_default_loop();
+  saturate_threadpool();
+
+  r = uv_getnameinfo(loop, reqs + 0, getnameinfo_cb, (const struct sockaddr*)&addr4, 0);
+  ASSERT(r == 0);
+
+  r = uv_getnameinfo(loop, reqs + 1, getnameinfo_cb, (const struct sockaddr*)&addr4, 0);
+  ASSERT(r == 0);
+
+  r = uv_getnameinfo(loop, reqs + 2, getnameinfo_cb, (const struct sockaddr*)&addr4, 0);
+  ASSERT(r == 0);
+
+  r = uv_getnameinfo(loop, reqs + 3, getnameinfo_cb, (const struct sockaddr*)&addr4, 0);
+  ASSERT(r == 0);
+
+  ASSERT(0 == uv_timer_init(loop, &ci.timer_handle));
+  ASSERT(0 == uv_timer_start(&ci.timer_handle, timer_cb, 10, 0));
+  ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT));
+  ASSERT(1 == timer_cb_called);
+
+  cleanup_threadpool();
+
+  MAKE_VALGRIND_HAPPY();
+  return 0;
+}
+
+
 TEST_IMPL(threadpool_cancel_work) {
   struct cancel_info ci;
   uv_work_t reqs[16];
index 5cc3698..19c45c2 100644 (file)
@@ -86,3 +86,25 @@ TEST_IMPL(udp_options) {
   MAKE_VALGRIND_HAPPY();
   return 0;
 }
+
+
+TEST_IMPL(udp_no_autobind) {
+  uv_loop_t* loop;
+  uv_udp_t h;
+
+  loop = uv_default_loop();
+
+  ASSERT(0 == uv_udp_init(loop, &h));
+  ASSERT(UV_EBADF == uv_udp_set_multicast_ttl(&h, 32));
+  ASSERT(UV_EBADF == uv_udp_set_broadcast(&h, 1));
+  ASSERT(UV_EBADF == uv_udp_set_ttl(&h, 1));
+  ASSERT(UV_EBADF == uv_udp_set_multicast_loop(&h, 1));
+  ASSERT(UV_EBADF == uv_udp_set_multicast_interface(&h, "0.0.0.0"));
+
+  uv_close((uv_handle_t*) &h, NULL);
+
+  ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT));
+
+  MAKE_VALGRIND_HAPPY();
+  return 0;
+}
index 710bd40..147fc06 100644 (file)
@@ -86,6 +86,7 @@
             'src/win/fs.c',
             'src/win/fs-event.c',
             'src/win/getaddrinfo.c',
+            'src/win/getnameinfo.c',
             'src/win/handle.c',
             'src/win/handle-inl.h',
             'src/win/internal.h',
             'src/unix/dl.c',
             'src/unix/fs.c',
             'src/unix/getaddrinfo.c',
+            'src/unix/getnameinfo.c',
             'src/unix/internal.h',
             'src/unix/loop.c',
             'src/unix/loop-watcher.c',
         'test/test-get-currentexe.c',
         'test/test-get-memory.c',
         'test/test-getaddrinfo.c',
+        'test/test-getnameinfo.c',
         'test/test-getsockname.c',
         'test/test-hrtime.c',
         'test/test-idle.c',
         'test/test-platform-output.c',
         'test/test-poll.c',
         'test/test-poll-close.c',
+        'test/test-poll-closesocket.c',
         'test/test-process-title.c',
         'test/test-ref.c',
         'test/test-run-nowait.c',
index df6eda0..d3b7aa1 100644 (file)
@@ -51,8 +51,8 @@ call "%VS120COMNTOOLS%\..\..\vc\vcvarsall.bat" %vs_toolset%
 set GYP_MSVS_VERSION=2013
 goto select-target
 
-@rem Look for Visual Studio 2012
 :vc-set-2012
+@rem Look for Visual Studio 2012
 if not defined VS110COMNTOOLS goto vc-set-2010
 if not exist "%VS110COMNTOOLS%\..\..\vc\vcvarsall.bat" goto vc-set-2010
 call "%VS110COMNTOOLS%\..\..\vc\vcvarsall.bat" %vs_toolset%
@@ -101,8 +101,8 @@ echo manually install gyp into %~dp0build\gyp.
 exit /b 1
 
 :have_gyp
-if not defined PYTHON set PYTHON="python"
-%PYTHON% gyp_uv.py -Dtarget_arch=%target_arch% -Duv_library=%library%
+if not defined PYTHON set PYTHON=python
+"%PYTHON%" gyp_uv.py -Dtarget_arch=%target_arch% -Duv_library=%library%
 if errorlevel 1 goto create-msvs-files-failed
 if not exist uv.sln goto create-msvs-files-failed
 echo Project files generated.