uv: Upgrade to v0.11.16

This commit is contained in:
Fedor Indutny 2013-12-13 22:35:09 +04:00
parent 069dd07a17
commit f61d9405bf
32 changed files with 826 additions and 141 deletions

1
deps/uv/.gitignore vendored
View File

@ -3,6 +3,7 @@
*.l[oa] *.l[oa]
*.opensdf *.opensdf
*.orig *.orig
*.pyc
*.sdf *.sdf
*.suo *.suo
core core

2
deps/uv/.mailmap vendored
View File

@ -8,6 +8,8 @@ Frank Denis <github@pureftpd.org>
Isaac Z. Schlueter <i@izs.me> Isaac Z. Schlueter <i@izs.me>
Keno Fischer <kenof@stanford.edu> <kfischer+github@college.harvard.edu> Keno Fischer <kenof@stanford.edu> <kfischer+github@college.harvard.edu>
Keno Fischer <kenof@stanford.edu> <kfischer@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> Robert Mustacchi <rm@joyent.com> <rm@fingolfin.org>
Ryan Dahl <ryan@joyent.com> <ry@tinyclouds.org> Ryan Dahl <ryan@joyent.com> <ry@tinyclouds.org>
Ryan Emery <seebees@gmail.com> Ryan Emery <seebees@gmail.com>

9
deps/uv/AUTHORS vendored
View File

@ -99,3 +99,12 @@ Maks Naumov <maksqwe1@ukr.net>
Sean Farrell <sean.farrell@rioki.org> Sean Farrell <sean.farrell@rioki.org>
Chris Bank <cbank@adobe.com> Chris Bank <cbank@adobe.com>
Geert Jansen <geertj@gmail.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>

177
deps/uv/CONTRIBUTING.md vendored Normal file
View File

@ -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

42
deps/uv/ChangeLog vendored
View 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: Changes since version 0.11.14:

15
deps/uv/Makefile.am vendored
View File

@ -126,6 +126,7 @@ test_run_tests_SOURCES = test/blackhole-server.c \
test/test-delayed-accept.c \ test/test-delayed-accept.c \
test/test-dlerror.c \ test/test-dlerror.c \
test/test-embed.c \ test/test-embed.c \
test/test-emfile.c \
test/test-error.c \ test/test-error.c \
test/test-fail-always.c \ test/test-fail-always.c \
test/test-fs-event.c \ test/test-fs-event.c \
@ -138,12 +139,14 @@ test_run_tests_SOURCES = test/blackhole-server.c \
test/test-getsockname.c \ test/test-getsockname.c \
test/test-hrtime.c \ test/test-hrtime.c \
test/test-idle.c \ test/test-idle.c \
test/test-ip4-addr.c \
test/test-ip6-addr.c \ test/test-ip6-addr.c \
test/test-ipc-send-recv.c \ test/test-ipc-send-recv.c \
test/test-ipc.c \ test/test-ipc.c \
test/test-list.h \ test/test-list.h \
test/test-loop-handles.c \ test/test-loop-handles.c \
test/test-loop-stop.c \ test/test-loop-stop.c \
test/test-loop-time.c \
test/test-multiple-listen.c \ test/test-multiple-listen.c \
test/test-mutexes.c \ test/test-mutexes.c \
test/test-osx-select.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-unexpected-read.c \
test/test-tcp-write-to-half-open-connection.c \ test/test-tcp-write-to-half-open-connection.c \
test/test-tcp-writealot.c \ test/test-tcp-writealot.c \
test/test-tcp-try-write.c \
test/test-thread.c \ test/test-thread.c \
test/test-threadpool-cancel.c \ test/test-threadpool-cancel.c \
test/test-threadpool.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 CLEANFILES += src/unix/uv-dtrace.o src/unix/uv-dtrace.lo
endif 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 include/uv-dtrace.h: src/unix/uv-dtrace.d
$(AM_V_GEN)$(DTRACE) $(DTRACEFLAGS) -h -xnolibs -s $< -o $(top_srcdir)/$@ $(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} 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'" \ "pic_object='uv-dtrace.o'" \
"non_pic_object='uv-dtrace.o'" \ "non_pic_object='uv-dtrace.o'" \
> ${top_builddir}/uv-dtrace.lo > ${top_builddir}/uv-dtrace.lo
endif

