uv: Upgrade to v0.11.16
authorFedor Indutny <fedor.indutny@gmail.com>
Fri, 13 Dec 2013 18:35:09 +0000 (22:35 +0400)
committerFedor Indutny <fedor.indutny@gmail.com>
Fri, 13 Dec 2013 18:35:09 +0000 (22:35 +0400)
32 files changed:
deps/uv/.gitignore
deps/uv/.mailmap
deps/uv/AUTHORS
deps/uv/CONTRIBUTING.md [new file with mode: 0644]
deps/uv/ChangeLog
deps/uv/Makefile.am
deps/uv/README.md
deps/uv/configure.ac
deps/uv/gyp_uv.py
deps/uv/include/uv-errno.h
deps/uv/include/uv.h
deps/uv/libuv.pc.in [new file with mode: 0644]
deps/uv/src/unix/core.c
deps/uv/src/unix/darwin.c
deps/uv/src/unix/fs.c
deps/uv/src/unix/fsevents.c
deps/uv/src/unix/internal.h
deps/uv/src/unix/signal.c
deps/uv/src/unix/stream.c
deps/uv/src/uv-common.c
deps/uv/src/version.c
deps/uv/src/win/core.c
deps/uv/src/win/fs-event.c
deps/uv/src/win/process.c
deps/uv/src/win/stream.c
deps/uv/src/win/util.c
deps/uv/test/test-emfile.c [new file with mode: 0644]
deps/uv/test/test-ip4-addr.c [new file with mode: 0644]
deps/uv/test/test-list.h
deps/uv/test/test-loop-time.c [new file with mode: 0644]
deps/uv/test/test-tcp-try-write.c [new file with mode: 0644]
deps/uv/uv.gyp

index 506f04a..c8d93d8 100644 (file)
@@ -3,6 +3,7 @@
 *.l[oa]
 *.opensdf
 *.orig
+*.pyc
 *.sdf
 *.suo
 core
index a2cf836..a1e5f71 100644 (file)
@@ -8,6 +8,8 @@ Frank Denis <github@pureftpd.org>
 Isaac Z. Schlueter <i@izs.me>
 Keno Fischer <kenof@stanford.edu> <kfischer+github@college.harvard.edu>
 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>
 Robert Mustacchi <rm@joyent.com> <rm@fingolfin.org>
 Ryan Dahl <ryan@joyent.com> <ry@tinyclouds.org>
 Ryan Emery <seebees@gmail.com>
index a9c63bf..a7c48c4 100644 (file)
@@ -99,3 +99,12 @@ Maks Naumov <maksqwe1@ukr.net>
 Sean Farrell <sean.farrell@rioki.org>
 Chris Bank <cbank@adobe.com>
 Geert Jansen <geertj@gmail.com>
