Browse Source

deps: update libuv to 0.10.36

PR: #9274
PR-URL: https://github.com/joyent/node/pull/9274
Reviewed-By: Julien Gilli <julien.gilli@joyent.com>
v0.10.37-release
Saúl Ibarra Corretgé 10 years ago
committed by Julien Gilli
parent
commit
dcff5d565c
  1. 3
      deps/uv/AUTHORS
  2. 70
      deps/uv/ChangeLog
  3. 2
      deps/uv/build.mk
  4. 1
      deps/uv/checksparse.sh
  5. 4
      deps/uv/config-unix.mk
  6. 5
      deps/uv/include/uv-private/uv-win.h
  7. 43
      deps/uv/src/unix/async.c
  8. 60
      deps/uv/src/unix/atomic-ops.h
  9. 15
      deps/uv/src/unix/internal.h
  10. 40
      deps/uv/src/unix/linux-core.c
  11. 6
      deps/uv/src/unix/linux-syscalls.c
  12. 2
      deps/uv/src/unix/linux-syscalls.h
  13. 15
      deps/uv/src/unix/process.c
  14. 13
      deps/uv/src/unix/stream.c
  15. 2
      deps/uv/src/version.c
  16. 35
      deps/uv/src/win/dl.c
  17. 4
      deps/uv/src/win/fs.c
  18. 4
      deps/uv/src/win/internal.h
  19. 40
      deps/uv/src/win/poll.c
  20. 12
      deps/uv/src/win/winsock.c
  21. 19
      deps/uv/test/test-dlerror.c
  22. 10
      deps/uv/test/test-list.h
  23. 40
      deps/uv/test/test-loop-configure.c
  24. 114
      deps/uv/test/test-poll-close-doesnt-corrupt-stack.c
  25. 137
      deps/uv/test/test-tcp-oob.c
  26. 4
      deps/uv/uv.gyp

3
deps/uv/AUTHORS

@ -132,3 +132,6 @@ Javier Hernández <jhernandez@emergya.com>
Tonis Tiigi <tonistiigi@gmail.com>
Michael Hudson-Doyle <michael.hudson@linaro.org>
Helge Deller <deller@gmx.de>
Logan Rosen <loganrosen@gmail.com>
Kenneth Perry <thothonegan@gmail.com>
Michael Penick <michael.penick@datastax.com>

70
deps/uv/ChangeLog

@ -1,4 +1,72 @@
2014.12.10, Version 0.10.30 (Stable)
2015.02.27, Version 0.10.36 (Stable)
Changes since version 0.10.35:
* stream: ignore EINVAL for SO_OOBINLINE on OS X (Fedor Indutny)
2015.02.25, Version 0.10.35 (Stable), 4dc978825d870643bbaa4660f71d22975efba29e
Changes since version 0.10.34:
* stream: use SO_OOBINLINE on OS X (Fedor Indutny)
2015.02.21, Version 0.10.34 (Stable), 37aa4aa9b9712c778d7b249563e868cabfdb8332
Changes since version 0.10.33:
* unix: add atomic-ops.h (Ben Noordhuis)
* unix: fix for uv_async data race (Michael Penick)
* unix: call setgoups before calling setuid/setgid (Saúl Ibarra Corretgé)
2015.01.29, Version 0.10.33 (Stable), 7a2253d33ad8215a26c1b34f1952aee7242dd687
Changes since version 0.10.32:
* linux: fix epoll_pwait() regression with < 2.6.19 (Ben Noordhuis)
* test: back-port uv_loop_configure() test (Ben Noordhuis)
2015.01.06, Version 0.10.32 (Stable), 378de30c59aef5fdb6d130fa5cfcb0a68fce571c
Changes since version 0.10.31:
* linux: fix epoll_pwait() sigmask size calculation (Ben Noordhuis)
2014.12.25, Version 0.10.31 (Stable), 4dbd27e2219069a6daa769fb37f98673b77b4261
Changes since version 0.10.30:
* test: test that closing a poll handle doesn't corrupt the stack (Bert Belder)
* win: fix compilation of tests (Marc Schlaich)
* Revert "win: keep a reference to AFD_POLL_INFO in cancel poll" (Bert Belder)
* win: avoid stack corruption when closing a poll handle (Bert Belder)
* gitignore: ignore Visual Studio files (Marc Schlaich)
* win: set fallback message if FormatMessage fails (Marc Schlaich)
* win: fall back to default language in uv_dlerror (Marc Schlaich)
* test: improve compatibility for dlerror test (Marc Schlaich)
* test: check dlerror is "no error" in no error case (Marc Schlaich)
* build: link against -pthread (Logan Rosen)
* win: scandir use 'ls' for formatting long strings (Kenneth Perry)
2014.12.10, Version 0.10.30 (Stable), 5a63f5e9546dca482eeebc3054139b21f509f21f
Changes since version 0.10.29:

2
deps/uv/build.mk