15
deps/uv/README.md vendored
View File

@ -1,7 +1,7 @@
# libuv # libuv
libuv is a multi-platform support library with a focus on asynchronous I/O. It 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/), used by Mozilla's [Rust language](http://www.rust-lang.org/),
[Luvit](http://luvit.io/), [Julia](http://julialang.org/), [Luvit](http://luvit.io/), [Julia](http://julialang.org/),
[pyuv](https://crate.io/packages/pyuv/), and others. [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 Note for UNIX users: compile your project with `-D_LARGEFILE_SOURCE` and
`-D_FILE_OFFSET_BITS=64`. GYP builds take care of that automatically. `-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 ## Supported Platforms
Microsoft Windows operating systems since Windows XP SP2. It can be built 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. Solaris 121 and later using GCC toolchain.
## patches
See the [guidelines for contributing][].
[node.js]: http://nodejs.org/ [node.js]: http://nodejs.org/
[GYP]: http://code.google.com/p/gyp/ [GYP]: http://code.google.com/p/gyp/
[Visual Studio Express 2010]: http://www.microsoft.com/visualstudio/eng/products/visual-studio-2010-express [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

View File

@ -13,7 +13,7 @@
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
AC_PREREQ(2.57) 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]) AC_CONFIG_MACRO_DIR([m4])
m4_include([m4/libuv-extra-automake-flags.m4]) m4_include([m4/libuv-extra-automake-flags.m4])
AM_INIT_AUTOMAKE([-Wall -Werror foreign subdir-objects] UV_EXTRA_AUTOMAKE_FLAGS) 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([SUNOS], [AS_CASE([$host_os], [solaris*], [true], [false])])
AM_CONDITIONAL([WINNT], [AS_CASE([$host_os], [mingw*], [true], [false])]) AM_CONDITIONAL([WINNT], [AS_CASE([$host_os], [mingw*], [true], [false])])
PANDORA_ENABLE_DTRACE 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_CONFIG_FILES([Makefile])
AC_OUTPUT AC_OUTPUT

2
deps/uv/gyp_uv.py vendored
View File

@ -75,7 +75,7 @@ if __name__ == '__main__':
if sys.platform != 'win32': if sys.platform != 'win32':
if '-f' not in args: if '-f' not in args:
args.extend('-f make'.split()) 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(['-Goutput_dir=' + output_dir])
args.extend(['--generator-output', output_dir]) args.extend(['--generator-output', output_dir])
(major, minor), is_clang = compiler_version() (major, minor), is_clang = compiler_version()

View File

@ -40,6 +40,8 @@
#define UV__EAI_SERVICE (-3010) #define UV__EAI_SERVICE (-3010)
#define UV__EAI_SOCKTYPE (-3011) #define UV__EAI_SOCKTYPE (-3011)
#define UV__EAI_SYSTEM (-3012) /* TODO(bnoordhuis) Return system error. */ #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 /* Only map to the system errno on non-Windows platforms. It's apparently
* a fairly common practice for Windows programmers to redefine errno codes. * a fairly common practice for Windows programmers to redefine errno codes.

13
deps/uv/include/uv.h vendored
View File

@ -71,12 +71,15 @@ extern "C" {
XX(EAI_ADDRFAMILY, "address family not supported") \ XX(EAI_ADDRFAMILY, "address family not supported") \
XX(EAI_AGAIN, "temporary failure") \ XX(EAI_AGAIN, "temporary failure") \
XX(EAI_BADFLAGS, "bad ai_flags value") \ XX(EAI_BADFLAGS, "bad ai_flags value") \
XX(EAI_BADHINTS, "invalid value for hints") \
XX(EAI_CANCELED, "request canceled") \ XX(EAI_CANCELED, "request canceled") \
XX(EAI_FAIL, "permanent failure") \ XX(EAI_FAIL, "permanent failure") \
XX(EAI_FAMILY, "ai_family not supported") \ XX(EAI_FAMILY, "ai_family not supported") \
XX(EAI_MEMORY, "out of memory") \ XX(EAI_MEMORY, "out of memory") \
XX(EAI_NODATA, "no address") \ XX(EAI_NODATA, "no address") \
XX(EAI_NONAME, "unknown node or service") \ 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_SERVICE, "service not available for socket type") \
XX(EAI_SOCKTYPE, "socket type not supported") \ XX(EAI_SOCKTYPE, "socket type not supported") \
XX(EAI_SYSTEM, "system error") \ XX(EAI_SYSTEM, "system error") \
@ -670,6 +673,16 @@ UV_EXTERN int uv_write2(uv_write_t* req,
uv_stream_t* send_handle, uv_stream_t* send_handle,
uv_write_cb cb); 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 */ /* uv_write_t is a subclass of uv_req_t */
struct uv_write_s { struct uv_write_s {
UV_REQ_FIELDS UV_REQ_FIELDS

11
deps/uv/libuv.pc.in vendored Normal file
View File

@ -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}

View File

@ -260,6 +260,9 @@ int uv_run(uv_loop_t* loop, uv_run_mode mode) {
int r; int r;
r = uv__loop_alive(loop); r = uv__loop_alive(loop);
if (!r)
uv__update_time(loop);
while (r != 0 && loop->stop_flag == 0) { while (r != 0 && loop->stop_flag == 0) {
UV_TICK_START(loop, mode); UV_TICK_START(loop, mode);

View File

@ -75,7 +75,7 @@ int uv_exepath(char* buffer, size_t* size) {
result = _NSGetExecutablePath(buffer, &usize); result = _NSGetExecutablePath(buffer, &usize);
if (result) return result; if (result) return result;
path = (char*)malloc(2 * PATH_MAX); path = malloc(2 * PATH_MAX);
fullpath = realpath(buffer, path); fullpath = realpath(buffer, path);
if (fullpath == NULL) { if (fullpath == NULL) {
SAVE_ERRNO(free(path)); SAVE_ERRNO(free(path));

View 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. * 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 * 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 * 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. * mean data loss: we've read data but now we can't write it out.

View File

@ -251,13 +251,15 @@ static void uv__fsevents_event_cb(ConstFSEventStreamRef streamRef,
if (strncmp(path, handle->realpath, handle->realpath_len) != 0) if (strncmp(path, handle->realpath, handle->realpath_len) != 0)
continue; continue;
path += handle->realpath_len; if (handle->realpath_len > 1 || *handle->realpath != '/') {
len -= handle->realpath_len; path += handle->realpath_len;
len -= handle->realpath_len;
/* Skip back slash */ /* Skip forward slash */
if (*path != 0) { if (*path != '\0') {
path++; path++;
len--; len--;
}
} }
#ifdef MAC_OS_X_VERSION_10_7 #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 */ #endif /* MAC_OS_X_VERSION_10_7 */
/* Do not emit events from subdirectories (without option set) */ /* Do not emit events from subdirectories (without option set) */
if ((handle->cf_flags & UV_FS_EVENT_RECURSIVE) == 0) { if ((handle->cf_flags & UV_FS_EVENT_RECURSIVE) == 0 && *path != 0) {
pos = strchr(path, '/'); pos = strchr(path + 1, '/');
if (pos != NULL && pos != path + 1) if (pos != NULL)
continue; continue;
} }
@ -588,7 +590,7 @@ static int uv__fsevents_loop_init(uv_loop_t* loop) {
err = uv_mutex_init(&loop->cf_mutex); err = uv_mutex_init(&loop->cf_mutex);
if (err) if (err)
return err; goto fail_mutex_init;
err = uv_sem_init(&loop->cf_sem, 0); err = uv_sem_init(&loop->cf_sem, 0);
if (err) if (err)
@ -658,6 +660,8 @@ fail_fsevent_sem_init:
fail_sem_init: fail_sem_init:
uv_mutex_destroy(&loop->cf_mutex); uv_mutex_destroy(&loop->cf_mutex);
fail_mutex_init:
free(state); free(state);
return err; return err;
} }

View File

@ -243,7 +243,6 @@ void uv__fsevents_loop_delete(uv_loop_t* loop);
/* OSX < 10.7 has no file events, polyfill them */ /* OSX < 10.7 has no file events, polyfill them */
#ifndef MAC_OS_X_VERSION_10_7 #ifndef MAC_OS_X_VERSION_10_7
static const int kFSEventStreamCreateFlagNoDefer = 0x00000002;
static const int kFSEventStreamCreateFlagFileEvents = 0x00000010; static const int kFSEventStreamCreateFlagFileEvents = 0x00000010;
static const int kFSEventStreamEventFlagItemCreated = 0x00000100; static const int kFSEventStreamEventFlagItemCreated = 0x00000100;
static const int kFSEventStreamEventFlagItemRemoved = 0x00000200; static const int kFSEventStreamEventFlagItemRemoved = 0x00000200;

View File

@ -348,6 +348,7 @@ static void uv__signal_event(uv_loop_t* loop,
int r; int r;
bytes = 0; bytes = 0;
end = 0;
do { do {
r = read(loop->signal_pipefd[0], buf + bytes, sizeof(buf) - bytes); r = read(loop->signal_pipefd[0], buf + bytes, sizeof(buf) - bytes);

View File

@ -462,27 +462,22 @@ void uv__stream_destroy(uv_stream_t* stream) {
* calling close() and accept(). * calling close() and accept().
*/ */
static int uv__emfile_trick(uv_loop_t* loop, int accept_fd) { static int uv__emfile_trick(uv_loop_t* loop, int accept_fd) {
int fd; int err;
if (loop->emfile_fd == -1) if (loop->emfile_fd == -1)
return -EMFILE; return -EMFILE;
uv__close(loop->emfile_fd); uv__close(loop->emfile_fd);
loop->emfile_fd = -1;
for (;;) { do {
fd = uv__accept(accept_fd); err = uv__accept(accept_fd);
if (err >= 0)
uv__close(err);
} while (err >= 0 || err == -EINTR);
if (fd != -1) { SAVE_ERRNO(loop->emfile_fd = uv__open_cloexec("/", O_RDONLY));
uv__close(fd); return err;
continue;
}
if (errno == EINTR)
continue;
SAVE_ERRNO(loop->emfile_fd = uv__open_cloexec("/", O_RDONLY));
return -errno;
}
} }
@ -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 /* 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 * 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 * 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 * they should stop writing - which they should if we got an error. Something
* revisit in future revisions of the libuv API. * to revisit in future revisions of the libuv API.
*/ */
if (req->error == 0) { if (req->error == 0) {
if (req->bufs != req->bufsml) 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, static int uv__read_start_common(uv_stream_t* stream,
uv_alloc_cb alloc_cb, uv_alloc_cb alloc_cb,
uv_read_cb read_cb, uv_read_cb read_cb,

View File

@ -102,9 +102,7 @@ int uv_ip4_addr(const char* ip, int port, struct sockaddr_in* addr) {
memset(addr, 0, sizeof(*addr)); memset(addr, 0, sizeof(*addr));
addr->sin_family = AF_INET; addr->sin_family = AF_INET;
addr->sin_port = htons(port); addr->sin_port = htons(port);
/* TODO(bnoordhuis) Don't use inet_addr(), no good way to detect errors. */ return uv_inet_pton(AF_INET, ip, &(addr->sin_addr.s_addr));
addr->sin_addr.s_addr = inet_addr(ip);
return 0;
} }
@ -140,10 +138,7 @@ int uv_ip6_addr(const char* ip, int port, struct sockaddr_in6* addr) {
} }
#endif #endif
/* TODO(bnoordhuis) Return an error when the address is bad. */ return uv_inet_pton(AF_INET6, ip, &addr->sin6_addr);
uv_inet_pton(AF_INET6, ip, &addr->sin6_addr);
return 0;
} }
@ -404,6 +399,9 @@ int uv__getaddrinfo_translate_error(int sys_err) {
#if defined(EAI_BADFLAGS) #if defined(EAI_BADFLAGS)
case EAI_BADFLAGS: return UV_EAI_BADFLAGS; case EAI_BADFLAGS: return UV_EAI_BADFLAGS;
#endif #endif
#if defined(EAI_BADHINTS)
case EAI_BADHINTS: return UV_EAI_BADHINTS;
#endif
#if defined(EAI_CANCELED) #if defined(EAI_CANCELED)
case EAI_CANCELED: return UV_EAI_CANCELED; case EAI_CANCELED: return UV_EAI_CANCELED;
#endif #endif
@ -424,6 +422,12 @@ int uv__getaddrinfo_translate_error(int sys_err) {
case EAI_NONAME: return UV_EAI_NONAME; case EAI_NONAME: return UV_EAI_NONAME;
# endif # endif
#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) #if defined(EAI_SERVICE)
case EAI_SERVICE: return UV_EAI_SERVICE; case EAI_SERVICE: return UV_EAI_SERVICE;
#endif #endif

View File

@ -31,8 +31,8 @@
#define UV_VERSION_MAJOR 0 #define UV_VERSION_MAJOR 0
#define UV_VERSION_MINOR 11 #define UV_VERSION_MINOR 11
#define UV_VERSION_PATCH 15 #define UV_VERSION_PATCH 17
#define UV_VERSION_IS_RELEASE 1 #define UV_VERSION_IS_RELEASE 0
#define UV_VERSION ((UV_VERSION_MAJOR << 16) | \ #define UV_VERSION ((UV_VERSION_MAJOR << 16) | \

View File

@ -273,6 +273,9 @@ int uv_run(uv_loop_t *loop, uv_run_mode mode) {
poll = &uv_poll; poll = &uv_poll;
r = uv__loop_alive(loop); r = uv__loop_alive(loop);
if (!r)
uv_update_time(loop);
while (r != 0 && loop->stop_flag == 0) { while (r != 0 && loop->stop_flag == 0) {
uv_update_time(loop); uv_update_time(loop);
uv_process_timers(loop); uv_process_timers(loop);

View 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"); 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); file_info->FileName);
filenamew[size - 1] = L'\0'; filenamew[size - 1] = L'\0';

View File

@ -832,26 +832,26 @@ int uv_spawn(uv_loop_t* loop,
err = uv_utf8_to_utf16_alloc(options->file, &application); err = uv_utf8_to_utf16_alloc(options->file, &application);
if (err) if (err)
goto immediate_failure; goto done;
err = make_program_args( err = make_program_args(
options->args, options->args,
options->flags & UV_PROCESS_WINDOWS_VERBATIM_ARGUMENTS, options->flags & UV_PROCESS_WINDOWS_VERBATIM_ARGUMENTS,
&arguments); &arguments);
if (err) if (err)
goto immediate_failure; goto done;
if (options->env) { if (options->env) {
err = make_program_env(options->env, &env); err = make_program_env(options->env, &env);
if (err) if (err)
goto immediate_failure; goto done;
} }
if (options->cwd) { if (options->cwd) {
/* Explicit cwd */ /* Explicit cwd */
err = uv_utf8_to_utf16_alloc(options->cwd, &cwd); err = uv_utf8_to_utf16_alloc(options->cwd, &cwd);
if (err) if (err)
goto immediate_failure; goto done;
} else { } else {
/* Inherit cwd */ /* Inherit cwd */
@ -860,19 +860,19 @@ int uv_spawn(uv_loop_t* loop,
cwd_len = GetCurrentDirectoryW(0, NULL); cwd_len = GetCurrentDirectoryW(0, NULL);
if (!cwd_len) { if (!cwd_len) {
err = GetLastError(); err = GetLastError();
goto immediate_failure; goto done;
} }
cwd = (WCHAR*) malloc(cwd_len * sizeof(WCHAR)); cwd = (WCHAR*) malloc(cwd_len * sizeof(WCHAR));
if (cwd == NULL) { if (cwd == NULL) {
err = ERROR_OUTOFMEMORY; err = ERROR_OUTOFMEMORY;
goto immediate_failure; goto done;
} }
r = GetCurrentDirectoryW(cwd_len, cwd); r = GetCurrentDirectoryW(cwd_len, cwd);
if (r == 0 || r >= cwd_len) { if (r == 0 || r >= cwd_len) {
err = GetLastError(); 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); path_len = GetEnvironmentVariableW(L"PATH", NULL, 0);
if (path_len == 0) { if (path_len == 0) {
err = GetLastError(); err = GetLastError();
goto immediate_failure; goto done;
} }
path = (WCHAR*) malloc(path_len * sizeof(WCHAR)); path = (WCHAR*) malloc(path_len * sizeof(WCHAR));
if (path == NULL) { if (path == NULL) {
err = ERROR_OUTOFMEMORY; err = ERROR_OUTOFMEMORY;
goto immediate_failure; goto done;
} }
r = GetEnvironmentVariableW(L"PATH", path, path_len); r = GetEnvironmentVariableW(L"PATH", path, path_len);
if (r == 0 || r >= path_len) { if (r == 0 || r >= path_len) {
err = GetLastError(); err = GetLastError();
goto immediate_failure; goto done;
} }
} }
err = uv__stdio_create(loop, options, &process->child_stdio_buffer); err = uv__stdio_create(loop, options, &process->child_stdio_buffer);
if (err) if (err)
goto immediate_failure; goto done;
/* Beyond this point, failure is reported asynchronously. */
application_path = search_path(application, application_path = search_path(application,
cwd, cwd,
@ -911,7 +909,7 @@ int uv_spawn(uv_loop_t* loop,
if (application_path == NULL) { if (application_path == NULL) {
/* Not found. */ /* Not found. */
err = ERROR_FILE_NOT_FOUND; err = ERROR_FILE_NOT_FOUND;
goto success_or_async_failure; goto done;
} }
startup.cb = sizeof(startup); startup.cb = sizeof(startup);
@ -950,7 +948,7 @@ int uv_spawn(uv_loop_t* loop,
process_flags |= DETACHED_PROCESS | CREATE_NEW_PROCESS_GROUP; process_flags |= DETACHED_PROCESS | CREATE_NEW_PROCESS_GROUP;
} }
if (CreateProcessW(application_path, if (!CreateProcessW(application_path,
arguments, arguments,
NULL, NULL,
NULL, NULL,
@ -960,60 +958,67 @@ int uv_spawn(uv_loop_t* loop,
cwd, cwd,
&startup, &startup,
&info)) { &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");
}
}
/* 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;
}
}
/* 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");
}
CloseHandle(info.hThread);
} else {
/* CreateProcessW failed. */ /* CreateProcessW failed. */
err = GetLastError(); err = GetLastError();
goto done;
} }
/* We get here if we successfully created a process, or when we */ /* Spawn succeeded */
/* encountered failure that we want to report asynchronously. */ /* Beyond this point, failure is reported asynchronously. */
success_or_async_failure:
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");
}
}
/* 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;
}
}
/* 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");
}
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);
free(application_path); free(application_path);
free(arguments); free(arguments);
@ -1027,27 +1032,6 @@ int uv_spawn(uv_loop_t* loop,
process->child_stdio_buffer = NULL; 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); return uv_translate_sys_error(err);
} }

View 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) { int uv_shutdown(uv_shutdown_t* req, uv_stream_t* handle, uv_shutdown_cb cb) {
uv_loop_t* loop = handle->loop; uv_loop_t* loop = handle->loop;

View File

@ -59,20 +59,24 @@
static char *process_title; static char *process_title;
static CRITICAL_SECTION process_title_lock; static CRITICAL_SECTION process_title_lock;
/* The tick frequency of the high-resolution clock. */ /* Frequency (ticks per nanosecond) of the high-resolution clock. */
static uint64_t hrtime_frequency_ = 0; static double hrtime_frequency_ = 0;
/* /*
* One-time intialization code for functionality defined in util.c. * One-time intialization code for functionality defined in util.c.
*/ */
void uv__util_init() { void uv__util_init() {
LARGE_INTEGER perf_frequency;
/* Initialize process title access mutex. */ /* Initialize process title access mutex. */
InitializeCriticalSection(&process_title_lock); InitializeCriticalSection(&process_title_lock);
/* Retrieve high-resolution timer frequency. */ /* Retrieve high-resolution timer frequency. */
if (!QueryPerformanceFrequency((LARGE_INTEGER*) &hrtime_frequency_)) if (QueryPerformanceFrequency(&perf_frequency))
hrtime_frequency_ = 0; hrtime_frequency_ = (double) perf_frequency.QuadPart / (double) NANOSEC;
else
hrtime_frequency_= 0;
} }
@ -447,7 +451,7 @@ uint64_t uv_hrtime(void) {
uv__once_init(); uv__once_init();
/* If the performance frequency is zero, there's no support. */ /* 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); */ /* uv__set_sys_error(loop, ERROR_NOT_SUPPORTED); */
return 0; return 0;
} }
@ -457,12 +461,11 @@ uint64_t uv_hrtime(void) {
return 0; return 0;
} }
/* Because we have no guarantee about the order of magnitude of the */ /* Because we have no guarantee about the order of magnitude of the
/* performance counter frequency, and there may not be much headroom to */ * performance counter frequency, integer math could cause this computation
/* multiply by NANOSEC without overflowing, we use 128-bit math instead. */ * to overflow. Therefore we resort to floating point math.
return ((uint64_t) counter.LowPart * NANOSEC / hrtime_frequency_) + */
(((uint64_t) counter.HighPart * NANOSEC / hrtime_frequency_) return (uint64_t) ((double) counter.QuadPart / hrtime_frequency_);
<< 32);
} }

111
deps/uv/test/test-emfile.c vendored Normal file
View File

@ -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) */

46
deps/uv/test/test-ip4-addr.c vendored Normal file
View File

@ -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;
}

View File

@ -25,6 +25,7 @@ TEST_DECLARE (close_order)
TEST_DECLARE (run_once) TEST_DECLARE (run_once)
TEST_DECLARE (run_nowait) TEST_DECLARE (run_nowait)
TEST_DECLARE (loop_stop) TEST_DECLARE (loop_stop)
TEST_DECLARE (loop_update_time)
TEST_DECLARE (barrier_1) TEST_DECLARE (barrier_1)
TEST_DECLARE (barrier_2) TEST_DECLARE (barrier_2)
TEST_DECLARE (barrier_3) TEST_DECLARE (barrier_3)
@ -51,6 +52,7 @@ TEST_DECLARE (pipe_ping_pong)
TEST_DECLARE (delayed_accept) TEST_DECLARE (delayed_accept)
TEST_DECLARE (multiple_listen) TEST_DECLARE (multiple_listen)
TEST_DECLARE (tcp_writealot) TEST_DECLARE (tcp_writealot)
TEST_DECLARE (tcp_try_write)
TEST_DECLARE (tcp_open) TEST_DECLARE (tcp_open)
TEST_DECLARE (tcp_connect_error_after_write) TEST_DECLARE (tcp_connect_error_after_write)
TEST_DECLARE (tcp_shutdown_after_write) TEST_DECLARE (tcp_shutdown_after_write)
@ -216,6 +218,7 @@ TEST_DECLARE (dlerror)
TEST_DECLARE (poll_duplex) TEST_DECLARE (poll_duplex)
TEST_DECLARE (poll_unidirectional) TEST_DECLARE (poll_unidirectional)
TEST_DECLARE (poll_close) TEST_DECLARE (poll_close)
TEST_DECLARE (ip4_addr)
TEST_DECLARE (ip6_addr_link_local) TEST_DECLARE (ip6_addr_link_local)
#ifdef _WIN32 #ifdef _WIN32
TEST_DECLARE (spawn_detect_pipe_name_collisions_on_windows) 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 (listen_no_simultaneous_accepts)
TEST_DECLARE (fs_stat_root) TEST_DECLARE (fs_stat_root)
#else #else
TEST_DECLARE (emfile)
TEST_DECLARE (close_fd) TEST_DECLARE (close_fd)
TEST_DECLARE (spawn_setuid_setgid) TEST_DECLARE (spawn_setuid_setgid)
TEST_DECLARE (we_get_signal) TEST_DECLARE (we_get_signal)
@ -250,6 +254,7 @@ TASK_LIST_START
TEST_ENTRY (run_once) TEST_ENTRY (run_once)
TEST_ENTRY (run_nowait) TEST_ENTRY (run_nowait)
TEST_ENTRY (loop_stop) TEST_ENTRY (loop_stop)
TEST_ENTRY (loop_update_time)
TEST_ENTRY (barrier_1) TEST_ENTRY (barrier_1)
TEST_ENTRY (barrier_2) TEST_ENTRY (barrier_2)
TEST_ENTRY (barrier_3) TEST_ENTRY (barrier_3)
@ -290,6 +295,8 @@ TASK_LIST_START
TEST_ENTRY (tcp_writealot) TEST_ENTRY (tcp_writealot)
TEST_HELPER (tcp_writealot, tcp4_echo_server) TEST_HELPER (tcp_writealot, tcp4_echo_server)
TEST_ENTRY (tcp_try_write)
TEST_ENTRY (tcp_open) TEST_ENTRY (tcp_open)
TEST_HELPER (tcp_open, tcp4_echo_server) TEST_HELPER (tcp_open, tcp4_echo_server)
@ -457,6 +464,7 @@ TASK_LIST_START
TEST_ENTRY (listen_no_simultaneous_accepts) TEST_ENTRY (listen_no_simultaneous_accepts)
TEST_ENTRY (fs_stat_root) TEST_ENTRY (fs_stat_root)
#else #else
TEST_ENTRY (emfile)
TEST_ENTRY (close_fd) TEST_ENTRY (close_fd)
TEST_ENTRY (spawn_setuid_setgid) TEST_ENTRY (spawn_setuid_setgid)
TEST_ENTRY (we_get_signal) TEST_ENTRY (we_get_signal)
@ -513,6 +521,7 @@ TASK_LIST_START
TEST_ENTRY (thread_rwlock) TEST_ENTRY (thread_rwlock)
TEST_ENTRY (thread_create) TEST_ENTRY (thread_create)
TEST_ENTRY (dlerror) TEST_ENTRY (dlerror)
TEST_ENTRY (ip4_addr)
TEST_ENTRY (ip6_addr_link_local) TEST_ENTRY (ip6_addr_link_local)
#if 0 #if 0
/* These are for testing the test runner. */ /* These are for testing the test runner. */

34
deps/uv/test/test-loop-time.c vendored Normal file
View File

@ -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;
}

143
deps/uv/test/test-tcp-try-write.c vendored Normal file
View File

@ -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 */

4
deps/uv/uv.gyp vendored
View File

@ -309,6 +309,7 @@
'test/test-delayed-accept.c', 'test/test-delayed-accept.c',
'test/test-error.c', 'test/test-error.c',
'test/test-embed.c', 'test/test-embed.c',
'test/test-emfile.c',
'test/test-fail-always.c', 'test/test-fail-always.c',
'test/test-fs.c', 'test/test-fs.c',
'test/test-fs-event.c', 'test/test-fs-event.c',
@ -323,6 +324,7 @@
'test/test-list.h', 'test/test-list.h',
'test/test-loop-handles.c', 'test/test-loop-handles.c',
'test/test-loop-stop.c', 'test/test-loop-stop.c',
'test/test-loop-time.c',
'test/test-walk-handles.c', 'test/test-walk-handles.c',
'test/test-watcher-cross-stop.c', 'test/test-watcher-cross-stop.c',
'test/test-multiple-listen.c', 'test/test-multiple-listen.c',
@ -360,6 +362,7 @@
'test/test-tcp-open.c', 'test/test-tcp-open.c',
'test/test-tcp-write-to-half-open-connection.c', 'test/test-tcp-write-to-half-open-connection.c',
'test/test-tcp-writealot.c', 'test/test-tcp-writealot.c',
'test/test-tcp-try-write.c',
'test/test-tcp-unexpected-read.c', 'test/test-tcp-unexpected-read.c',
'test/test-tcp-read-stop.c', 'test/test-tcp-read-stop.c',
'test/test-threadpool.c', 'test/test-threadpool.c',
@ -380,6 +383,7 @@
'test/test-udp-multicast-join.c', 'test/test-udp-multicast-join.c',
'test/test-dlerror.c', 'test/test-dlerror.c',
'test/test-udp-multicast-ttl.c', 'test/test-udp-multicast-ttl.c',
'test/test-ip4-addr.c',
'test/test-ip6-addr.c', 'test/test-ip6-addr.c',
], ],
'conditions': [ 'conditions': [