+Alex Gaynor <alex.gaynor@gmail.com>
+huxingyi <huxingyi@msn.com>
+ci-innoq <christoph.iserlohn@innoq.com>
+Steven Kabbes <stevenkabbes@gmail.com>
+Tenor Biel <tenorbiel@gmail.com>
+Andrej Manduch <AManduch@gmail.com>
+Joshua Neuheisel <joshua@neuheisel.us>
+Alexis Campailla <alexis@janeasystems.com>
+Yorkie <yorkiefixer@gmail.com>
diff --git a/deps/uv/CONTRIBUTING.md b/deps/uv/CONTRIBUTING.md
new file mode 100644 (file)
index 0000000..960a945
--- /dev/null
@@ -0,0 +1,177 @@
+# CONTRIBUTING
+
+The libuv project welcomes new contributors. This document will guide you
+through the process.
+
+
+### FORK
+
+Fork the project [on GitHub](https://github.com/joyent/libuv) and check out
+your copy.
+
+```
+$ git clone https://github.com/username/libuv.git
+$ cd libuv
+$ git remote add upstream https://github.com/joyent/libuv.git
+```
+
+Now decide if you want your feature or bug fix to go into the master branch
+or the stable branch.  As a rule of thumb, bug fixes go into the stable branch
+while new features go into the master branch.
+
+The stable branch is effectively frozen; patches that change the libuv
+API/ABI or affect the run-time behavior of applications get rejected.
+
+In case of doubt, open an issue in the [issue tracker][], post your question
+to the [libuv mailing list], or contact one of project maintainers
+(@bnoordhuis, @piscisaureus, @indutny or @saghul) on [IRC][].
+
+Especially do so if you plan to work on something big.  Nothing is more
+frustrating than seeing your hard work go to waste because your vision
+does not align with that of a project maintainers.
+
+
+### BRANCH
+
+Okay, so you have decided on the proper branch.  Create a feature branch
+and start hacking:
+
+```
+$ git checkout -b my-feature-branch -t origin/v0.10
+```
+
+(Where v0.10 is the latest stable branch as of this writing.)
+
+### CODE
+
+Please adhere to libuv's code style. In general it follows the conventions from
+the [Google C/C++ style guide]. Some of the key points, as well as some
+additional guidelines, are enumerated below.
+
+* Code that is specific to unix-y platforms should be placed in `src/unix`, and
+  declarations go into `src/uv-unix.h`.
+
+* Source code that is Windows-specific goes into `src/win`, and related
+  publicly exported types, functions and macro declarations should generally
+  be declared in `include/uv-win.h`.
+
+* Names should be descriptive and concise.
+
+* All the symbols and types that libuv makes available publicly should be
+  prefixed with `uv_` (or `UV_` in case of macros).
+
+* Internal, non-static functions should be prefixed with `uv__`.
+
+* Use two spaces and no tabs.
+
+* Lines should be wrapped at 80 characters.
+
+* Ensure that lines have no trailing whitespace, and use unix-style (LF) line
+  endings.
+
+* Use C89-compliant syntax. In other words, variables can only be declared at
+  the top of a scope (function, if/for/while-block).
+
+* When writing comments, use properly constructed sentences, including
+  punctuation.
+
+* When documenting APIs and/or source code, don't make assumptions or make
+  implications about race, gender, religion, political orientation or anything
+  else that isn't relevant to the project.
+
+* Remember that source code usually gets written once and read often: ensure
+  the reader doesn't have to make guesses. Make sure that the purpose and inner
+  logic are either obvious to a reasonably skilled professional, or add a
+  comment that explains it.
+
+
+### COMMIT
+
+Make sure git knows your name and email address:
+
+```
+$ git config --global user.name "J. Random User"
+$ git config --global user.email "j.random.user@example.com"
+```
+
+Writing good commit logs is important.  A commit log should describe what
+changed and why.  Follow these guidelines when writing one:
+
+1. The first line should be 50 characters or less and contain a short
+   description of the change prefixed with the name of the changed
+   subsystem (e.g. "net: add localAddress and localPort to Socket").
+2. Keep the second line blank.
+3. Wrap all other lines at 72 columns.
+
+A good commit log looks like this:
+
+```
+subsystem: explaining the commit in one line
+
+Body of commit message is a few lines of text, explaining things
+in more detail, possibly giving some background about the issue
+being fixed, etc etc.
+
+The body of the commit message can be several paragraphs, and
+please do proper word-wrap and keep columns shorter than about
+72 characters or so. That way `git log` will show things
+nicely even when it is indented.
+```
+
+The header line should be meaningful; it is what other people see when they
+run `git shortlog` or `git log --oneline`.
+
+Check the output of `git log --oneline files_that_you_changed` to find out
+what subsystem (or subsystems) your changes touch.
+
+
+### REBASE
+
+Use `git rebase` (not `git merge`) to sync your work from time to time.
+
+```
+$ git fetch upstream
+$ git rebase upstream/v0.10  # or upstream/master
+```
+
+
+### TEST
+
+Bug fixes and features should come with tests.  Add your tests in the
+`test/` directory. Tests also need to be registered in `test/test-list.h`.
+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.
+
+### PUSH
+
+```
+$ git push origin my-feature-branch
+```
+
+Go to https://github.com/username/libuv and select your feature branch.  Click
+the 'Pull Request' button and fill out the form.
+
+Pull requests are usually reviewed within a few days.  If there are comments
+to address, apply your changes in a separate commit and push that to your
+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 0e5638f..5ee5338 100644 (file)
@@ -1,4 +1,44 @@
-2013.11.21, Version 0.11.15 (Unstable)
+2013.12.14, Version 0.11.16 (Unstable), ae0ed8c49d0d313c935c22077511148b6e8408a4
+
+Changes since version 0.11.15:
+
+* fsevents: remove kFSEventStreamCreateFlagNoDefer polyfill (ci-innoq)
+
+* libuv: add more getaddrinfo errors (Steven Kabbes)
+
+* unix: fix accept() EMFILE error handling (Ben Noordhuis)
+
+* linux: fix up SO_REUSEPORT back-port (Ben Noordhuis)
+
+* fsevents: fix subfolder check (Fedor Indutny)
+
+* fsevents: fix invalid memory access (huxingyi)
+
+* windows/timer: fix uv_hrtime discontinuity (Bert Belder)
+
+* unix: fix various memory leaks and undef behavior (Fedor Indutny)
+
+* unix, windows: always update loop time (Saúl Ibarra Corretgé)
+
+* windows: translate system errors in uv_spawn (Alexis Campailla)
+
+* windows: uv_spawn code refactor (Alexis Campailla)
+
+* unix, windows: detect errors in uv_ip4/6_addr (Yorkie)
+
+* stream: introduce uv_try_write(...) (Fedor Indutny)
+
+
+2013.12.13, Version 0.10.20 (Stable), 04141464dd0fba90ace9aa6f7003ce139b888a40
+
+Changes since version 0.10.19:
+
+* linux: fix up SO_REUSEPORT back-port (Ben Noordhuis)
+
+* fs-event: fix invalid memory access (huxingyi)
+
+
+2013.11.21, Version 0.11.15 (Unstable), bfe645ed7e99ca5670d9279ad472b604c129d2e5
 
 Changes since version 0.11.14:
 
index 8f656f3..2229e86 100644 (file)
@@ -126,6 +126,7 @@ test_run_tests_SOURCES = test/blackhole-server.c \
                          test/test-delayed-accept.c \
                          test/test-dlerror.c \
                          test/test-embed.c \
+                         test/test-emfile.c \
                          test/test-error.c \
                          test/test-fail-always.c \
                          test/test-fs-event.c \
@@ -138,12 +139,14 @@ test_run_tests_SOURCES = test/blackhole-server.c \
                          test/test-getsockname.c \
                          test/test-hrtime.c \
                          test/test-idle.c \
+                         test/test-ip4-addr.c \
                          test/test-ip6-addr.c \
                          test/test-ipc-send-recv.c \
                          test/test-ipc.c \
                          test/test-list.h \
                          test/test-loop-handles.c \
                          test/test-loop-stop.c \
+                         test/test-loop-time.c \
                          test/test-multiple-listen.c \
                          test/test-mutexes.c \
                          test/test-osx-select.c \
@@ -181,6 +184,7 @@ test_run_tests_SOURCES = test/blackhole-server.c \
                          test/test-tcp-unexpected-read.c \
                          test/test-tcp-write-to-half-open-connection.c \
                          test/test-tcp-writealot.c \
+                         test/test-tcp-try-write.c \
                          test/test-thread.c \
                          test/test-threadpool-cancel.c \
                          test/test-threadpool.c \
@@ -266,10 +270,18 @@ libuv_la_LIBADD = uv-dtrace.lo
 CLEANFILES += src/unix/uv-dtrace.o src/unix/uv-dtrace.lo
 endif
 
-SUFFIXES = .d
+if HAVE_PKG_CONFIG
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA = @PACKAGE_NAME@.pc
+endif
 
+if HAVE_DTRACE
 include/uv-dtrace.h: src/unix/uv-dtrace.d
        $(AM_V_GEN)$(DTRACE) $(DTRACEFLAGS) -h -xnolibs -s $< -o $(top_srcdir)/$@
+endif
+
+if DTRACE_NEEDS_OBJECTS
+SUFFIXES = .d
 
 src/unix/uv-dtrace.o: src/unix/uv-dtrace.d ${libuv_la_OBJECTS}
 
@@ -285,3 +297,4 @@ src/unix/uv-dtrace.o: src/unix/uv-dtrace.d ${libuv_la_OBJECTS}
                "pic_object='uv-dtrace.o'" \
                "non_pic_object='uv-dtrace.o'" \
        > ${top_builddir}/uv-dtrace.lo
+endif
index ce43f6d..0b0f17f 100644 (file)
@@ -1,7 +1,7 @@
 # libuv
 
 libuv is a multi-platform support library with a focus on asynchronous I/O. It
-was primarily developed for use by [Node.js](http://node.js.org), but it's also
+was primarily developed for use by [Node.js](http://nodejs.org), but it's also
 used by Mozilla's [Rust language](http://www.rust-lang.org/),
 [Luvit](http://luvit.io/), [Julia](http://julialang.org/),
 [pyuv](https://crate.io/packages/pyuv/), and others.
@@ -103,6 +103,14 @@ Run:
 Note for UNIX users: compile your project with `-D_LARGEFILE_SOURCE` and
 `-D_FILE_OFFSET_BITS=64`. GYP builds take care of that automatically.
 
+### Running tests
+
+Run:
+
+    $ ./gyp_uv.py -f make
+    $ make -C out
+    $ ./out/Debug/run-tests
+
 ## Supported Platforms
 
 Microsoft Windows operating systems since Windows XP SP2. It can be built
@@ -116,6 +124,11 @@ OS X using the GCC or XCode toolchain.
 
 Solaris 121 and later using GCC toolchain.
 
+## patches
+
+See the [guidelines for contributing][].
+
 [node.js]: http://nodejs.org/
 [GYP]: http://code.google.com/p/gyp/
 [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 fda951e..c8b3257 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.15], [https://github.com/joyent/libuv/issues])
+AC_INIT([libuv], [0.11.17], [https://github.com/joyent/libuv/issues])
 AC_CONFIG_MACRO_DIR([m4])
 m4_include([m4/libuv-extra-automake-flags.m4])
 AM_INIT_AUTOMAKE([-Wall -Werror foreign subdir-objects] UV_EXTRA_AUTOMAKE_FLAGS)
@@ -46,5 +46,10 @@ AM_CONDITIONAL([OPENBSD], [AS_CASE([$host_os], [openbsd*], [true], [false])])
 AM_CONDITIONAL([SUNOS],   [AS_CASE([$host_os], [solaris*], [true], [false])])
 AM_CONDITIONAL([WINNT],   [AS_CASE([$host_os], [mingw*],   [true], [false])])
 PANDORA_ENABLE_DTRACE
+AC_CHECK_PROG(PKG_CONFIG, pkg-config, yes)
+AM_CONDITIONAL([HAVE_PKG_CONFIG], [test "x$PKG_CONFIG" = "xyes"])
+AS_IF([test "x$PKG_CONFIG" = "xyes"], [
+    AC_CONFIG_FILES([libuv.pc])
+])
 AC_CONFIG_FILES([Makefile])
 AC_OUTPUT
index 651bd09..4ba6916 100755 (executable)
@@ -75,7 +75,7 @@ if __name__ == '__main__':
   if sys.platform != 'win32':
     if '-f' not in args:
       args.extend('-f make'.split())
-    if 'ninja' not in args:
+    if 'eclipse' not in args and 'ninja' not in args:
       args.extend(['-Goutput_dir=' + output_dir])
       args.extend(['--generator-output', output_dir])
     (major, minor), is_clang = compiler_version()
index ce895b7..797bcab 100644 (file)
@@ -40,6 +40,8 @@
 #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)
 
 /* Only map to the system errno on non-Windows platforms. It's apparently
  * a fairly common practice for Windows programmers to redefine errno codes.
index c3ba250..d6485e5 100644 (file)
@@ -71,12 +71,15 @@ extern "C" {
   XX(EAI_ADDRFAMILY, "address family not supported")                          \
   XX(EAI_AGAIN, "temporary failure")                                          \
   XX(EAI_BADFLAGS, "bad ai_flags value")                                      \
+  XX(EAI_BADHINTS, "invalid value for hints")                                 \
   XX(EAI_CANCELED, "request canceled")                                        \
   XX(EAI_FAIL, "permanent failure")                                           \
   XX(EAI_FAMILY, "ai_family not supported")                                   \
   XX(EAI_MEMORY, "out of memory")                                             \
   XX(EAI_NODATA, "no address")                                                \
   XX(EAI_NONAME, "unknown node or service")                                   \
+  XX(EAI_OVERFLOW, "argument buffer overflow")                                \
+  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")                                              \
@@ -670,6 +673,16 @@ UV_EXTERN int uv_write2(uv_write_t* req,
                         uv_stream_t* send_handle,
                         uv_write_cb cb);
 
+/*
+ * Same as `uv_write()`, but won't queue write request if it can't be completed
+ * immediately.
+ * Will return either:
+ * - positive number of bytes written
+ * - zero - if queued write is needed
+ * - negative error code
+ */
+UV_EXTERN int uv_try_write(uv_stream_t* handle, const char* buf, size_t length);
+
 /* uv_write_t is a subclass of uv_req_t */
 struct uv_write_s {
   UV_REQ_FIELDS
diff --git a/deps/uv/libuv.pc.in b/deps/uv/libuv.pc.in
new file mode 100644 (file)
index 0000000..86c1a12
--- /dev/null
@@ -0,0 +1,11 @@
+prefix=@prefix@
+exec_prefix=@prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: @PACKAGE_NAME@
+Version: @PACKAGE_VERSION@
+Description: multi-platform support library with a focus on asynchronous I/O.
+
+Libs: -L${libdir} -luv
+Cflags: -I${includedir}
index 79813a0..6bb2057 100644 (file)
@@ -260,6 +260,9 @@ int uv_run(uv_loop_t* loop, uv_run_mode mode) {
   int r;
 
   r = uv__loop_alive(loop);
+  if (!r)
+    uv__update_time(loop);
+
   while (r != 0 && loop->stop_flag == 0) {
     UV_TICK_START(loop, mode);
 
index c165599..bc282e7 100644 (file)
@@ -75,7 +75,7 @@ int uv_exepath(char* buffer, size_t* size) {
   result = _NSGetExecutablePath(buffer, &usize);
   if (result) return result;
 
-  path = (char*)malloc(2 * PATH_MAX);
+  path = malloc(2 * PATH_MAX);
   fullpath = realpath(buffer, path);
   if (fullpath == NULL) {
     SAVE_ERRNO(free(path));
index 64517c4..4e572b7 100644 (file)
@@ -313,7 +313,7 @@ static ssize_t uv__fs_sendfile_emul(uv_fs_t* req) {
    *
    * 1. Read errors are reported only if nsent==0, otherwise we return nsent.
    *    The user needs to know that some data has already been sent, to stop
-   *    him from sending it twice.
+   *    them from sending it twice.
    *
    * 2. Write errors are always reported. Write errors are bad because they
    *    mean data loss: we've read data but now we can't write it out.
index 3618f46..7faa156 100644 (file)
@@ -251,13 +251,15 @@ static void uv__fsevents_event_cb(ConstFSEventStreamRef streamRef,
       if (strncmp(path, handle->realpath, handle->realpath_len) != 0)
         continue;
 
-      path += handle->realpath_len;
-      len -= handle->realpath_len;
-
-      /* Skip back slash */
-      if (*path != 0) {
-        path++;
-        len--;
+      if (handle->realpath_len > 1 || *handle->realpath != '/') {
+        path += handle->realpath_len;
+        len -= handle->realpath_len;
+
+        /* Skip forward slash */
+        if (*path != '\0') {
+          path++;
+          len--;
+        }
       }
 
 #ifdef MAC_OS_X_VERSION_10_7
@@ -267,9 +269,9 @@ static void uv__fsevents_event_cb(ConstFSEventStreamRef streamRef,
 #endif /* MAC_OS_X_VERSION_10_7 */
 
       /* Do not emit events from subdirectories (without option set) */
-      if ((handle->cf_flags & UV_FS_EVENT_RECURSIVE) == 0) {
-        pos = strchr(path, '/');
-        if (pos != NULL && pos != path + 1)
+      if ((handle->cf_flags & UV_FS_EVENT_RECURSIVE) == 0 && *path != 0) {
+        pos = strchr(path + 1, '/');
+        if (pos != NULL)
           continue;
       }
 
@@ -588,7 +590,7 @@ static int uv__fsevents_loop_init(uv_loop_t* loop) {
 
   err = uv_mutex_init(&loop->cf_mutex);
   if (err)
-    return err;
+    goto fail_mutex_init;
 
   err = uv_sem_init(&loop->cf_sem, 0);
   if (err)
@@ -658,6 +660,8 @@ fail_fsevent_sem_init:
 
 fail_sem_init:
   uv_mutex_destroy(&loop->cf_mutex);
+
+fail_mutex_init:
   free(state);
   return err;
 }
index 79e41fa..0ea82b5 100644 (file)
@@ -243,7 +243,6 @@ void uv__fsevents_loop_delete(uv_loop_t* loop);
 /* OSX < 10.7 has no file events, polyfill them */
 #ifndef MAC_OS_X_VERSION_10_7
 
-static const int kFSEventStreamCreateFlagNoDefer = 0x00000002;
 static const int kFSEventStreamCreateFlagFileEvents = 0x00000010;
 static const int kFSEventStreamEventFlagItemCreated = 0x00000100;
 static const int kFSEventStreamEventFlagItemRemoved = 0x00000200;
index 8c0d62f..0b7a405 100644 (file)
@@ -348,6 +348,7 @@ static void uv__signal_event(uv_loop_t* loop,
   int r;
 
   bytes = 0;
+  end = 0;
 
   do {
     r = read(loop->signal_pipefd[0], buf + bytes, sizeof(buf) - bytes);
index abef01e..afd2a05 100644 (file)
@@ -462,27 +462,22 @@ void uv__stream_destroy(uv_stream_t* stream) {
  * calling close() and accept().
  */
 static int uv__emfile_trick(uv_loop_t* loop, int accept_fd) {
-  int fd;
+  int err;
 
   if (loop->emfile_fd == -1)
     return -EMFILE;
 
   uv__close(loop->emfile_fd);
+  loop->emfile_fd = -1;
 
-  for (;;) {
-    fd = uv__accept(accept_fd);
-
-    if (fd != -1) {
-      uv__close(fd);
-      continue;
-    }
-
-    if (errno == EINTR)
-      continue;
+  do {
+    err = uv__accept(accept_fd);
+    if (err >= 0)
+      uv__close(err);
+  } while (err >= 0 || err == -EINTR);
 
-    SAVE_ERRNO(loop->emfile_fd = uv__open_cloexec("/", O_RDONLY));
-    return -errno;
-  }
+  SAVE_ERRNO(loop->emfile_fd = uv__open_cloexec("/", O_RDONLY));
+  return err;
 }
 
 
@@ -673,8 +668,8 @@ static void uv__write_req_finish(uv_write_t* req) {
   /* Only free when there was no error. On error, we touch up write_queue_size
    * right before making the callback. The reason we don't do that right away
    * is that a write_queue_size > 0 is our only way to signal to the user that
-   * he should stop writing - which he should if we got an error. Something to
-   * revisit in future revisions of the libuv API.
+   * they should stop writing - which they should if we got an error. Something
+   * to revisit in future revisions of the libuv API.
    */
   if (req->error == 0) {
     if (req->bufs != req->bufsml)
@@ -1304,6 +1299,55 @@ int uv_write(uv_write_t* req,
 }
 
 
+void uv_try_write_cb(uv_write_t* req, int status) {
+  /* Should not be called */
+  abort();
+}
+
+
+int uv_try_write(uv_stream_t* stream, const char* buf, size_t size) {
+  int r;
+  int has_pollout;
+  size_t written;
+  size_t req_size;
+  uv_write_t req;
+  uv_buf_t bufstruct;
+
+  /* Connecting or already writing some data */
+  if (stream->connect_req != NULL || stream->write_queue_size != 0)
+    return 0;
+
+  has_pollout = uv__io_active(&stream->io_watcher, UV__POLLOUT);
+
+  bufstruct = uv_buf_init((char*) buf, size);
+  r = uv_write(&req, stream, &bufstruct, 1, uv_try_write_cb);
+  if (r != 0)
+    return r;
+
+  /* Remove not written bytes from write queue size */
+  written = size;
+  if (req.bufs != NULL)
+    req_size = uv__write_req_size(&req);
+  else
+    req_size = 0;
+  written -= req_size;
+  stream->write_queue_size -= req_size;
+
+  /* Unqueue request, regardless of immediateness */
+  QUEUE_REMOVE(&req.queue);
+  uv__req_unregister(stream->loop, &req);
+  if (req.bufs != req.bufsml)
+    free(req.bufs);
+  req.bufs = NULL;
+
+  /* Do not poll for writable, if we wasn't before calling this */
+  if (!has_pollout)
+    uv__io_stop(stream->loop, &stream->io_watcher, UV__POLLOUT);
+
+  return (int) written;
+}
+
+
 static int uv__read_start_common(uv_stream_t* stream,
                                  uv_alloc_cb alloc_cb,
                                  uv_read_cb read_cb,
index 4129a36..c4cf3c7 100644 (file)
@@ -102,9 +102,7 @@ int uv_ip4_addr(const char* ip, int port, struct sockaddr_in* addr) {
   memset(addr, 0, sizeof(*addr));
   addr->sin_family = AF_INET;
   addr->sin_port = htons(port);
-  /* TODO(bnoordhuis) Don't use inet_addr(), no good way to detect errors. */
-  addr->sin_addr.s_addr = inet_addr(ip);
-  return 0;
+  return uv_inet_pton(AF_INET, ip, &(addr->sin_addr.s_addr));
 }
 
 
@@ -140,10 +138,7 @@ int uv_ip6_addr(const char* ip, int port, struct sockaddr_in6* addr) {
   }
 #endif
 
-  /* TODO(bnoordhuis) Return an error when the address is bad. */
-  uv_inet_pton(AF_INET6, ip, &addr->sin6_addr);
-
-  return 0;
+  return uv_inet_pton(AF_INET6, ip, &addr->sin6_addr);
 }
 
 
@@ -404,6 +399,9 @@ int uv__getaddrinfo_translate_error(int sys_err) {
 #if defined(EAI_BADFLAGS)
   case EAI_BADFLAGS: return UV_EAI_BADFLAGS;
 #endif
+#if defined(EAI_BADHINTS)
+  case EAI_BADHINTS: return UV_EAI_BADHINTS;
+#endif
 #if defined(EAI_CANCELED)
   case EAI_CANCELED: return UV_EAI_CANCELED;
 #endif
@@ -424,6 +422,12 @@ int uv__getaddrinfo_translate_error(int sys_err) {
   case EAI_NONAME: return UV_EAI_NONAME;
 # endif
 #endif
+#if defined(EAI_OVERFLOW)
+  case EAI_OVERFLOW: return UV_EAI_OVERFLOW;
+#endif
+#if defined(EAI_PROTOCOL)
+  case EAI_PROTOCOL: return UV_EAI_PROTOCOL;
+#endif
 #if defined(EAI_SERVICE)
   case EAI_SERVICE: return UV_EAI_SERVICE;
 #endif
index 2170dee..c9e4200 100644 (file)
@@ -31,8 +31,8 @@
 
 #define UV_VERSION_MAJOR 0
 #define UV_VERSION_MINOR 11
-#define UV_VERSION_PATCH 15
-#define UV_VERSION_IS_RELEASE 1
+#define UV_VERSION_PATCH 17
+#define UV_VERSION_IS_RELEASE 0
 
 
 #define UV_VERSION  ((UV_VERSION_MAJOR << 16) | \
index 4a9eca2..2eab49f 100644 (file)
@@ -273,6 +273,9 @@ int uv_run(uv_loop_t *loop, uv_run_mode mode) {
     poll = &uv_poll;
 
   r = uv__loop_alive(loop);
+  if (!r)
+    uv_update_time(loop);
+
   while (r != 0 && loop->stop_flag == 0) {
     uv_update_time(loop);
     uv_process_timers(loop);
index 2a09bf4..6132b79 100644 (file)
@@ -382,7 +382,8 @@ void uv_process_fs_event_req(uv_loop_t* loop, uv_req_t* req,
                 uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
               }
 
-              _snwprintf(filenamew, size, L"%s\\%s", handle->dirw,
+              _snwprintf(filenamew, size, L"%s\\%.*s", handle->dirw,
+                file_info->FileNameLength / sizeof(WCHAR),
                 file_info->FileName);
 
               filenamew[size - 1] = L'\0';
index a5bb743..813e522 100644 (file)
@@ -832,26 +832,26 @@ int uv_spawn(uv_loop_t* loop,
 
   err = uv_utf8_to_utf16_alloc(options->file, &application);
   if (err)
-    goto immediate_failure;
+    goto done;
 
   err = make_program_args(
       options->args,
       options->flags & UV_PROCESS_WINDOWS_VERBATIM_ARGUMENTS,
       &arguments);
   if (err)
-    goto immediate_failure;
+    goto done;
 
   if (options->env) {
      err = make_program_env(options->env, &env);
      if (err)
-       goto immediate_failure;
+       goto done;
   }
 
   if (options->cwd) {
     /* Explicit cwd */
     err = uv_utf8_to_utf16_alloc(options->cwd, &cwd);
     if (err)
-      goto immediate_failure;
+      goto done;
 
   } else {
     /* Inherit cwd */
@@ -860,19 +860,19 @@ int uv_spawn(uv_loop_t* loop,
     cwd_len = GetCurrentDirectoryW(0, NULL);
     if (!cwd_len) {
       err = GetLastError();
-      goto immediate_failure;
+      goto done;
     }
 
     cwd = (WCHAR*) malloc(cwd_len * sizeof(WCHAR));
     if (cwd == NULL) {
       err = ERROR_OUTOFMEMORY;
-      goto immediate_failure;
+      goto done;
     }
 
     r = GetCurrentDirectoryW(cwd_len, cwd);
     if (r == 0 || r >= cwd_len) {
       err = GetLastError();
-      goto immediate_failure;
+      goto done;
     }
   }
 
@@ -883,27 +883,25 @@ int uv_spawn(uv_loop_t* loop,
     path_len = GetEnvironmentVariableW(L"PATH", NULL, 0);
     if (path_len == 0) {
       err = GetLastError();
-      goto immediate_failure;
+      goto done;
     }
 
     path = (WCHAR*) malloc(path_len * sizeof(WCHAR));
     if (path == NULL) {
       err = ERROR_OUTOFMEMORY;
-      goto immediate_failure;
+      goto done;
     }
 
     r = GetEnvironmentVariableW(L"PATH", path, path_len);
     if (r == 0 || r >= path_len) {
       err = GetLastError();
-      goto immediate_failure;
+      goto done;
     }
   }
 
   err = uv__stdio_create(loop, options, &process->child_stdio_buffer);
   if (err)
-    goto immediate_failure;
-
-  /* Beyond this point, failure is reported asynchronously. */
+    goto done;
 
   application_path = search_path(application,
                                  cwd,
@@ -911,7 +909,7 @@ int uv_spawn(uv_loop_t* loop,
   if (application_path == NULL) {
     /* Not found. */
     err = ERROR_FILE_NOT_FOUND;
-    goto success_or_async_failure;
+    goto done;
   }
 
   startup.cb = sizeof(startup);
@@ -950,7 +948,7 @@ int uv_spawn(uv_loop_t* loop,
     process_flags |= DETACHED_PROCESS | CREATE_NEW_PROCESS_GROUP;
   }
 
-  if (CreateProcessW(application_path,
+  if (!CreateProcessW(application_path,
                      arguments,
                      NULL,
                      NULL,
@@ -960,60 +958,67 @@ int uv_spawn(uv_loop_t* loop,
                      cwd,
                      &startup,
                      &info)) {
-    /* Spawn succeeded */
-    process->process_handle = info.hProcess;
-    process->pid = info.dwProcessId;
-
-    /* If the process isn't spawned as detached, assign to the global job */
-    /* object so windows will kill it when the parent process dies. */
-    if (!(options->flags & UV_PROCESS_DETACHED)) {
-      uv_once(&uv_global_job_handle_init_guard_, uv__init_global_job_handle);
-
-      if (!AssignProcessToJobObject(uv_global_job_handle_, info.hProcess)) {
-        /* AssignProcessToJobObject might fail if this process is under job
-         * control and the job doesn't have the
-         * JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK flag set, on a Windows version
-         * that doesn't support nested jobs.
-         *
-         * When that happens we just swallow the error and continue without
-         * establishing a kill-child-on-parent-exit relationship, otherwise
-         * there would be no way for libuv applications run under job control
-         * to spawn processes at all.
-         */
-        DWORD err = GetLastError();
-        if (err != ERROR_ACCESS_DENIED)
-          uv_fatal_error(err, "AssignProcessToJobObject");
-      }
-    }
+    /* CreateProcessW failed. */
+    err = GetLastError();
+    goto done;
+  }
 
-    /* Set IPC pid to all IPC pipes. */
-    for (i = 0; i < options->stdio_count; i++) {
-      const uv_stdio_container_t* fdopt = &options->stdio[i];
-      if (fdopt->flags & UV_CREATE_PIPE &&
-          fdopt->data.stream->type == UV_NAMED_PIPE &&
-          ((uv_pipe_t*) fdopt->data.stream)->ipc) {
-        ((uv_pipe_t*) fdopt->data.stream)->ipc_pid = info.dwProcessId;
-      }
+  /* Spawn succeeded */
+  /* Beyond this point, failure is reported asynchronously. */
+  
+  process->process_handle = info.hProcess;
+  process->pid = info.dwProcessId;
+
+  /* If the process isn't spawned as detached, assign to the global job */
+  /* object so windows will kill it when the parent process dies. */
+  if (!(options->flags & UV_PROCESS_DETACHED)) {
+    uv_once(&uv_global_job_handle_init_guard_, uv__init_global_job_handle);
+
+    if (!AssignProcessToJobObject(uv_global_job_handle_, info.hProcess)) {
+      /* AssignProcessToJobObject might fail if this process is under job
+       * control and the job doesn't have the
+       * JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK flag set, on a Windows version
+       * that doesn't support nested jobs.
+       *
+       * When that happens we just swallow the error and continue without
+       * establishing a kill-child-on-parent-exit relationship, otherwise
+       * there would be no way for libuv applications run under job control
+       * to spawn processes at all.
+       */
+      DWORD err = GetLastError();
+      if (err != ERROR_ACCESS_DENIED)
+        uv_fatal_error(err, "AssignProcessToJobObject");
     }
+  }
 
-    /* Setup notifications for when the child process exits. */
-    result = RegisterWaitForSingleObject(&process->wait_handle,
-        process->process_handle, exit_wait_callback, (void*)process, INFINITE,
-        WT_EXECUTEINWAITTHREAD | WT_EXECUTEONLYONCE);
-    if (!result) {
-      uv_fatal_error(GetLastError(), "RegisterWaitForSingleObject");
+  /* Set IPC pid to all IPC pipes. */
+  for (i = 0; i < options->stdio_count; i++) {
+    const uv_stdio_container_t* fdopt = &options->stdio[i];
+    if (fdopt->flags & UV_CREATE_PIPE &&
+        fdopt->data.stream->type == UV_NAMED_PIPE &&
+        ((uv_pipe_t*) fdopt->data.stream)->ipc) {
+      ((uv_pipe_t*) fdopt->data.stream)->ipc_pid = info.dwProcessId;
     }
+  }
 
-    CloseHandle(info.hThread);
-
-  } else {
-    /* CreateProcessW failed. */
-    err = GetLastError();
+  /* Setup notifications for when the child process exits. */
+  result = RegisterWaitForSingleObject(&process->wait_handle,
+      process->process_handle, exit_wait_callback, (void*)process, INFINITE,
+      WT_EXECUTEINWAITTHREAD | WT_EXECUTEONLYONCE);
+  if (!result) {
+    uv_fatal_error(GetLastError(), "RegisterWaitForSingleObject");
   }
 
-  /* We get here if we successfully created a process, or when we */
-  /* encountered failure that we want to report asynchronously. */
- success_or_async_failure:
+  CloseHandle(info.hThread);
+
+  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);
+
+  /* Cleanup, whether we succeeded or failed. */
+ done:
   free(application);
   free(application_path);
   free(arguments);
@@ -1027,27 +1032,6 @@ int uv_spawn(uv_loop_t* loop,
     process->child_stdio_buffer = NULL;
   }
 
-  /* Make the handle active, but only if an error didn't happen. It will */
-  /* remain active until the exit callback is made or the handle is closed, */
-  /* whichever happens first. */
-  if (err == 0) {
-    uv__handle_start(process);
-  }
-
-  return err;
-
-  /* This code path is taken when we run into an error that we want to */
-  /* report immediately. */
- immediate_failure:
-  free(application);
-  free(application_path);
-  free(arguments);
-  free(cwd);
-  free(env);
-  free(path);
-
-  assert(process->child_stdio_buffer == NULL);
-
   return uv_translate_sys_error(err);
 }
 
index 5c792f2..da62883 100644 (file)
@@ -202,6 +202,12 @@ int uv_write2(uv_write_t* req,
 }
 
 
+int uv_try_write(uv_stream_t* handle, const char* buf, size_t length) {
+  /* NOTE: Won't work with overlapped writes */
+  return UV_ENOSYS;
+}
+
+
 int uv_shutdown(uv_shutdown_t* req, uv_stream_t* handle, uv_shutdown_cb cb) {
   uv_loop_t* loop = handle->loop;
 
index a818343..266b881 100644 (file)
 static char *process_title;
 static CRITICAL_SECTION process_title_lock;
 
-/* The tick frequency of the high-resolution clock. */
-static uint64_t hrtime_frequency_ = 0;
+/* Frequency (ticks per nanosecond) of the high-resolution clock. */
+static double hrtime_frequency_ = 0;
 
 
 /*
  * One-time intialization code for functionality defined in util.c.
  */
 void uv__util_init() {
+  LARGE_INTEGER perf_frequency;
+
   /* Initialize process title access mutex. */
   InitializeCriticalSection(&process_title_lock);
 
   /* Retrieve high-resolution timer frequency. */
-  if (!QueryPerformanceFrequency((LARGE_INTEGER*) &hrtime_frequency_))
-    hrtime_frequency_ = 0;
+  if (QueryPerformanceFrequency(&perf_frequency))
+    hrtime_frequency_ = (double) perf_frequency.QuadPart / (double) NANOSEC;
+  else
+    hrtime_frequency_= 0;
 }
 
 
@@ -447,7 +451,7 @@ uint64_t uv_hrtime(void) {
   uv__once_init();
 
   /* If the performance frequency is zero, there's no support. */
-  if (!hrtime_frequency_) {
+  if (hrtime_frequency_ == 0) {
     /* uv__set_sys_error(loop, ERROR_NOT_SUPPORTED); */
     return 0;
   }
@@ -457,12 +461,11 @@ uint64_t uv_hrtime(void) {
     return 0;
   }
 
-  /* Because we have no guarantee about the order of magnitude of the */
-  /* performance counter frequency, and there may not be much headroom to */
-  /* multiply by NANOSEC without overflowing, we use 128-bit math instead. */
-  return ((uint64_t) counter.LowPart * NANOSEC / hrtime_frequency_) +
-         (((uint64_t) counter.HighPart * NANOSEC / hrtime_frequency_)
-         << 32);
+  /* Because we have no guarantee about the order of magnitude of the
+   * performance counter frequency, integer math could cause this computation
+   * to overflow. Therefore we resort to floating point math.
+   */
+  return (uint64_t) ((double) counter.QuadPart / hrtime_frequency_);
 }
 
 
diff --git a/deps/uv/test/test-emfile.c b/deps/uv/test/test-emfile.c
new file mode 100644 (file)
index 0000000..98b7da5
--- /dev/null
@@ -0,0 +1,111 @@
+/* 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.
+ */
+
+#if !defined(_WIN32)
+
+#include "uv.h"
+#include "task.h"
+
+#include <errno.h>
+#include <stdio.h>
+#include <sys/resource.h>
+#include <unistd.h>
+
+static void connection_cb(uv_stream_t* server_handle, int status);
+static void connect_cb(uv_connect_t* req, int status);
+
+static const int maxfd = 31;
+static unsigned connect_cb_called;
+static uv_tcp_t server_handle;
+static uv_tcp_t client_handle;
+
+
+TEST_IMPL(emfile) {
+  struct sockaddr_in addr;
+  struct rlimit limits;
+  uv_connect_t connect_req;
+  uv_loop_t* loop;
+  int first_fd;
+
+  loop = uv_default_loop();
+  ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));
+  ASSERT(0 == uv_tcp_init(loop, &server_handle));
+  ASSERT(0 == uv_tcp_init(loop, &client_handle));
+  ASSERT(0 == uv_tcp_bind(&server_handle, (const struct sockaddr*) &addr));
+  ASSERT(0 == uv_listen((uv_stream_t*) &server_handle, 8, connection_cb));
+
+  /* Lower the file descriptor limit and use up all fds save one. */
+  limits.rlim_cur = limits.rlim_max = maxfd + 1;
+  if (setrlimit(RLIMIT_NOFILE, &limits)) {
+    perror("setrlimit(RLIMIT_NOFILE)");
+    ASSERT(0);
+  }
+
+  /* Remember the first one so we can clean up afterwards. */
+  do
+    first_fd = dup(0);
+  while (first_fd == -1 && errno == EINTR);
+  ASSERT(first_fd > 0);
+
+  while (dup(0) != -1 || errno == EINTR);
+  ASSERT(errno == EMFILE);
+  close(maxfd);
+
+  /* Now connect and use up the last available file descriptor.  The EMFILE
+   * handling logic in src/unix/stream.c should ensure that connect_cb() runs
+   * whereas connection_cb() should *not* run.
+   */
+  ASSERT(0 == uv_tcp_connect(&connect_req,
+                             &client_handle,
+                             (const struct sockaddr*) &addr,
+                             connect_cb));
+  ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT));
+  ASSERT(1 == connect_cb_called);
+
+  /* Close the dups again. Ignore errors in the unlikely event that the
+   * file descriptors were not contiguous.
+   */
+  while (first_fd < maxfd) {
+    close(first_fd);
+    first_fd += 1;
+  }
+
+  MAKE_VALGRIND_HAPPY();
+  return 0;
+}
+
+
+static void connection_cb(uv_stream_t* server_handle, int status) {
+  ASSERT(0 && "connection_cb should not be called.");
+}
+
+
+static void connect_cb(uv_connect_t* req, int status) {
+  /* |status| should equal 0 because the connection should have been accepted,
+   * it's just that the server immediately closes it again.
+   */
+  ASSERT(0 == status);
+  connect_cb_called += 1;
+  uv_close((uv_handle_t*) &server_handle, NULL);
+  uv_close((uv_handle_t*) &client_handle, NULL);
+}
+
+#endif  /* !defined(_WIN32) */
diff --git a/deps/uv/test/test-ip4-addr.c b/deps/uv/test/test-ip4-addr.c
new file mode 100644 (file)
index 0000000..fc61f50
--- /dev/null
@@ -0,0 +1,46 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include "uv.h"
+#include "task.h"
+
+#include <stdio.h>
+#include <string.h>
+
+
+TEST_IMPL(ip4_addr) {
+
+  struct sockaddr_in addr;
+
+  ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));
+  ASSERT(0 == uv_ip4_addr("255.255.255.255", TEST_PORT, &addr));
+  ASSERT(UV_EINVAL == uv_ip4_addr("255.255.255*000", TEST_PORT, &addr));
+  ASSERT(UV_EINVAL == uv_ip4_addr("255.255.255.256", TEST_PORT, &addr));
+  ASSERT(UV_EINVAL == uv_ip4_addr("2555.0.0.0", TEST_PORT, &addr));
+  ASSERT(UV_EINVAL == uv_ip4_addr("255", TEST_PORT, &addr));
+
+  // for broken address family
+  ASSERT(UV_EAFNOSUPPORT == uv_inet_pton(42, "127.0.0.1",
+    &addr.sin_addr.s_addr));
+
+  MAKE_VALGRIND_HAPPY();
+  return 0;
+}
index b3f2e0a..f744a20 100644 (file)
@@ -25,6 +25,7 @@ TEST_DECLARE   (close_order)
 TEST_DECLARE   (run_once)
 TEST_DECLARE   (run_nowait)
 TEST_DECLARE   (loop_stop)
+TEST_DECLARE   (loop_update_time)
 TEST_DECLARE   (barrier_1)
 TEST_DECLARE   (barrier_2)
 TEST_DECLARE   (barrier_3)
@@ -51,6 +52,7 @@ TEST_DECLARE   (pipe_ping_pong)
 TEST_DECLARE   (delayed_accept)
 TEST_DECLARE   (multiple_listen)
 TEST_DECLARE   (tcp_writealot)
+TEST_DECLARE   (tcp_try_write)
 TEST_DECLARE   (tcp_open)
 TEST_DECLARE   (tcp_connect_error_after_write)
 TEST_DECLARE   (tcp_shutdown_after_write)
@@ -216,6 +218,7 @@ 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   (spawn_detect_pipe_name_collisions_on_windows)
@@ -225,6 +228,7 @@ TEST_DECLARE   (listen_with_simultaneous_accepts)
 TEST_DECLARE   (listen_no_simultaneous_accepts)
 TEST_DECLARE   (fs_stat_root)
 #else
+TEST_DECLARE   (emfile)
 TEST_DECLARE   (close_fd)
 TEST_DECLARE   (spawn_setuid_setgid)
 TEST_DECLARE   (we_get_signal)
@@ -250,6 +254,7 @@ TASK_LIST_START
   TEST_ENTRY  (run_once)
   TEST_ENTRY  (run_nowait)
   TEST_ENTRY  (loop_stop)
+  TEST_ENTRY  (loop_update_time)
   TEST_ENTRY  (barrier_1)
   TEST_ENTRY  (barrier_2)
   TEST_ENTRY  (barrier_3)
@@ -290,6 +295,8 @@ TASK_LIST_START
   TEST_ENTRY  (tcp_writealot)
   TEST_HELPER (tcp_writealot, tcp4_echo_server)
 
+  TEST_ENTRY  (tcp_try_write)
+
   TEST_ENTRY  (tcp_open)
   TEST_HELPER (tcp_open, tcp4_echo_server)
 
@@ -457,6 +464,7 @@ TASK_LIST_START
   TEST_ENTRY  (listen_no_simultaneous_accepts)
   TEST_ENTRY  (fs_stat_root)
 #else
+  TEST_ENTRY  (emfile)
   TEST_ENTRY  (close_fd)
   TEST_ENTRY  (spawn_setuid_setgid)
   TEST_ENTRY  (we_get_signal)
@@ -513,6 +521,7 @@ TASK_LIST_START
   TEST_ENTRY  (thread_rwlock)
   TEST_ENTRY  (thread_create)
   TEST_ENTRY  (dlerror)
+  TEST_ENTRY  (ip4_addr)
   TEST_ENTRY  (ip6_addr_link_local)
 #if 0
   /* These are for testing the test runner. */
diff --git a/deps/uv/test/test-loop-time.c b/deps/uv/test/test-loop-time.c
new file mode 100644 (file)
index 0000000..49dc79b
--- /dev/null
@@ -0,0 +1,34 @@
+/* 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"
+
+
+TEST_IMPL(loop_update_time) {
+  uint64_t start;
+
+  start = uv_now(uv_default_loop());
+  while (uv_now(uv_default_loop()) - start < 1000)
+    ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_NOWAIT));
+
+  return 0;
+}
diff --git a/deps/uv/test/test-tcp-try-write.c b/deps/uv/test/test-tcp-try-write.c
new file mode 100644 (file)
index 0000000..3fd6166
--- /dev/null
@@ -0,0 +1,143 @@
+/* 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>
+
+#define MAX_BYTES 1024 * 1024
+
+#ifdef _WIN32
+
+TEST_IMPL(tcp_try_write) {
+
+  MAKE_VALGRIND_HAPPY();
+  return 0;
+}
+
+#else  /* !_WIN32 */
+
+static uv_tcp_t server;
+static uv_tcp_t client;
+static uv_tcp_t incoming;
+static int connect_cb_called;
+static int close_cb_called;
+static int connection_cb_called;
+static int bytes_read;
+static int bytes_written;
+
+
+static void close_cb(uv_handle_t* handle) {
+  close_cb_called++;
+}
+
+
+static void connect_cb(uv_connect_t* req, int status) {
+  static char zeroes[1024];
+  int r;
+  uv_buf_t buf;
+  ASSERT(status == 0);
+  connect_cb_called++;
+
+  do {
+    r = uv_try_write((uv_stream_t*) &client, zeroes, sizeof(zeroes));
+    ASSERT(r >= 0);
+    bytes_written += r;
+
+    /* Partial write */
+    if (r != (int) sizeof(zeroes))
+      break;
+  } while (1);
+  uv_close((uv_handle_t*) &client, close_cb);
+}
+
+
+static void alloc_cb(uv_handle_t* handle, size_t size, uv_buf_t* buf) {
+  static char base[1024];
+
+  buf->base = base;
+  buf->len = sizeof(base);
+}
+
+
+static void read_cb(uv_stream_t* tcp, ssize_t nread, const uv_buf_t* buf) {
+  if (nread < 0) {
+    uv_close((uv_handle_t*) tcp, close_cb);
+    uv_close((uv_handle_t*) &server, close_cb);
+    return;
+  }
+
+  bytes_read += nread;
+}
+
+
+static void connection_cb(uv_stream_t* tcp, int status) {
+  ASSERT(status == 0);
+
+  ASSERT(0 == uv_tcp_init(tcp->loop, &incoming));
+  ASSERT(0 == uv_accept(tcp, (uv_stream_t*) &incoming));
+
+  connection_cb_called++;
+  ASSERT(0 == uv_read_start((uv_stream_t*) &incoming, alloc_cb, read_cb));
+}
+
+
+static void start_server(void) {
+  struct sockaddr_in addr;
+
+  ASSERT(0 == uv_ip4_addr("0.0.0.0", TEST_PORT, &addr));
+
+  ASSERT(0 == uv_tcp_init(uv_default_loop(), &server));
+  ASSERT(0 == uv_tcp_bind(&server, (struct sockaddr*) &addr));
+  ASSERT(0 == uv_listen((uv_stream_t*) &server, 128, connection_cb));
+}
+
+
+TEST_IMPL(tcp_try_write) {
+  uv_connect_t connect_req;
+  struct sockaddr_in addr;
+
+  start_server();
+
+  ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));
+
+  ASSERT(0 == uv_tcp_init(uv_default_loop(), &client));
+  ASSERT(0 == uv_tcp_connect(&connect_req,
+                             &client,
+                             (struct sockaddr*) &addr,
+                             connect_cb));
+
+  ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT));
+
+  ASSERT(connect_cb_called == 1);
+  ASSERT(close_cb_called == 3);
+  ASSERT(connection_cb_called == 1);
+  ASSERT(bytes_read == bytes_written);
+  ASSERT(bytes_written > 0);
+
+  MAKE_VALGRIND_HAPPY();
+  return 0;
+}
+
+#endif  /* !_WIN32 */
index 25190b6..962efac 100644 (file)
         'test/test-delayed-accept.c',
         'test/test-error.c',
         'test/test-embed.c',
+        'test/test-emfile.c',
         'test/test-fail-always.c',
         'test/test-fs.c',
         'test/test-fs-event.c',
         'test/test-list.h',
         'test/test-loop-handles.c',
         'test/test-loop-stop.c',
+        'test/test-loop-time.c',
         'test/test-walk-handles.c',
         'test/test-watcher-cross-stop.c',
         'test/test-multiple-listen.c',
         'test/test-tcp-open.c',
         'test/test-tcp-write-to-half-open-connection.c',
         'test/test-tcp-writealot.c',
+        'test/test-tcp-try-write.c',
         'test/test-tcp-unexpected-read.c',
         'test/test-tcp-read-stop.c',
         'test/test-threadpool.c',
         'test/test-udp-multicast-join.c',
         'test/test-dlerror.c',
         'test/test-udp-multicast-ttl.c',
+        'test/test-ip4-addr.c',
         'test/test-ip6-addr.c',
       ],
       'conditions': [