mirror of
https://github.com/nodejs/node-v0.x-archive.git
synced 2026-01-10 07:28:10 -05:00
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>
This commit is contained in:
committed by
Julien Gilli
parent
8bcd0a4c4a
commit
dcff5d565c
3
deps/uv/AUTHORS
vendored
3
deps/uv/AUTHORS
vendored
@@ -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
vendored
70
deps/uv/ChangeLog
vendored
@@ -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
vendored
2
deps/uv/build.mk
vendored
@@ -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
vendored
1
deps/uv/checksparse.sh
vendored
@@ -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
vendored
4
deps/uv/config-unix.mk
vendored
@@ -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
vendored
5
deps/uv/include/uv-private/uv-win.h
vendored
@@ -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; \
|
||||
|
||||
45
deps/uv/src/unix/async.c
vendored
45
deps/uv/src/unix/async.c
vendored
@@ -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,44 +79,15 @@ 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;
|
||||
|
||||
if (cmpxchgi(&h->pending, 1, 0) == 0)
|
||||
continue;
|
||||
|
||||
h->async_cb(h, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
#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
|
||||
}
|
||||
|
||||
|
||||
static void uv__async_io(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
|
||||
struct uv__async* wa;
|
||||
char buf[1024];
|
||||
|
||||
60
deps/uv/src/unix/atomic-ops.h
vendored
Normal file
60
deps/uv/src/unix/atomic-ops.h
vendored
Normal file
@@ -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
vendored
15
deps/uv/src/unix/internal.h
vendored
@@ -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
vendored
40
deps/uv/src/unix/linux-core.c
vendored
@@ -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
vendored
6
deps/uv/src/unix/linux-syscalls.c
vendored
@@ -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
vendored
2
deps/uv/src/unix/linux-syscalls.h
vendored
@@ -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
vendored
15
deps/uv/src/unix/process.c
vendored
@@ -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
vendored
13
deps/uv/src/unix/stream.c
vendored
@@ -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
vendored
2
deps/uv/src/version.c
vendored
@@ -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
vendored
35
deps/uv/src/win/dl.c
vendored
@@ -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
vendored
4
deps/uv/src/win/fs.c
vendored
@@ -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
vendored
4
deps/uv/src/win/internal.h
vendored
@@ -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
vendored
40
deps/uv/src/win/poll.c
vendored
@@ -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
vendored
12
deps/uv/src/win/winsock.c
vendored
@@ -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
vendored
19
deps/uv/test/test-dlerror.c
vendored
@@ -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
vendored
10
deps/uv/test/test-list.h
vendored
@@ -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
vendored
Normal file
40
deps/uv/test/test-loop-configure.c
vendored
Normal file
@@ -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
vendored
Normal file
114
deps/uv/test/test-poll-close-doesnt-corrupt-stack.c
vendored
Normal file
@@ -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
vendored
Normal file
137
deps/uv/test/test-tcp-oob.c
vendored
Normal file
@@ -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
vendored
4
deps/uv/uv.gyp
vendored
@@ -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',
|
||||
|
||||
Reference in New Issue
Block a user