@ -91,6 +91,7 @@ TESTS= \
test/test-ipc-send-recv.o \
test/test-loop-handles.o \
test/test-loop-stop.o \
test/test-loop-configure.o \
test/test-multiple-listen.o \
test/test-mutexes.o \
test/test-osx-select.o \
@ -126,6 +127,7 @@ TESTS= \
test/test-tcp-connect-timeout.o \
test/test-tcp-flags.o \
test/test-tcp-open.o \
test/test-tcp-oob.o \
test/test-tcp-read-stop.o \
test/test-tcp-shutdown-after-write.o \
test/test-tcp-unexpected-read.o \

1
deps/uv/checksparse.sh

@ -145,6 +145,7 @@ test/test-tcp-open.c
test/test-tcp-read-stop.c
test/test-tcp-shutdown-after-write.c
test/test-tcp-unexpected-read.c
test/test-tcp-oob.c
test/test-tcp-write-error.c
test/test-tcp-write-to-half-open-connection.c
test/test-tcp-writealot.c

4
deps/uv/config-unix.mk

@ -22,7 +22,7 @@ E=
CSTDFLAG=--std=c89 -pedantic -Wall -Wextra -Wno-unused-parameter
CFLAGS += -g
CPPFLAGS += -I$(SRCDIR)/src
LDFLAGS=-lm
LDFLAGS=-lm -pthread
CPPFLAGS += -D_LARGEFILE_SOURCE
CPPFLAGS += -D_FILE_OFFSET_BITS=64
@ -186,7 +186,7 @@ src/.buildstamp src/unix/.buildstamp test/.buildstamp:
mkdir -p $(@D)
touch $@
src/unix/%.o src/unix/%.pic.o: src/unix/%.c include/uv.h include/uv-private/uv-unix.h src/unix/internal.h src/unix/.buildstamp $(DTRACE_HEADER)
src/unix/%.o src/unix/%.pic.o: src/unix/%.c include/uv.h include/uv-private/uv-unix.h src/unix/atomic-ops.h src/unix/internal.h src/unix/.buildstamp $(DTRACE_HEADER)
$(CC) $(CSTDFLAG) $(CPPFLAGS) $(CFLAGS) -c $< -o $@
src/%.o src/%.pic.o: src/%.c include/uv.h include/uv-private/uv-unix.h src/.buildstamp

5
deps/uv/include/uv-private/uv-win.h

@ -474,10 +474,7 @@ RB_HEAD(uv_timer_tree_s, uv_timer_s);
/* Used in fast mode */ \
SOCKET peer_socket; \
AFD_POLL_INFO afd_poll_info_1; \
union { \
AFD_POLL_INFO* afd_poll_info_ptr; \
AFD_POLL_INFO afd_poll_info; \
} afd_poll_info_2; \
AFD_POLL_INFO afd_poll_info_2; \
/* Used in fast and slow mode. */ \
uv_req_t poll_req_1; \
uv_req_t poll_req_2; \

43
deps/uv/src/unix/async.c

@ -24,6 +24,7 @@
#include "uv.h"
#include "internal.h"
#include "atomic-ops.h"
#include <errno.h>
#include <assert.h>
@ -34,7 +35,6 @@
static void uv__async_event(uv_loop_t* loop,
struct uv__async* w,
unsigned int nevents);
static int uv__async_make_pending(int* pending);
static int uv__async_eventfd(void);
@ -54,7 +54,11 @@ int uv_async_init(uv_loop_t* loop, uv_async_t* handle, uv_async_cb async_cb) {
int uv_async_send(uv_async_t* handle) {
if (uv__async_make_pending(&handle->pending) == 0)
/* Do a cheap read first. */
if (ACCESS_ONCE(int, handle->pending) != 0)
return 0;
if (cmpxchgi(&handle->pending, 0, 1) == 0)
uv__async_send(&handle->loop->async_watcher);
return 0;
@ -75,41 +79,12 @@ static void uv__async_event(uv_loop_t* loop,
ngx_queue_foreach(q, &loop->async_handles) {
h = ngx_queue_data(q, uv_async_t, queue);
if (!h->pending) continue;
h->pending = 0;
h->async_cb(h, 0);
}
}
if (cmpxchgi(&h->pending, 1, 0) == 0)
continue;
static int uv__async_make_pending(int* pending) {
/* Do a cheap read first. */
if (ACCESS_ONCE(int, *pending) != 0)
return 1;
/* Micro-optimization: use atomic memory operations to detect if we've been
* preempted by another thread and don't have to make an expensive syscall.
* This speeds up the heavily contended case by about 1-2% and has little
* if any impact on the non-contended case.
*
* Use XCHG instead of the CMPXCHG that __sync_val_compare_and_swap() emits
* on x86, it's about 4x faster. It probably makes zero difference in the
* grand scheme of things but I'm OCD enough not to let this one pass.
*/
#if defined(__i386__) || defined(__x86_64__)
{
unsigned int val = 1;
__asm__ __volatile__ ("xchgl %0, %1"
: "+r" (val)
: "m" (*pending));
return val != 0;
h->async_cb(h, 0);
}
#elif defined(__GNUC__) && (__GNUC__ > 4 || __GNUC__ == 4 && __GNUC_MINOR__ > 0)
return __sync_val_compare_and_swap(pending, 0, 1) != 0;
#else
ACCESS_ONCE(int, *pending) = 1;
return 0;
#endif
}

60
deps/uv/src/unix/atomic-ops.h

@ -0,0 +1,60 @@
/* Copyright (c) 2013, Ben Noordhuis <info@bnoordhuis.nl>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef UV_ATOMIC_OPS_H_
#define UV_ATOMIC_OPS_H_
#include "internal.h" /* UV_UNUSED */
UV_UNUSED(static int cmpxchgi(int* ptr, int oldval, int newval));
UV_UNUSED(static long cmpxchgl(long* ptr, long oldval, long newval));
UV_UNUSED(static void cpu_relax(void));
/* Prefer hand-rolled assembly over the gcc builtins because the latter also
* issue full memory barriers.
*/
UV_UNUSED(static int cmpxchgi(int* ptr, int oldval, int newval)) {
#if defined(__i386__) || defined(__x86_64__)
int out;
__asm__ __volatile__ ("lock; cmpxchg %2, %1;"
: "=a" (out), "+m" (*(volatile int*) ptr)
: "r" (newval), "0" (oldval)
: "memory");
return out;
#else
return __sync_val_compare_and_swap(ptr, oldval, newval);
#endif
}
UV_UNUSED(static long cmpxchgl(long* ptr, long oldval, long newval)) {
#if defined(__i386__) || defined(__x86_64__)
long out;
__asm__ __volatile__ ("lock; cmpxchg %2, %1;"
: "=a" (out), "+m" (*(volatile long*) ptr)
: "r" (newval), "0" (oldval)
: "memory");
return out;
#else
return __sync_val_compare_and_swap(ptr, oldval, newval);
#endif
}
UV_UNUSED(static void cpu_relax(void)) {
#if defined(__i386__) || defined(__x86_64__)
__asm__ __volatile__ ("rep; nop"); /* a.k.a. PAUSE */
#endif
}
#endif /* UV_ATOMIC_OPS_H_ */

15
deps/uv/src/unix/internal.h

@ -66,6 +66,21 @@
} \
while (0)
/* The __clang__ and __INTEL_COMPILER checks are superfluous because they
* define __GNUC__. They are here to convey to you, dear reader, that these
* macros are enabled when compiling with clang or icc.
*/
#if defined(__clang__) || \
defined(__GNUC__) || \
defined(__INTEL_COMPILER) || \
defined(__SUNPRO_C)
# define UV_DESTRUCTOR(declaration) __attribute__((destructor)) declaration
# define UV_UNUSED(declaration) __attribute__((unused)) declaration
#else
# define UV_DESTRUCTOR(declaration) declaration
# define UV_UNUSED(declaration) declaration
#endif
#if defined(__linux__)
# define UV__POLLIN UV__EPOLLIN
# define UV__POLLOUT UV__EPOLLOUT

40
deps/uv/src/unix/linux-core.c

@ -33,7 +33,6 @@
#include <sys/prctl.h>
#include <sys/sysinfo.h>
#include <unistd.h>
#include <signal.h>
#include <fcntl.h>
#include <time.h>
@ -126,13 +125,15 @@ void uv__platform_invalidate_fd(uv_loop_t* loop, int fd) {
void uv__io_poll(uv_loop_t* loop, int timeout) {
static int no_epoll_pwait;
static int no_epoll_wait;
struct uv__epoll_event events[1024];
struct uv__epoll_event* pe;
struct uv__epoll_event e;
ngx_queue_t* q;
uv__io_t* w;
sigset_t* pset;
sigset_t set;
sigset_t sigset;
uint64_t sigmask;
uint64_t base;
uint64_t diff;
int nevents;
@ -141,7 +142,6 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
int fd;
int op;
int i;
static int no_epoll_wait;
if (loop->nfds == 0) {
assert(ngx_queue_empty(&loop->watcher_queue));
@ -183,11 +183,11 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
w->events = w->pevents;
}
pset = NULL;
sigmask = 0;
if (loop->flags & UV_LOOP_BLOCK_SIGPROF) {
pset = &set;
sigemptyset(pset);
sigaddset(pset, SIGPROF);
sigemptyset(&sigset);
sigaddset(&sigset, SIGPROF);
sigmask |= 1 << (SIGPROF - 1);
}
assert(timeout >= -1);
@ -195,23 +195,31 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
count = 48; /* Benchmarks suggest this gives the best throughput. */
for (;;) {
if (no_epoll_wait || pset != NULL) {
if (sigmask != 0 && no_epoll_pwait != 0)
if (pthread_sigmask(SIG_BLOCK, &sigset, NULL))
abort();
if (sigmask != 0 && no_epoll_pwait == 0) {
nfds = uv__epoll_pwait(loop->backend_fd,
events,
ARRAY_SIZE(events),
timeout,
pset);
sigmask);
if (nfds == -1 && errno == ENOSYS)
no_epoll_pwait = 1;
} else {
nfds = uv__epoll_wait(loop->backend_fd,
events,
ARRAY_SIZE(events),
timeout);
if (nfds == -1 && errno == ENOSYS) {
if (nfds == -1 && errno == ENOSYS)
no_epoll_wait = 1;
continue;
}
}
if (sigmask != 0 && no_epoll_pwait != 0)
if (pthread_sigmask(SIG_UNBLOCK, &sigset, NULL))
abort();
/* Update loop->time unconditionally. It's tempting to skip the update when
* timeout == 0 (i.e. non-blocking poll) but there is no guarantee that the
* operating system didn't reschedule our process while in the syscall.
@ -224,6 +232,12 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
}
if (nfds == -1) {
if (errno == ENOSYS) {
/* epoll_wait() or epoll_pwait() failed, try the other system call. */
assert(no_epoll_wait == 0 || no_epoll_pwait == 0);
continue;
}
if (errno != EINTR)
abort();

6
deps/uv/src/unix/linux-syscalls.c

@ -291,15 +291,15 @@ int uv__epoll_pwait(int epfd,
struct uv__epoll_event* events,
int nevents,
int timeout,
const sigset_t* sigmask) {
uint64_t sigmask) {
#if defined(__NR_epoll_pwait)
return syscall(__NR_epoll_pwait,
epfd,
events,
nevents,
timeout,
sigmask,
_NSIG / 8);
&sigmask,
sizeof(sigmask));
#else
return errno = ENOSYS, -1;
#endif

2
deps/uv/src/unix/linux-syscalls.h

@ -130,7 +130,7 @@ int uv__epoll_pwait(int epfd,
struct uv__epoll_event* events,
int nevents,
int timeout,
const sigset_t* sigmask);
uint64_t sigmask);
int uv__eventfd2(unsigned int count, int flags);
int uv__inotify_init(void);
int uv__inotify_init1(int flags);

15
deps/uv/src/unix/process.c

@ -40,6 +40,10 @@
extern char **environ;
#endif
#ifdef __linux__
# include <grp.h>
#endif
static ngx_queue_t* uv__process_queue(uv_loop_t* loop, int pid) {
assert(pid > 0);
@ -331,6 +335,17 @@ static void uv__process_child_init(uv_process_options_t options,
_exit(127);
}
if (options.flags & (UV_PROCESS_SETUID | UV_PROCESS_SETGID)) {
/* When dropping privileges from root, the `setgroups` call will
* remove any extraneous groups. If we don't call this, then
* even though our uid has dropped, we may still have groups
* that enable us to do super-user things. This will fail if we
* aren't root, so don't bother checking the return value, this
* is just done as an optimistic privilege dropping function.
*/
SAVE_ERRNO(setgroups(0, NULL));
}
if ((options.flags & UV_PROCESS_SETGID) && setgid(options.gid)) {
uv__write_int(error_fd, errno);
_exit(127);

13
deps/uv/src/unix/stream.c

@ -403,6 +403,10 @@ failed_malloc:
int uv__stream_open(uv_stream_t* stream, int fd, int flags) {
#if defined(__APPLE__)
int enable;
#endif
assert(fd >= 0);
stream->flags |= flags;
@ -415,6 +419,15 @@ int uv__stream_open(uv_stream_t* stream, int fd, int flags) {
return uv__set_sys_error(stream->loop, errno);
}
#if defined(__APPLE__)
enable = 1;
if (setsockopt(fd, SOL_SOCKET, SO_OOBINLINE, &enable, sizeof(enable)) &&
errno != ENOTSOCK &&
errno != EINVAL) {
return uv__set_sys_error(stream->loop, errno);
}
#endif
stream->io_watcher.fd = fd;
return 0;

2
deps/uv/src/version.c

@ -34,7 +34,7 @@
#define UV_VERSION_MAJOR 0
#define UV_VERSION_MINOR 10
#define UV_VERSION_PATCH 30
#define UV_VERSION_PATCH 36
#define UV_VERSION_IS_RELEASE 1

35
deps/uv/src/win/dl.c

@ -69,17 +69,44 @@ const char* uv_dlerror(uv_lib_t* lib) {
}
static void uv__format_fallback_error(uv_lib_t* lib, int errorno){
DWORD_PTR args[1] = { (DWORD_PTR) errorno };
LPSTR fallback_error = "error: %1!d!";
FormatMessageA(FORMAT_MESSAGE_FROM_STRING |
FORMAT_MESSAGE_ARGUMENT_ARRAY |
FORMAT_MESSAGE_ALLOCATE_BUFFER,
fallback_error, 0, 0,
(LPSTR) &lib->errmsg,
0, (va_list*) args);
}
static int uv__dlerror(uv_lib_t* lib, int errorno) {
DWORD res;
if (lib->errmsg) {
LocalFree((void*)lib->errmsg);
lib->errmsg = NULL;
}
if (errorno) {
FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS, NULL, errorno,
MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US),
(LPSTR)&lib->errmsg, 0, NULL);
res = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS, NULL, errorno,
MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US),
(LPSTR) &lib->errmsg, 0, NULL);
if (!res && GetLastError() == ERROR_MUI_FILE_NOT_FOUND) {
res = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS, NULL, errorno,
0, (LPSTR) &lib->errmsg, 0, NULL);
}
if (!res) {
uv__format_fallback_error(lib, errorno);
}
}
return errorno ? -1 : 0;

4
deps/uv/src/win/fs.c

@ -732,9 +732,9 @@ void fs__readdir(uv_fs_t* req) {
if (len == 0) {
fmt = L"./*";
} else if (pathw[len - 1] == L'/' || pathw[len - 1] == L'\\') {
fmt = L"%s*";
fmt = L"%ls*";
} else {
fmt = L"%s\\*";
fmt = L"%ls\\*";
}
/* Figure out whether path is a file or a directory. */

4
deps/uv/src/win/internal.h

@ -332,8 +332,8 @@ int WSAAPI uv_wsarecvfrom_workaround(SOCKET socket, WSABUF* buffers,
int* addr_len, WSAOVERLAPPED *overlapped,
LPWSAOVERLAPPED_COMPLETION_ROUTINE completion_routine);
int WSAAPI uv_msafd_poll(SOCKET socket, AFD_POLL_INFO* info,
OVERLAPPED* overlapped);
int WSAAPI uv_msafd_poll(SOCKET socket, AFD_POLL_INFO* info_in,
AFD_POLL_INFO* info_out, OVERLAPPED* overlapped);
/* Whether there are any non-IFS LSPs stacked on TCP */
extern int uv_tcp_non_ifs_lsp_ipv4;

40
deps/uv/src/win/poll.c

@ -46,6 +46,8 @@ typedef struct uv_single_fd_set_s {
static OVERLAPPED overlapped_dummy_;
static uv_once_t overlapped_dummy_init_guard_ = UV_ONCE_INIT;
static AFD_POLL_INFO afd_poll_info_dummy_;
static void uv__init_overlapped_dummy(void) {
HANDLE event;
@ -65,6 +67,11 @@ static OVERLAPPED* uv__get_overlapped_dummy() {
}
static AFD_POLL_INFO* uv__get_afd_poll_info_dummy() {
return &afd_poll_info_dummy_;
}
static void uv__fast_poll_submit_poll_req(uv_loop_t* loop, uv_poll_t* handle) {
uv_req_t* req;
AFD_POLL_INFO* afd_poll_info;
@ -79,7 +86,7 @@ static void uv__fast_poll_submit_poll_req(uv_loop_t* loop, uv_poll_t* handle) {
handle->mask_events_2 = handle->events;
} else if (handle->submitted_events_2 == 0) {
req = &handle->poll_req_2;
afd_poll_info = &handle->afd_poll_info_2.afd_poll_info_ptr[0];
afd_poll_info = &handle->afd_poll_info_2;
handle->submitted_events_2 = handle->events;
handle->mask_events_1 = handle->events;
handle->mask_events_2 = 0;
@ -107,6 +114,7 @@ static void uv__fast_poll_submit_poll_req(uv_loop_t* loop, uv_poll_t* handle) {
memset(&req->overlapped, 0, sizeof req->overlapped);
result = uv_msafd_poll((SOCKET) handle->peer_socket,
afd_poll_info,
afd_poll_info,
&req->overlapped);
if (result != 0 && WSAGetLastError() != WSA_IO_PENDING) {
@ -118,19 +126,19 @@ static void uv__fast_poll_submit_poll_req(uv_loop_t* loop, uv_poll_t* handle) {
static int uv__fast_poll_cancel_poll_req(uv_loop_t* loop, uv_poll_t* handle) {
AFD_POLL_INFO* afd_poll_info;
AFD_POLL_INFO afd_poll_info;
DWORD result;
afd_poll_info = &handle->afd_poll_info_2.afd_poll_info_ptr[1];
afd_poll_info->Exclusive = TRUE;
afd_poll_info->NumberOfHandles = 1;
afd_poll_info->Timeout.QuadPart = INT64_MAX;
afd_poll_info->Handles[0].Handle = (HANDLE) handle->socket;
afd_poll_info->Handles[0].Status = 0;
afd_poll_info->Handles[0].Events = AFD_POLL_ALL;
afd_poll_info.Exclusive = TRUE;
afd_poll_info.NumberOfHandles = 1;
afd_poll_info.Timeout.QuadPart = INT64_MAX;
afd_poll_info.Handles[0].Handle = (HANDLE) handle->socket;
afd_poll_info.Handles[0].Status = 0;
afd_poll_info.Handles[0].Events = AFD_POLL_ALL;
result = uv_msafd_poll(handle->socket,
afd_poll_info,
&afd_poll_info,
uv__get_afd_poll_info_dummy(),
uv__get_overlapped_dummy());
if (result == SOCKET_ERROR) {
@ -155,7 +163,7 @@ static void uv__fast_poll_process_poll_req(uv_loop_t* loop, uv_poll_t* handle,
handle->submitted_events_1 = 0;
mask_events = handle->mask_events_1;
} else if (req == &handle->poll_req_2) {
afd_poll_info = &handle->afd_poll_info_2.afd_poll_info_ptr[0];
afd_poll_info = &handle->afd_poll_info_2;
handle->submitted_events_2 = 0;
mask_events = handle->mask_events_2;
} else {
@ -552,12 +560,6 @@ int uv_poll_init_socket(uv_loop_t* loop, uv_poll_t* handle,
handle->poll_req_2.type = UV_POLL_REQ;
handle->poll_req_2.data = handle;
handle->afd_poll_info_2.afd_poll_info_ptr = malloc(sizeof(*handle->afd_poll_info_2.afd_poll_info_ptr) * 2);
if (handle->afd_poll_info_2.afd_poll_info_ptr == NULL) {
uv__set_artificial_error(loop, UV_ENOMEM);
return -1;
}
return 0;
}
@ -611,9 +613,5 @@ void uv_poll_endgame(uv_loop_t* loop, uv_poll_t* handle) {
assert(handle->submitted_events_1 == 0);
assert(handle->submitted_events_2 == 0);
if (handle->afd_poll_info_2.afd_poll_info_ptr) {
free(handle->afd_poll_info_2.afd_poll_info_ptr);
handle->afd_poll_info_2.afd_poll_info_ptr = NULL;
}
uv__handle_close(handle);
}

12
deps/uv/src/win/winsock.c

@ -467,8 +467,8 @@ int WSAAPI uv_wsarecvfrom_workaround(SOCKET socket, WSABUF* buffers,
}
int WSAAPI uv_msafd_poll(SOCKET socket, AFD_POLL_INFO* info,
OVERLAPPED* overlapped) {
int WSAAPI uv_msafd_poll(SOCKET socket, AFD_POLL_INFO* info_in,
AFD_POLL_INFO* info_out, OVERLAPPED* overlapped) {
IO_STATUS_BLOCK iosb;
IO_STATUS_BLOCK* iosb_ptr;
HANDLE event = NULL;
@ -506,10 +506,10 @@ int WSAAPI uv_msafd_poll(SOCKET socket, AFD_POLL_INFO* info,
apc_context,
iosb_ptr,
IOCTL_AFD_POLL,
info,
sizeof *info,
info,
sizeof *info);
info_in,
sizeof *info_in,
info_out,
sizeof *info_out);
if (overlapped == NULL) {
/* If this is a blocking operation, wait for the event to become */

19
deps/uv/test/test-dlerror.c

@ -26,31 +26,28 @@
TEST_IMPL(dlerror) {
const char* path = "test/fixtures/load_error.node";
const char* dlerror_no_error = "no error";
const char* msg;
uv_lib_t lib;
int r;
#ifdef __linux__
const char* dlerror_desc = "file too short";
#elif defined (__sun__)
const char* dlerror_desc = "unknown file type";
#elif defined (_WIN32)
const char* dlerror_desc = "%1 is not a valid Win32 application";
#else
const char* dlerror_desc = "";
#endif
lib.errmsg = NULL;
lib.handle = NULL;
msg = uv_dlerror(&lib);
ASSERT(msg != NULL);
ASSERT(strstr(msg, dlerror_no_error) != NULL);
r = uv_dlopen(path, &lib);
ASSERT(r == -1);
msg = uv_dlerror(&lib);
ASSERT(msg != NULL);
ASSERT(strstr(msg, dlerror_desc) != NULL);
ASSERT(strstr(msg, dlerror_no_error) == NULL);
/* Should return the same error twice in a row. */
msg = uv_dlerror(&lib);
ASSERT(msg != NULL);
ASSERT(strstr(msg, dlerror_desc) != NULL);
ASSERT(strstr(msg, dlerror_no_error) == NULL);
uv_dlclose(&lib);

10
deps/uv/test/test-list.h

@ -24,6 +24,7 @@ TEST_DECLARE (callback_order)
TEST_DECLARE (run_once)
TEST_DECLARE (run_nowait)
TEST_DECLARE (loop_stop)
TEST_DECLARE (loop_configure)
TEST_DECLARE (barrier_1)
TEST_DECLARE (barrier_2)
TEST_DECLARE (barrier_3)
@ -64,7 +65,10 @@ TEST_DECLARE (tcp_connect_error_fault)
TEST_DECLARE (tcp_connect_timeout)
TEST_DECLARE (tcp_close_while_connecting)
TEST_DECLARE (tcp_close)
#ifndef _WIN32
TEST_DECLARE (tcp_close_accept)
TEST_DECLARE (tcp_oob)
#endif
TEST_DECLARE (tcp_flags)
TEST_DECLARE (tcp_write_to_half_open_connection)
TEST_DECLARE (tcp_unexpected_read)
@ -215,6 +219,7 @@ TEST_DECLARE (poll_duplex)
TEST_DECLARE (poll_unidirectional)
TEST_DECLARE (poll_close)
#ifdef _WIN32
TEST_DECLARE (poll_close_doesnt_corrupt_stack)
TEST_DECLARE (poll_closesocket)
TEST_DECLARE (spawn_detect_pipe_name_collisions_on_windows)
TEST_DECLARE (argument_escaping)
@ -249,6 +254,7 @@ TASK_LIST_START
TEST_ENTRY (run_once)
TEST_ENTRY (run_nowait)
TEST_ENTRY (loop_stop)
TEST_ENTRY (loop_configure)
TEST_ENTRY (barrier_1)
TEST_ENTRY (barrier_2)
TEST_ENTRY (barrier_3)
@ -308,7 +314,10 @@ TASK_LIST_START
TEST_ENTRY (tcp_connect_timeout)
TEST_ENTRY (tcp_close_while_connecting)
TEST_ENTRY (tcp_close)
#ifndef _WIN32
TEST_ENTRY (tcp_close_accept)
TEST_ENTRY (tcp_oob)
#endif
TEST_ENTRY (tcp_flags)
TEST_ENTRY (tcp_write_to_half_open_connection)
TEST_ENTRY (tcp_unexpected_read)
@ -451,6 +460,7 @@ TASK_LIST_START
TEST_ENTRY (kill)
#ifdef _WIN32
TEST_ENTRY (poll_close_doesnt_corrupt_stack)
TEST_ENTRY (poll_closesocket)
TEST_ENTRY (spawn_detect_pipe_name_collisions_on_windows)
TEST_ENTRY (argument_escaping)

40
deps/uv/test/test-loop-configure.c

@ -0,0 +1,40 @@
/* Copyright (c) 2014, Ben Noordhuis <info@bnoordhuis.nl>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "uv.h"
#include "task.h"
static void timer_cb(uv_timer_t* handle, int status) {
uv_close((uv_handle_t*) handle, NULL);
}
TEST_IMPL(loop_configure) {
uv_timer_t timer_handle;
uv_loop_t* loop;
loop = uv_default_loop();
#ifdef _WIN32
ASSERT(UV_ENOSYS == uv_loop_configure(loop, UV_LOOP_BLOCK_SIGNAL, 0));
#else
ASSERT(0 == uv_loop_configure(loop, UV_LOOP_BLOCK_SIGNAL, SIGPROF));
#endif
ASSERT(0 == uv_timer_init(loop, &timer_handle));
ASSERT(0 == uv_timer_start(&timer_handle, timer_cb, 10, 0));
ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT));
MAKE_VALGRIND_HAPPY();
return 0;
}

114
deps/uv/test/test-poll-close-doesnt-corrupt-stack.c

@ -0,0 +1,114 @@
/* Copyright Bert Belder, and other libuv contributors. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
#ifdef _WIN32
#include <errno.h>
#include <stdio.h>
#include "uv.h"
#include "task.h"
#ifdef _MSC_VER /* msvc */
# define NO_INLINE __declspec(noinline)
#else /* gcc */
# define NO_INLINE __attribute__ ((noinline))
#endif
uv_os_sock_t sock;
uv_poll_t handle;
static int close_cb_called = 0;
static void close_cb(uv_handle_t* h) {
close_cb_called++;
}
static void poll_cb(uv_poll_t* h, int status, int events) {
ASSERT(0 && "should never get here");
}
static void NO_INLINE close_socket_and_verify_stack() {
const uint32_t MARKER = 0xDEADBEEF;
const int VERIFY_AFTER = 10; /* ms */
int r;
volatile uint32_t data[65536];
size_t i;
for (i = 0; i < ARRAY_SIZE(data); i++)
data[i] = MARKER;
r = closesocket(sock);
ASSERT(r == 0);
uv_sleep(VERIFY_AFTER);
for (i = 0; i < ARRAY_SIZE(data); i++)
ASSERT(data[i] == MARKER);
}
TEST_IMPL(poll_close_doesnt_corrupt_stack) {
struct WSAData wsa_data;
int r;
unsigned long on;
struct sockaddr_in addr;
r = WSAStartup(MAKEWORD(2, 2), &wsa_data);
ASSERT(r == 0);
sock = socket(AF_INET, SOCK_STREAM, 0);
ASSERT(sock != INVALID_SOCKET);
on = 1;
r = ioctlsocket(sock, FIONBIO, &on);
ASSERT(r == 0);
addr = uv_ip4_addr("127.0.0.1", TEST_PORT);
ASSERT(r == 0);
r = connect(sock, (const struct sockaddr*) &addr, sizeof addr);
ASSERT(r != 0);
ASSERT(WSAGetLastError() == WSAEWOULDBLOCK);
r = uv_poll_init_socket(uv_default_loop(), &handle, sock);
ASSERT(r == 0);
r = uv_poll_start(&handle, UV_READABLE | UV_WRITABLE, poll_cb);
ASSERT(r == 0);
uv_close((uv_handle_t*) &handle, close_cb);
close_socket_and_verify_stack();
r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
ASSERT(r == 0);
ASSERT(close_cb_called == 1);
MAKE_VALGRIND_HAPPY();
return 0;
}
#endif /* _WIN32 */

137
deps/uv/test/test-tcp-oob.c

@ -0,0 +1,137 @@
/* Copyright Fedor Indutny. 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 <sys/socket.h>
#include <unistd.h>
static uv_tcp_t server_handle;
static uv_tcp_t client_handle;
static uv_tcp_t peer_handle;
static uv_idle_t idle;
static uv_connect_t connect_req;
static int ticks;
static const int kMaxTicks = 10;
static void set_nonblocking(int fd, int set) {
int r;
int flags = fcntl(fd, F_GETFL, 0);
ASSERT(flags >= 0);
if (set)
flags |= O_NONBLOCK;
else
flags &= ~O_NONBLOCK;
r = fcntl(fd, F_SETFL, flags);
ASSERT(r >= 0);
}
static uv_buf_t alloc_cb(uv_handle_t* handle, size_t size) {
static char storage[1024];
return uv_buf_init(storage, sizeof(storage));
}
static void idle_cb(uv_idle_t* idle, int status) {
ASSERT(status == 0);
if (++ticks < kMaxTicks)
return;
uv_close((uv_handle_t*) &server_handle, NULL);
uv_close((uv_handle_t*) &client_handle, NULL);
uv_close((uv_handle_t*) &peer_handle, NULL);
uv_close((uv_handle_t*) idle, NULL);
}
static void read_cb(uv_stream_t* tcp, ssize_t nread, uv_buf_t buf) {
ASSERT(nread > 0);
ASSERT(0 == uv_idle_start(&idle, idle_cb));
}
static void connect_cb(uv_connect_t* req, int status) {
ASSERT(req->handle == (uv_stream_t*) &client_handle);
ASSERT(0 == status);
}
static void connection_cb(uv_stream_t* handle, int status) {
int r;
int fd;
ASSERT(0 == status);
ASSERT(0 == uv_accept(handle, (uv_stream_t*) &peer_handle));
ASSERT(0 == uv_read_start((uv_stream_t*) &peer_handle, alloc_cb, read_cb));
/* Send some OOB data */
fd = client_handle.io_watcher.fd;
set_nonblocking(fd, 0);
/* The problem triggers only on a second message, it seem that xnu is not
* triggering `kevent()` for the first one
*/
do {
r = send(fd, "hello", 5, MSG_OOB);
} while (r < 0 && errno == EINTR);
ASSERT(5 == r);
do {
r = send(fd, "hello", 5, MSG_OOB);
} while (r < 0 && errno == EINTR);
ASSERT(5 == r);
set_nonblocking(fd, 1);
}
TEST_IMPL(tcp_oob) {
uv_loop_t* loop;
loop = uv_default_loop();
ASSERT(0 == uv_tcp_init(loop, &server_handle));
ASSERT(0 == uv_tcp_init(loop, &client_handle));
ASSERT(0 == uv_tcp_init(loop, &peer_handle));
ASSERT(0 == uv_idle_init(loop, &idle));
ASSERT(0 == uv_tcp_bind(&server_handle, uv_ip4_addr("127.0.0.1", TEST_PORT)));
ASSERT(0 == uv_listen((uv_stream_t*) &server_handle, 1, connection_cb));
/* Ensure two separate packets */
ASSERT(0 == uv_tcp_nodelay(&client_handle, 1));
ASSERT(0 == uv_tcp_connect(&connect_req,
&client_handle,
uv_ip4_addr("127.0.0.1", TEST_PORT),
connect_cb));
ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT));
ASSERT(ticks == kMaxTicks);
MAKE_VALGRIND_HAPPY();
return 0;
}
#endif

4
deps/uv/uv.gyp

@ -133,6 +133,7 @@
'include/uv-private/uv-darwin.h',
'include/uv-private/uv-bsd.h',
'src/unix/async.c',
'src/unix/atomic-ops.h',
'src/unix/core.c',
'src/unix/dl.c',
'src/unix/error.c',
@ -311,6 +312,7 @@
'test/test-list.h',
'test/test-loop-handles.c',
'test/test-loop-stop.c',
'test/test-loop-configure.c',
'test/test-walk-handles.c',
'test/test-watcher-cross-stop.c',
'test/test-multiple-listen.c',
@ -323,6 +325,7 @@
'test/test-platform-output.c',
'test/test-poll.c',
'test/test-poll-close.c',
'test/test-poll-close-doesnt-corrupt-stack.c',
'test/test-poll-closesocket.c',
'test/test-process-title.c',
'test/test-ref.c',
@ -352,6 +355,7 @@
'test/test-tcp-write-to-half-open-connection.c',
'test/test-tcp-writealot.c',
'test/test-tcp-unexpected-read.c',
'test/test-tcp-oob.c',
'test/test-tcp-read-stop.c',
'test/test-threadpool.c',
'test/test-threadpool-cancel.c',

Loading…
Cancel
Save