Browse Source

uv: upgrade 8c78cb4

v0.9.1-release
Ben Noordhuis 13 years ago
parent
commit
9d72a742e3
  1. 2
      deps/uv/config-mingw.mk
  2. 2
      deps/uv/include/uv.h
  3. 1
      deps/uv/src/unix/cygwin.c
  4. 38
      deps/uv/src/unix/stream.c
  5. 1
      deps/uv/src/win/core.c
  6. 2
      deps/uv/src/win/error.c
  7. 3
      deps/uv/src/win/fs.c
  8. 15
      deps/uv/src/win/handle.c
  9. 187
      deps/uv/src/win/pipe.c
  10. 2
      deps/uv/src/win/process.c
  11. 5
      deps/uv/src/win/stream.c
  12. 27
      deps/uv/src/win/tcp.c
  13. 21
      deps/uv/src/win/tty.c
  14. 3
      deps/uv/src/win/udp.c
  15. 11
      deps/uv/src/win/util.c
  16. 13
      deps/uv/src/win/winapi.h
  17. 4
      deps/uv/test/benchmark-pound.c
  18. 2
      deps/uv/test/benchmark-thread.c
  19. 15
      deps/uv/test/run-tests.c
  20. 2
      deps/uv/test/runner-win.c
  21. 5
      deps/uv/test/runner.c
  22. 30
      deps/uv/test/test-counters-init.c
  23. 21
      deps/uv/test/test-cwd-and-chdir.c
  24. 66
      deps/uv/test/test-fs.c
  25. 208
      deps/uv/test/test-ipc-send-recv.c
  26. 35
      deps/uv/test/test-ipc.c
  27. 25
      deps/uv/test/test-list.h
  28. 76
      deps/uv/test/test-ref.c
  29. 101
      deps/uv/test/test-shutdown-close.c
  30. 64
      deps/uv/test/test-tty.c
  31. 2
      deps/uv/uv.gyp

2
deps/uv/config-mingw.mk

@ -34,7 +34,7 @@ WIN_OBJS=$(WIN_SRCS:.c=.o)
RUNNER_CFLAGS=$(CFLAGS) -D_GNU_SOURCE # Need _GNU_SOURCE for strdup? RUNNER_CFLAGS=$(CFLAGS) -D_GNU_SOURCE # Need _GNU_SOURCE for strdup?
RUNNER_LINKFLAGS=$(LINKFLAGS) RUNNER_LINKFLAGS=$(LINKFLAGS)
RUNNER_LIBS=-lws2_32 RUNNER_LIBS=-lws2_32 -lpsapi -liphlpapi
RUNNER_SRC=test/runner-win.c RUNNER_SRC=test/runner-win.c
uv.a: $(WIN_OBJS) src/uv-common.o $(CARES_OBJS) uv.a: $(WIN_OBJS) src/uv-common.o $(CARES_OBJS)

2
deps/uv/include/uv.h

@ -1388,7 +1388,7 @@ UV_EXTERN extern uint64_t uv_hrtime(void);
/* /*
* Opens a shared library. The filename is in utf-8. On success, -1 is * Opens a shared library. The filename is in utf-8. On success, -1 is returned
* and the variable pointed by library receives a handle to the library. * and the variable pointed by library receives a handle to the library.
*/ */
UV_EXTERN uv_err_t uv_dlopen(const char* filename, uv_lib_t* library); UV_EXTERN uv_err_t uv_dlopen(const char* filename, uv_lib_t* library);

1
deps/uv/src/unix/cygwin.c

@ -19,6 +19,7 @@
*/ */
#include "uv.h" #include "uv.h"
#include "../uv-common.h"
#include <assert.h> #include <assert.h>
#include <stdint.h> #include <stdint.h>

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

@ -22,14 +22,17 @@
#include "uv.h" #include "uv.h"
#include "internal.h" #include "internal.h"
#include <assert.h> #include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <sys/uio.h> #include <assert.h>
#include <errno.h>
#include <stdio.h> #include <sys/types.h>
#include <sys/socket.h>
#include <sys/uio.h>
#include <sys/un.h>
#include <unistd.h>
static void uv__stream_connect(uv_stream_t*); static void uv__stream_connect(uv_stream_t*);
@ -513,6 +516,28 @@ static void uv__write_callbacks(uv_stream_t* stream) {
} }
static uv_handle_type uv__handle_type(int fd) {
struct sockaddr_storage ss;
socklen_t len;
memset(&ss, 0, sizeof(ss));
len = sizeof(ss);
if (getsockname(fd, (struct sockaddr*)&ss, &len))
return UV_UNKNOWN_HANDLE;
switch (ss.ss_family) {
case AF_UNIX:
return UV_NAMED_PIPE;
case AF_INET:
case AF_INET6:
return UV_TCP;
}
return UV_UNKNOWN_HANDLE;
}
static void uv__read(uv_stream_t* stream) { static void uv__read(uv_stream_t* stream) {
uv_buf_t buf; uv_buf_t buf;
ssize_t nread; ssize_t nread;
@ -633,7 +658,8 @@ static void uv__read(uv_stream_t* stream) {
if (stream->accepted_fd >= 0) { if (stream->accepted_fd >= 0) {
stream->read2_cb((uv_pipe_t*)stream, nread, buf, UV_TCP); stream->read2_cb((uv_pipe_t*)stream, nread, buf,
uv__handle_type(stream->accepted_fd));
} else { } else {
stream->read2_cb((uv_pipe_t*)stream, nread, buf, UV_UNKNOWN_HANDLE); stream->read2_cb((uv_pipe_t*)stream, nread, buf, UV_UNKNOWN_HANDLE);
} }

1
deps/uv/src/win/core.c

@ -59,6 +59,7 @@ static void uv_init(void) {
static void uv_loop_init(uv_loop_t* loop) { static void uv_loop_init(uv_loop_t* loop) {
loop->uv_ares_handles_ = NULL;
/* Create an I/O completion port */ /* Create an I/O completion port */
loop->iocp = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 1); loop->iocp = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 1);
if (loop->iocp == NULL) { if (loop->iocp == NULL) {

2
deps/uv/src/win/error.c

@ -91,6 +91,8 @@ uv_err_code uv_translate_sys_error(int sys_errno) {
case WSAEFAULT: return UV_EFAULT; case WSAEFAULT: return UV_EFAULT;
case ERROR_HOST_UNREACHABLE: return UV_EHOSTUNREACH; case ERROR_HOST_UNREACHABLE: return UV_EHOSTUNREACH;
case WSAEHOSTUNREACH: return UV_EHOSTUNREACH; case WSAEHOSTUNREACH: return UV_EHOSTUNREACH;
case ERROR_OPERATION_ABORTED: return UV_EINTR;
case WSAEINTR: return UV_EINTR;
case ERROR_INVALID_DATA: return UV_EINVAL; case ERROR_INVALID_DATA: return UV_EINVAL;
case WSAEINVAL: return UV_EINVAL; case WSAEINVAL: return UV_EINVAL;
case ERROR_CANT_RESOLVE_FILENAME: return UV_ELOOP; case ERROR_CANT_RESOLVE_FILENAME: return UV_ELOOP;

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

@ -547,7 +547,8 @@ static void fs__stat(uv_fs_t* req, const wchar_t* path) {
req->stat.st_size = ((int64_t) info.nFileSizeHigh << 32) + req->stat.st_size = ((int64_t) info.nFileSizeHigh << 32) +
(int64_t) info.nFileSizeLow; (int64_t) info.nFileSizeLow;
req->stat.st_nlink = info.nNumberOfLinks; req->stat.st_nlink = (info.nNumberOfLinks <= SHRT_MAX) ?
(short) info.nNumberOfLinks : SHRT_MAX;
req->ptr = &req->stat; req->ptr = &req->stat;
req->result = 0; req->result = 0;

15
deps/uv/src/win/handle.c

@ -27,9 +27,15 @@
uv_handle_type uv_guess_handle(uv_file file) { uv_handle_type uv_guess_handle(uv_file file) {
HANDLE handle = (HANDLE) _get_osfhandle(file); HANDLE handle;
DWORD mode; DWORD mode;
if (file < 0) {
return UV_UNKNOWN_HANDLE;
}
handle = (HANDLE) _get_osfhandle(file);
switch (GetFileType(handle)) { switch (GetFileType(handle)) {
case FILE_TYPE_CHAR: case FILE_TYPE_CHAR:
if (GetConsoleMode(handle, &mode)) { if (GetConsoleMode(handle, &mode)) {
@ -85,9 +91,10 @@ void uv_close(uv_handle_t* handle, uv_close_cb cb) {
tcp = (uv_tcp_t*)handle; tcp = (uv_tcp_t*)handle;
/* If we don't shutdown before calling closesocket, windows will */ /* If we don't shutdown before calling closesocket, windows will */
/* silently discard the kernel send buffer and reset the connection. */ /* silently discard the kernel send buffer and reset the connection. */
if (!(tcp->flags & UV_HANDLE_SHUT)) { if ((tcp->flags & UV_HANDLE_CONNECTION) &&
!(tcp->flags & UV_HANDLE_SHUT)) {
shutdown(tcp->socket, SD_SEND); shutdown(tcp->socket, SD_SEND);
tcp->flags |= UV_HANDLE_SHUT; tcp->flags |= UV_HANDLE_SHUTTING | UV_HANDLE_SHUT;
} }
tcp->flags &= ~(UV_HANDLE_READING | UV_HANDLE_LISTENING); tcp->flags &= ~(UV_HANDLE_READING | UV_HANDLE_LISTENING);
closesocket(tcp->socket); closesocket(tcp->socket);
@ -173,7 +180,7 @@ void uv_want_endgame(uv_loop_t* loop, uv_handle_t* handle) {
void uv_process_endgames(uv_loop_t* loop) { void uv_process_endgames(uv_loop_t* loop) {
uv_handle_t* handle; uv_handle_t* handle;
while (loop->endgame_handles) { while (loop->endgame_handles && loop->refs > 0) {
handle = loop->endgame_handles; handle = loop->endgame_handles;
loop->endgame_handles = handle->endgame_next; loop->endgame_handles = handle->endgame_next;

187
deps/uv/src/win/pipe.c

@ -98,59 +98,61 @@ static void uv_pipe_connection_init(uv_pipe_t* handle) {
} }
static int open_named_pipe(uv_pipe_t* handle) { static HANDLE open_named_pipe(WCHAR* name, DWORD* duplex_flags) {
/* HANDLE pipeHandle;
* Assume that we have a duplex pipe first, so attempt to
/*
* Assume that we have a duplex pipe first, so attempt to
* connect with GENERIC_READ | GENERIC_WRITE. * connect with GENERIC_READ | GENERIC_WRITE.
*/ */
handle->handle = CreateFileW(handle->name, pipeHandle = CreateFileW(name,
GENERIC_READ | GENERIC_WRITE, GENERIC_READ | GENERIC_WRITE,
0, 0,
NULL, NULL,
OPEN_EXISTING, OPEN_EXISTING,
FILE_FLAG_OVERLAPPED, FILE_FLAG_OVERLAPPED,
NULL); NULL);
if (pipeHandle != INVALID_HANDLE_VALUE) {
if (handle->handle != INVALID_HANDLE_VALUE) { *duplex_flags = 0;
return 0; return pipeHandle;
} }
/* /*
* If the pipe is not duplex CreateFileW fails with * If the pipe is not duplex CreateFileW fails with
* ERROR_ACCESS_DENIED. In that case try to connect * ERROR_ACCESS_DENIED. In that case try to connect
* as a read-only or write-only. * as a read-only or write-only.
*/ */
if (GetLastError() == ERROR_ACCESS_DENIED) { if (GetLastError() == ERROR_ACCESS_DENIED) {
handle->handle = CreateFileW(handle->name, pipeHandle = CreateFileW(name,
GENERIC_READ | FILE_WRITE_ATTRIBUTES, GENERIC_READ | FILE_WRITE_ATTRIBUTES,
0, 0,
NULL, NULL,
OPEN_EXISTING, OPEN_EXISTING,
FILE_FLAG_OVERLAPPED, FILE_FLAG_OVERLAPPED,
NULL); NULL);
if (handle->handle != INVALID_HANDLE_VALUE) { if (pipeHandle != INVALID_HANDLE_VALUE) {
handle->flags |= UV_HANDLE_SHUT; *duplex_flags = UV_HANDLE_SHUTTING;
return 0; return pipeHandle;
} }
} }
if (GetLastError() == ERROR_ACCESS_DENIED) { if (GetLastError() == ERROR_ACCESS_DENIED) {
handle->handle = CreateFileW(handle->name, pipeHandle = CreateFileW(name,
GENERIC_WRITE | FILE_READ_ATTRIBUTES, GENERIC_WRITE | FILE_READ_ATTRIBUTES,
0, 0,
NULL, NULL,
OPEN_EXISTING, OPEN_EXISTING,
FILE_FLAG_OVERLAPPED, FILE_FLAG_OVERLAPPED,
NULL); NULL);
if (handle->handle != INVALID_HANDLE_VALUE) { if (pipeHandle != INVALID_HANDLE_VALUE) {
handle->flags |= UV_HANDLE_EOF; *duplex_flags = UV_HANDLE_EOF;
return 0; return pipeHandle;
} }
} }
return -1; return INVALID_HANDLE_VALUE;
} }
@ -208,13 +210,18 @@ done:
static int uv_set_pipe_handle(uv_loop_t* loop, uv_pipe_t* handle, static int uv_set_pipe_handle(uv_loop_t* loop, uv_pipe_t* handle,
HANDLE pipeHandle) { HANDLE pipeHandle, DWORD duplex_flags) {
NTSTATUS nt_status; NTSTATUS nt_status;
IO_STATUS_BLOCK io_status; IO_STATUS_BLOCK io_status;
FILE_MODE_INFORMATION mode_info; FILE_MODE_INFORMATION mode_info;
DWORD mode = PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT; DWORD mode = PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT;
if (!SetNamedPipeHandleState(pipeHandle, &mode, NULL, NULL)) { if (!SetNamedPipeHandleState(pipeHandle, &mode, NULL, NULL)) {
/* If this returns ERROR_INVALID_PARAMETER we probably opened something */
/* that is not a pipe. */
if (GetLastError() == ERROR_INVALID_PARAMETER) {
SetLastError(WSAENOTSOCK);
}
return -1; return -1;
} }
@ -242,6 +249,9 @@ static int uv_set_pipe_handle(uv_loop_t* loop, uv_pipe_t* handle,
} }
} }
handle->handle = pipeHandle;
handle->flags |= duplex_flags;
return 0; return 0;
} }
@ -276,11 +286,25 @@ void uv_pipe_endgame(uv_loop_t* loop, uv_pipe_t* handle) {
IO_STATUS_BLOCK io_status; IO_STATUS_BLOCK io_status;
FILE_PIPE_LOCAL_INFORMATION pipe_info; FILE_PIPE_LOCAL_INFORMATION pipe_info;
if (handle->flags & UV_HANDLE_SHUTTING && if ((handle->flags & UV_HANDLE_CONNECTION) &&
!(handle->flags & UV_HANDLE_SHUT) && handle->shutdown_req != NULL &&
handle->write_reqs_pending == 0) { handle->write_reqs_pending == 0) {
req = handle->shutdown_req; req = handle->shutdown_req;
/* Clear the shutdown_req field so we don't go here again. */
handle->shutdown_req = NULL;
if (handle->flags & UV_HANDLE_CLOSING) {
/* Already closing. Cancel the shutdown. */
if (req->cb) {
uv__set_sys_error(loop, WSAEINTR);
req->cb(req, -1);
}
uv_unref(loop);
DECREASE_PENDING_REQ_COUNT(handle);
return;
}
/* Try to avoid flushing the pipe buffer in the thread pool. */ /* Try to avoid flushing the pipe buffer in the thread pool. */
nt_status = pNtQueryInformationFile(handle->handle, nt_status = pNtQueryInformationFile(handle->handle,
&io_status, &io_status,
@ -295,13 +319,12 @@ void uv_pipe_endgame(uv_loop_t* loop, uv_pipe_t* handle) {
uv__set_sys_error(loop, pRtlNtStatusToDosError(nt_status)); uv__set_sys_error(loop, pRtlNtStatusToDosError(nt_status));
req->cb(req, -1); req->cb(req, -1);
} }
uv_unref(loop);
DECREASE_PENDING_REQ_COUNT(handle); DECREASE_PENDING_REQ_COUNT(handle);
return; return;
} }
if (pipe_info.OutboundQuota == pipe_info.WriteQuotaAvailable) { if (pipe_info.OutboundQuota == pipe_info.WriteQuotaAvailable) {
handle->flags |= UV_HANDLE_SHUT;
/* Short-circuit, no need to call FlushFileBuffers. */ /* Short-circuit, no need to call FlushFileBuffers. */
uv_insert_pending_req(loop, (uv_req_t*) req); uv_insert_pending_req(loop, (uv_req_t*) req);
return; return;
@ -312,8 +335,6 @@ void uv_pipe_endgame(uv_loop_t* loop, uv_pipe_t* handle) {
req, req,
WT_EXECUTELONGFUNCTION); WT_EXECUTELONGFUNCTION);
if (result) { if (result) {
/* Mark the handle as shut now to avoid going through this again. */
handle->flags |= UV_HANDLE_SHUT;
return; return;
} else { } else {
@ -323,6 +344,7 @@ void uv_pipe_endgame(uv_loop_t* loop, uv_pipe_t* handle) {
uv__set_sys_error(loop, GetLastError()); uv__set_sys_error(loop, GetLastError());
req->cb(req, -1); req->cb(req, -1);
} }
uv_unref(loop);
DECREASE_PENDING_REQ_COUNT(handle); DECREASE_PENDING_REQ_COUNT(handle);
return; return;
} }
@ -338,7 +360,7 @@ void uv_pipe_endgame(uv_loop_t* loop, uv_pipe_t* handle) {
free(handle->pending_socket_info); free(handle->pending_socket_info);
handle->pending_socket_info = NULL; handle->pending_socket_info = NULL;
} }
if (handle->flags & UV_HANDLE_EMULATE_IOCP) { if (handle->flags & UV_HANDLE_EMULATE_IOCP) {
if (handle->read_req.wait_handle != INVALID_HANDLE_VALUE) { if (handle->read_req.wait_handle != INVALID_HANDLE_VALUE) {
UnregisterWait(handle->read_req.wait_handle); UnregisterWait(handle->read_req.wait_handle);
@ -449,7 +471,7 @@ int uv_pipe_bind(uv_pipe_t* handle, const char* name) {
goto error; goto error;
} }
if (uv_set_pipe_handle(loop, handle, handle->accept_reqs[0].pipeHandle)) { if (uv_set_pipe_handle(loop, handle, handle->accept_reqs[0].pipeHandle, 0)) {
uv__set_sys_error(loop, GetLastError()); uv__set_sys_error(loop, GetLastError());
goto error; goto error;
} }
@ -476,11 +498,12 @@ error:
static DWORD WINAPI pipe_connect_thread_proc(void* parameter) { static DWORD WINAPI pipe_connect_thread_proc(void* parameter) {
HANDLE pipeHandle = INVALID_HANDLE_VALUE;
int errno; int errno;
uv_loop_t* loop; uv_loop_t* loop;
uv_pipe_t* handle; uv_pipe_t* handle;
uv_connect_t* req; uv_connect_t* req;
HANDLE pipeHandle = INVALID_HANDLE_VALUE;
DWORD duplex_flags;
req = (uv_connect_t*) parameter; req = (uv_connect_t*) parameter;
assert(req); assert(req);
@ -493,7 +516,8 @@ static DWORD WINAPI pipe_connect_thread_proc(void* parameter) {
/* We wait for the pipe to become available with WaitNamedPipe. */ /* We wait for the pipe to become available with WaitNamedPipe. */
while (WaitNamedPipeW(handle->name, 30000)) { while (WaitNamedPipeW(handle->name, 30000)) {
/* The pipe is now available, try to connect. */ /* The pipe is now available, try to connect. */
if (open_named_pipe(handle) == 0) { pipeHandle = open_named_pipe(handle->name, &duplex_flags);
if (pipeHandle != INVALID_HANDLE_VALUE) {
break; break;
} }
@ -501,8 +525,7 @@ static DWORD WINAPI pipe_connect_thread_proc(void* parameter) {
} }
if (pipeHandle != INVALID_HANDLE_VALUE && if (pipeHandle != INVALID_HANDLE_VALUE &&
!uv_set_pipe_handle(loop, handle, pipeHandle)) { !uv_set_pipe_handle(loop, handle, pipeHandle, duplex_flags)) {
handle->handle = pipeHandle;
SET_REQ_SUCCESS(req); SET_REQ_SUCCESS(req);
} else { } else {
SET_REQ_ERROR(req, GetLastError()); SET_REQ_ERROR(req, GetLastError());
@ -519,8 +542,8 @@ void uv_pipe_connect(uv_connect_t* req, uv_pipe_t* handle,
const char* name, uv_connect_cb cb) { const char* name, uv_connect_cb cb) {
uv_loop_t* loop = handle->loop; uv_loop_t* loop = handle->loop;
int errno, nameSize; int errno, nameSize;
HANDLE pipeHandle = INVALID_HANDLE_VALUE;
handle->handle = INVALID_HANDLE_VALUE; DWORD duplex_flags;
uv_req_init(loop, (uv_req_t*) req); uv_req_init(loop, (uv_req_t*) req);
req->type = UV_CONNECT; req->type = UV_CONNECT;
@ -539,7 +562,8 @@ void uv_pipe_connect(uv_connect_t* req, uv_pipe_t* handle,
goto error; goto error;
} }
if (open_named_pipe(handle) != 0) { pipeHandle = open_named_pipe(handle->name, &duplex_flags);
if (pipeHandle == INVALID_HANDLE_VALUE) {
if (GetLastError() == ERROR_PIPE_BUSY) { if (GetLastError() == ERROR_PIPE_BUSY) {
/* Wait for the server to make a pipe instance available. */ /* Wait for the server to make a pipe instance available. */
if (!QueueUserWorkItem(&pipe_connect_thread_proc, if (!QueueUserWorkItem(&pipe_connect_thread_proc,
@ -549,6 +573,7 @@ void uv_pipe_connect(uv_connect_t* req, uv_pipe_t* handle,
goto error; goto error;
} }
uv_ref(loop);
handle->reqs_pending++; handle->reqs_pending++;
return; return;
@ -558,15 +583,12 @@ void uv_pipe_connect(uv_connect_t* req, uv_pipe_t* handle,
goto error; goto error;
} }
assert(handle->handle != INVALID_HANDLE_VALUE); assert(pipeHandle != INVALID_HANDLE_VALUE);
/* Ensure that what we just opened is actually a pipe */ if (uv_set_pipe_handle(loop,
if (!GetNamedPipeInfo(handle->handle, NULL, NULL, NULL, NULL)) { (uv_pipe_t*) req->handle,
errno = WSAENOTSOCK; pipeHandle,
goto error; duplex_flags)) {
}
if (uv_set_pipe_handle(loop, (uv_pipe_t*)req->handle, handle->handle)) {
errno = GetLastError(); errno = GetLastError();
goto error; goto error;
} }
@ -574,6 +596,7 @@ void uv_pipe_connect(uv_connect_t* req, uv_pipe_t* handle,
SET_REQ_SUCCESS(req); SET_REQ_SUCCESS(req);
uv_insert_pending_req(loop, (uv_req_t*) req); uv_insert_pending_req(loop, (uv_req_t*) req);
handle->reqs_pending++; handle->reqs_pending++;
uv_ref(loop);
return; return;
error: error:
@ -582,15 +605,15 @@ error:
handle->name = NULL; handle->name = NULL;
} }
if (handle->handle != INVALID_HANDLE_VALUE) { if (pipeHandle != INVALID_HANDLE_VALUE) {
CloseHandle(handle->handle); CloseHandle(pipeHandle);
handle->handle = INVALID_HANDLE_VALUE;
} }
/* Make this req pending reporting an error. */ /* Make this req pending reporting an error. */
SET_REQ_ERROR(req, errno); SET_REQ_ERROR(req, errno);
uv_insert_pending_req(loop, (uv_req_t*) req); uv_insert_pending_req(loop, (uv_req_t*) req);
handle->reqs_pending++; handle->reqs_pending++;
uv_ref(loop);
return; return;
} }
@ -617,6 +640,7 @@ void close_pipe(uv_pipe_t* handle, int* status, uv_err_t* err) {
} }
if (handle->flags & UV_HANDLE_CONNECTION) { if (handle->flags & UV_HANDLE_CONNECTION) {
handle->flags |= UV_HANDLE_SHUTTING;
eof_timer_destroy(handle); eof_timer_destroy(handle);
} }
@ -625,8 +649,6 @@ void close_pipe(uv_pipe_t* handle, int* status, uv_err_t* err) {
CloseHandle(handle->handle); CloseHandle(handle->handle);
handle->handle = INVALID_HANDLE_VALUE; handle->handle = INVALID_HANDLE_VALUE;
} }
handle->flags |= UV_HANDLE_SHUT;
} }
@ -649,7 +671,7 @@ static void uv_pipe_queue_accept(uv_loop_t* loop, uv_pipe_t* handle,
return; return;
} }
if (uv_set_pipe_handle(loop, handle, req->pipeHandle)) { if (uv_set_pipe_handle(loop, handle, req->pipeHandle, 0)) {
CloseHandle(req->pipeHandle); CloseHandle(req->pipeHandle);
req->pipeHandle = INVALID_HANDLE_VALUE; req->pipeHandle = INVALID_HANDLE_VALUE;
SET_REQ_ERROR(req, GetLastError()); SET_REQ_ERROR(req, GetLastError());
@ -872,7 +894,7 @@ static void uv_pipe_queue_read(uv_loop_t* loop, uv_pipe_t* handle) {
/* Make this req pending reporting an error. */ /* Make this req pending reporting an error. */
SET_REQ_ERROR(req, GetLastError()); SET_REQ_ERROR(req, GetLastError());
goto error; goto error;
} }
} else { } else {
memset(&req->overlapped, 0, sizeof(req->overlapped)); memset(&req->overlapped, 0, sizeof(req->overlapped));
if (handle->flags & UV_HANDLE_EMULATE_IOCP) { if (handle->flags & UV_HANDLE_EMULATE_IOCP) {
@ -1077,7 +1099,7 @@ static int uv_pipe_write_impl(uv_loop_t* loop, uv_write_t* req,
ipc_frame.header.raw_data_length = bufs[0].len; ipc_frame.header.raw_data_length = bufs[0].len;
} }
/* /*
* Use the provided req if we're only doing a single write. * Use the provided req if we're only doing a single write.
* If we're doing multiple writes, use ipc_header_write_req to do * If we're doing multiple writes, use ipc_header_write_req to do
* the first write, and then use the provided req for the second write. * the first write, and then use the provided req for the second write.
@ -1085,7 +1107,7 @@ static int uv_pipe_write_impl(uv_loop_t* loop, uv_write_t* req,
if (!(ipc_frame.header.flags & UV_IPC_RAW_DATA)) { if (!(ipc_frame.header.flags & UV_IPC_RAW_DATA)) {
ipc_header_req = req; ipc_header_req = req;
} else { } else {
/* /*
* Try to use the preallocated write req if it's available. * Try to use the preallocated write req if it's available.
* Otherwise allocate a new one. * Otherwise allocate a new one.
*/ */
@ -1129,10 +1151,7 @@ static int uv_pipe_write_impl(uv_loop_t* loop, uv_write_t* req,
handle->write_queue_size += req->queued_bytes; handle->write_queue_size += req->queued_bytes;
} }
if (handle->write_reqs_pending == 0) { uv_ref(loop);
uv_ref(loop);
}
handle->reqs_pending++; handle->reqs_pending++;
handle->write_reqs_pending++; handle->write_reqs_pending++;
@ -1187,10 +1206,7 @@ static int uv_pipe_write_impl(uv_loop_t* loop, uv_write_t* req,
} }
} }
if (handle->write_reqs_pending == 0) { uv_ref(loop);
uv_ref(loop);
}
handle->reqs_pending++; handle->reqs_pending++;
handle->write_reqs_pending++; handle->write_reqs_pending++;
@ -1365,7 +1381,7 @@ void uv_process_pipe_read_req(uv_loop_t* loop, uv_pipe_t* handle,
/* Successful read */ /* Successful read */
if (handle->ipc) { if (handle->ipc) {
assert(handle->remaining_ipc_rawdata_bytes >= bytes); assert(handle->remaining_ipc_rawdata_bytes >= bytes);
handle->remaining_ipc_rawdata_bytes = handle->remaining_ipc_rawdata_bytes =
handle->remaining_ipc_rawdata_bytes - bytes; handle->remaining_ipc_rawdata_bytes - bytes;
if (handle->read2_cb) { if (handle->read2_cb) {
handle->read2_cb(handle, bytes, buf, handle->read2_cb(handle, bytes, buf,
@ -1446,15 +1462,12 @@ void uv_process_pipe_write_req(uv_loop_t* loop, uv_pipe_t* handle,
uv_queue_non_overlapped_write(handle); uv_queue_non_overlapped_write(handle);
} }
if (handle->write_reqs_pending == 0) {
uv_unref(loop);
}
if (handle->write_reqs_pending == 0 && if (handle->write_reqs_pending == 0 &&
handle->flags & UV_HANDLE_SHUTTING) { handle->flags & UV_HANDLE_SHUTTING) {
uv_want_endgame(loop, (uv_handle_t*)handle); uv_want_endgame(loop, (uv_handle_t*)handle);
} }
uv_unref(loop);
DECREASE_PENDING_REQ_COUNT(handle); DECREASE_PENDING_REQ_COUNT(handle);
} }
@ -1501,6 +1514,7 @@ void uv_process_pipe_connect_req(uv_loop_t* loop, uv_pipe_t* handle,
} }
} }
uv_unref(loop);
DECREASE_PENDING_REQ_COUNT(handle); DECREASE_PENDING_REQ_COUNT(handle);
} }
@ -1525,6 +1539,7 @@ void uv_process_pipe_shutdown_req(uv_loop_t* loop, uv_pipe_t* handle,
req->cb(req, 0); req->cb(req, 0);
} }
uv_unref(loop);
DECREASE_PENDING_REQ_COUNT(handle); DECREASE_PENDING_REQ_COUNT(handle);
} }
@ -1540,6 +1555,7 @@ static void eof_timer_init(uv_pipe_t* pipe) {
r = uv_timer_init(pipe->loop, pipe->eof_timer); r = uv_timer_init(pipe->loop, pipe->eof_timer);
assert(r == 0); /* timers can't fail */ assert(r == 0); /* timers can't fail */
pipe->eof_timer->data = pipe; pipe->eof_timer->data = pipe;
uv_unref(pipe->loop);
} }
@ -1602,6 +1618,7 @@ static void eof_timer_destroy(uv_pipe_t* pipe) {
assert(pipe->flags && UV_HANDLE_CONNECTION); assert(pipe->flags && UV_HANDLE_CONNECTION);
if (pipe->eof_timer) { if (pipe->eof_timer) {
uv_ref(pipe->loop);
uv_close((uv_handle_t*) pipe->eof_timer, eof_timer_close_cb); uv_close((uv_handle_t*) pipe->eof_timer, eof_timer_close_cb);
pipe->eof_timer = NULL; pipe->eof_timer = NULL;
} }
@ -1618,7 +1635,7 @@ void uv_pipe_open(uv_pipe_t* pipe, uv_file file) {
HANDLE os_handle = (HANDLE)_get_osfhandle(file); HANDLE os_handle = (HANDLE)_get_osfhandle(file);
if (os_handle == INVALID_HANDLE_VALUE || if (os_handle == INVALID_HANDLE_VALUE ||
uv_set_pipe_handle(pipe->loop, pipe, os_handle) == -1) { uv_set_pipe_handle(pipe->loop, pipe, os_handle, 0) == -1) {
return; return;
} }

2
deps/uv/src/win/process.c

@ -832,7 +832,7 @@ done:
static int duplicate_std_handle(uv_loop_t* loop, DWORD id, HANDLE* dup) { static int duplicate_std_handle(uv_loop_t* loop, DWORD id, HANDLE* dup) {
HANDLE handle; HANDLE handle;
HANDLE current_process = GetCurrentProcess(); HANDLE current_process = GetCurrentProcess();
handle = GetStdHandle(id); handle = GetStdHandle(id);
if (handle == NULL) { if (handle == NULL) {

5
deps/uv/src/win/stream.c

@ -47,6 +47,8 @@ void uv_connection_init(uv_stream_t* handle) {
handle->read_req.wait_handle = INVALID_HANDLE_VALUE; handle->read_req.wait_handle = INVALID_HANDLE_VALUE;
handle->read_req.type = UV_READ; handle->read_req.type = UV_READ;
handle->read_req.data = handle; handle->read_req.data = handle;
handle->shutdown_req = NULL;
} }
@ -169,6 +171,7 @@ int uv_shutdown(uv_shutdown_t* req, uv_stream_t* handle, uv_shutdown_cb cb) {
handle->flags |= UV_HANDLE_SHUTTING; handle->flags |= UV_HANDLE_SHUTTING;
handle->shutdown_req = req; handle->shutdown_req = req;
handle->reqs_pending++; handle->reqs_pending++;
uv_ref(loop);
uv_want_endgame(loop, (uv_handle_t*)handle); uv_want_endgame(loop, (uv_handle_t*)handle);
@ -194,5 +197,5 @@ int uv_is_readable(uv_stream_t* handle) {
int uv_is_writable(uv_stream_t* handle) { int uv_is_writable(uv_stream_t* handle) {
return !(handle->flags & UV_HANDLE_SHUT); return !(handle->flags & UV_HANDLE_SHUTTING);
} }

27
deps/uv/src/win/tcp.c

@ -167,11 +167,13 @@ void uv_tcp_endgame(uv_loop_t* loop, uv_tcp_t* handle) {
uv_tcp_accept_t* req; uv_tcp_accept_t* req;
if (handle->flags & UV_HANDLE_CONNECTION && if (handle->flags & UV_HANDLE_CONNECTION &&
handle->flags & UV_HANDLE_SHUTTING && handle->shutdown_req != NULL &&
!(handle->flags & UV_HANDLE_SHUT) &&
handle->write_reqs_pending == 0) { handle->write_reqs_pending == 0) {
if (shutdown(handle->socket, SD_SEND) != SOCKET_ERROR) { if (handle->flags & UV_HANDLE_CLOSING) {
status = -1;
sys_error = WSAEINTR;
} else if (shutdown(handle->socket, SD_SEND) != SOCKET_ERROR) {
status = 0; status = 0;
handle->flags |= UV_HANDLE_SHUT; handle->flags |= UV_HANDLE_SHUT;
} else { } else {
@ -185,6 +187,9 @@ void uv_tcp_endgame(uv_loop_t* loop, uv_tcp_t* handle) {
handle->shutdown_req->cb(handle->shutdown_req, status); handle->shutdown_req->cb(handle->shutdown_req, status);
} }
handle->shutdown_req = NULL;
uv_unref(loop);
DECREASE_PENDING_REQ_COUNT(handle); DECREASE_PENDING_REQ_COUNT(handle);
return; return;
} }
@ -548,7 +553,7 @@ int uv_tcp_accept(uv_tcp_t* server, uv_tcp_t* client) {
if (server->processed_accepts >= uv_simultaneous_server_accepts) { if (server->processed_accepts >= uv_simultaneous_server_accepts) {
server->processed_accepts = 0; server->processed_accepts = 0;
/* /*
* All previously queued accept requests are now processed. * All previously queued accept requests are now processed.
* We now switch to queueing just a single accept. * We now switch to queueing just a single accept.
*/ */
@ -639,10 +644,12 @@ int uv__tcp_connect(uv_connect_t* req,
if (UV_SUCCEEDED_WITHOUT_IOCP(success)) { if (UV_SUCCEEDED_WITHOUT_IOCP(success)) {
/* Process the req without IOCP. */ /* Process the req without IOCP. */
handle->reqs_pending++; handle->reqs_pending++;
uv_ref(loop);
uv_insert_pending_req(loop, (uv_req_t*)req); uv_insert_pending_req(loop, (uv_req_t*)req);
} else if (UV_SUCCEEDED_WITH_IOCP(success)) { } else if (UV_SUCCEEDED_WITH_IOCP(success)) {
/* The req will be processed with IOCP. */ /* The req will be processed with IOCP. */
handle->reqs_pending++; handle->reqs_pending++;
uv_ref(loop);
} else { } else {
uv__set_sys_error(loop, WSAGetLastError()); uv__set_sys_error(loop, WSAGetLastError());
return -1; return -1;
@ -698,9 +705,11 @@ int uv__tcp_connect6(uv_connect_t* req,
if (UV_SUCCEEDED_WITHOUT_IOCP(success)) { if (UV_SUCCEEDED_WITHOUT_IOCP(success)) {
handle->reqs_pending++; handle->reqs_pending++;
uv_ref(loop);
uv_insert_pending_req(loop, (uv_req_t*)req); uv_insert_pending_req(loop, (uv_req_t*)req);
} else if (UV_SUCCEEDED_WITH_IOCP(success)) { } else if (UV_SUCCEEDED_WITH_IOCP(success)) {
handle->reqs_pending++; handle->reqs_pending++;
uv_ref(loop);
} else { } else {
uv__set_sys_error(loop, WSAGetLastError()); uv__set_sys_error(loop, WSAGetLastError());
return -1; return -1;
@ -795,12 +804,14 @@ int uv_tcp_write(uv_loop_t* loop, uv_write_t* req, uv_tcp_t* handle,
handle->reqs_pending++; handle->reqs_pending++;
handle->write_reqs_pending++; handle->write_reqs_pending++;
uv_insert_pending_req(loop, (uv_req_t*) req); uv_insert_pending_req(loop, (uv_req_t*) req);
uv_ref(loop);
} else if (UV_SUCCEEDED_WITH_IOCP(result == 0)) { } else if (UV_SUCCEEDED_WITH_IOCP(result == 0)) {
/* Request queued by the kernel. */ /* Request queued by the kernel. */
req->queued_bytes = uv_count_bufs(bufs, bufcnt); req->queued_bytes = uv_count_bufs(bufs, bufcnt);
handle->reqs_pending++; handle->reqs_pending++;
handle->write_reqs_pending++; handle->write_reqs_pending++;
handle->write_queue_size += req->queued_bytes; handle->write_queue_size += req->queued_bytes;
uv_ref(loop);
} else { } else {
/* Send failed due to an error. */ /* Send failed due to an error. */
uv__set_sys_error(loop, WSAGetLastError()); uv__set_sys_error(loop, WSAGetLastError());
@ -831,7 +842,7 @@ void uv_process_tcp_read_req(uv_loop_t* loop, uv_tcp_t* handle,
err = GET_REQ_SOCK_ERROR(req); err = GET_REQ_SOCK_ERROR(req);
if (err == WSAECONNABORTED) { if (err == WSAECONNABORTED) {
/* /*
* Turn WSAECONNABORTED into UV_ECONNRESET to be consistent with Unix. * Turn WSAECONNABORTED into UV_ECONNRESET to be consistent with Unix.
*/ */
uv__set_error(loop, UV_ECONNRESET, err); uv__set_error(loop, UV_ECONNRESET, err);
@ -900,7 +911,7 @@ void uv_process_tcp_read_req(uv_loop_t* loop, uv_tcp_t* handle,
handle->read_cb((uv_stream_t*)handle, 0, buf); handle->read_cb((uv_stream_t*)handle, 0, buf);
} else { } else {
if (err == WSAECONNABORTED) { if (err == WSAECONNABORTED) {
/* /*
* Turn WSAECONNABORTED into UV_ECONNRESET to be consistent with Unix. * Turn WSAECONNABORTED into UV_ECONNRESET to be consistent with Unix.
*/ */
uv__set_error(loop, UV_ECONNRESET, err); uv__set_error(loop, UV_ECONNRESET, err);
@ -946,6 +957,7 @@ void uv_process_tcp_write_req(uv_loop_t* loop, uv_tcp_t* handle,
} }
DECREASE_PENDING_REQ_COUNT(handle); DECREASE_PENDING_REQ_COUNT(handle);
uv_unref(loop);
} }
@ -1020,6 +1032,7 @@ void uv_process_tcp_connect_req(uv_loop_t* loop, uv_tcp_t* handle,
} }
DECREASE_PENDING_REQ_COUNT(handle); DECREASE_PENDING_REQ_COUNT(handle);
uv_unref(loop);
} }
@ -1086,7 +1099,7 @@ int uv_tcp_duplicate_socket(uv_tcp_t* handle, int pid,
LPWSAPROTOCOL_INFOW protocol_info) { LPWSAPROTOCOL_INFOW protocol_info) {
assert(!(handle->flags & UV_HANDLE_CONNECTION)); assert(!(handle->flags & UV_HANDLE_CONNECTION));
/* /*
* We're about to share the socket with another process. Because * We're about to share the socket with another process. Because
* this is a listening socket, we assume that the other process will * this is a listening socket, we assume that the other process will
* be accepting connections on it. So, before sharing the socket * be accepting connections on it. So, before sharing the socket

21
deps/uv/src/win/tty.c

@ -1683,6 +1683,7 @@ int uv_tty_write(uv_loop_t* loop, uv_write_t* req, uv_tty_t* handle,
handle->reqs_pending++; handle->reqs_pending++;
handle->write_reqs_pending++; handle->write_reqs_pending++;
uv_ref(loop);
req->queued_bytes = 0; req->queued_bytes = 0;
@ -1715,10 +1716,13 @@ void uv_process_tty_write_req(uv_loop_t* loop, uv_tty_t* handle,
} }
DECREASE_PENDING_REQ_COUNT(handle); DECREASE_PENDING_REQ_COUNT(handle);
uv_unref(loop);
} }
void uv_tty_close(uv_tty_t* handle) { void uv_tty_close(uv_tty_t* handle) {
handle->flags |= UV_HANDLE_SHUTTING;
uv_tty_read_stop(handle); uv_tty_read_stop(handle);
CloseHandle(handle->handle); CloseHandle(handle->handle);
@ -1729,17 +1733,22 @@ void uv_tty_close(uv_tty_t* handle) {
void uv_tty_endgame(uv_loop_t* loop, uv_tty_t* handle) { void uv_tty_endgame(uv_loop_t* loop, uv_tty_t* handle) {
if (handle->flags & UV_HANDLE_CONNECTION && if ((handle->flags && UV_HANDLE_CONNECTION) &&
handle->flags & UV_HANDLE_SHUTTING && handle->shutdown_req != NULL &&
!(handle->flags & UV_HANDLE_SHUT) &&
handle->write_reqs_pending == 0) { handle->write_reqs_pending == 0) {
handle->flags |= UV_HANDLE_SHUT;
/* TTY shutdown is really just a no-op */ /* TTY shutdown is really just a no-op */
if (handle->shutdown_req->cb) { if (handle->shutdown_req->cb) {
handle->shutdown_req->cb(handle->shutdown_req, 0); if (handle->flags & UV_HANDLE_CLOSING) {
uv__set_sys_error(loop, WSAEINTR);
handle->shutdown_req->cb(handle->shutdown_req, -1);
} else {
handle->shutdown_req->cb(handle->shutdown_req, 0);
}
} }
handle->shutdown_req = NULL;
uv_unref(loop);
DECREASE_PENDING_REQ_COUNT(handle); DECREASE_PENDING_REQ_COUNT(handle);
return; return;
} }

3
deps/uv/src/win/udp.c

@ -400,11 +400,13 @@ static int uv__udp_send(uv_udp_send_t* req, uv_udp_t* handle, uv_buf_t bufs[],
/* Request completed immediately. */ /* Request completed immediately. */
req->queued_bytes = 0; req->queued_bytes = 0;
handle->reqs_pending++; handle->reqs_pending++;
uv_ref(loop);
uv_insert_pending_req(loop, (uv_req_t*)req); uv_insert_pending_req(loop, (uv_req_t*)req);
} else if (UV_SUCCEEDED_WITH_IOCP(result == 0)) { } else if (UV_SUCCEEDED_WITH_IOCP(result == 0)) {
/* Request queued by the kernel. */ /* Request queued by the kernel. */
req->queued_bytes = uv_count_bufs(bufs, bufcnt); req->queued_bytes = uv_count_bufs(bufs, bufcnt);
handle->reqs_pending++; handle->reqs_pending++;
uv_ref(loop);
} else { } else {
/* Send failed due to an error. */ /* Send failed due to an error. */
uv__set_sys_error(loop, WSAGetLastError()); uv__set_sys_error(loop, WSAGetLastError());
@ -569,6 +571,7 @@ void uv_process_udp_send_req(uv_loop_t* loop, uv_udp_t* handle,
} }
} }
uv_unref(loop);
DECREASE_PENDING_REQ_COUNT(handle); DECREASE_PENDING_REQ_COUNT(handle);
} }

11
deps/uv/src/win/util.c

@ -490,11 +490,13 @@ uv_err_t uv_interface_addresses(uv_interface_address_t** addresses,
unsigned long size = 0; unsigned long size = 0;
IP_ADAPTER_ADDRESSES* adapter_addresses; IP_ADAPTER_ADDRESSES* adapter_addresses;
IP_ADAPTER_ADDRESSES* adapter_address; IP_ADAPTER_ADDRESSES* adapter_address;
IP_ADAPTER_UNICAST_ADDRESS_XP* unicast_address;
uv_interface_address_t* address; uv_interface_address_t* address;
struct sockaddr* sock_addr; struct sockaddr* sock_addr;
int length; int length;
char* name; char* name;
/* Use IP_ADAPTER_UNICAST_ADDRESS_XP to retain backwards compatibility */
/* with Windows XP */
IP_ADAPTER_UNICAST_ADDRESS_XP* unicast_address;
if (GetAdaptersAddresses(AF_UNSPEC, 0, NULL, NULL, &size) if (GetAdaptersAddresses(AF_UNSPEC, 0, NULL, NULL, &size)
!= ERROR_BUFFER_OVERFLOW) { != ERROR_BUFFER_OVERFLOW) {
@ -517,7 +519,8 @@ uv_err_t uv_interface_addresses(uv_interface_address_t** addresses,
for (adapter_address = adapter_addresses; for (adapter_address = adapter_addresses;
adapter_address != NULL; adapter_address != NULL;
adapter_address = adapter_address->Next) { adapter_address = adapter_address->Next) {
unicast_address = adapter_address->FirstUnicastAddress; unicast_address = (IP_ADAPTER_UNICAST_ADDRESS_XP*)
adapter_address->FirstUnicastAddress;
while (unicast_address) { while (unicast_address) {
(*count)++; (*count)++;
unicast_address = unicast_address->Next; unicast_address = unicast_address->Next;
@ -536,7 +539,8 @@ uv_err_t uv_interface_addresses(uv_interface_address_t** addresses,
adapter_address != NULL; adapter_address != NULL;
adapter_address = adapter_address->Next) { adapter_address = adapter_address->Next) {
name = NULL; name = NULL;
unicast_address = adapter_address->FirstUnicastAddress; unicast_address = (IP_ADAPTER_UNICAST_ADDRESS_XP*)
adapter_address->FirstUnicastAddress;
while (unicast_address) { while (unicast_address) {
sock_addr = unicast_address->Address.lpSockaddr; sock_addr = unicast_address->Address.lpSockaddr;
@ -610,6 +614,7 @@ void uv_filetime_to_time_t(FILETIME* file_time, time_t* stat_time) {
time.tm_hour = system_time.wHour; time.tm_hour = system_time.wHour;
time.tm_min = system_time.wMinute; time.tm_min = system_time.wMinute;
time.tm_sec = system_time.wSecond; time.tm_sec = system_time.wSecond;
time.tm_isdst = -1;
*stat_time = mktime(&time); *stat_time = mktime(&time);
} else { } else {

13
deps/uv/src/win/winapi.h

@ -4323,10 +4323,17 @@ typedef NTSTATUS (NTAPI *sNtSetInformationFile)
/* /*
* Kernel32 headers * Kernel32 headers
*/ */
#define FILE_SKIP_COMPLETION_PORT_ON_SUCCESS 0x1 #ifndef FILE_SKIP_COMPLETION_PORT_ON_SUCCESS
#define FILE_SKIP_SET_EVENT_ON_HANDLE 0x2 # define FILE_SKIP_COMPLETION_PORT_ON_SUCCESS 0x1
#endif
#ifdef FILE_SKIP_SET_EVENT_ON_HANDLE
# define FILE_SKIP_SET_EVENT_ON_HANDLE 0x2
#endif
#define SYMBOLIC_LINK_FLAG_DIRECTORY 0x1 #ifndef SYMBOLIC_LINK_FLAG_DIRECTORY
# define SYMBOLIC_LINK_FLAG_DIRECTORY 0x1
#endif
#ifdef __MINGW32__ #ifdef __MINGW32__
typedef struct _OVERLAPPED_ENTRY { typedef struct _OVERLAPPED_ENTRY {

4
deps/uv/test/benchmark-pound.c

@ -107,7 +107,9 @@ static void connect_cb(uv_connect_t* req, int status) {
if (status != 0) { if (status != 0) {
#if DEBUG #if DEBUG
fprintf(stderr, "connect error %s\n", uv_err_name(uv_last_error())); fprintf(stderr,
"connect error %s\n",
uv_err_name(uv_last_error(uv_default_loop())));
#endif #endif
uv_close((uv_handle_t*)req->handle, close_cb); uv_close((uv_handle_t*)req->handle, close_cb);
conns_failed++; conns_failed++;

2
deps/uv/test/benchmark-thread.c

@ -25,7 +25,7 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#define NUM_THREADS (100 * 1000) #define NUM_THREADS (20 * 1000)
static volatile int num_threads; static volatile int num_threads;

15
deps/uv/test/run-tests.c

@ -86,7 +86,7 @@ static void ipc_on_connection(uv_stream_t* server, int status) {
uv_tcp_t* conn; uv_tcp_t* conn;
if (!connection_accepted) { if (!connection_accepted) {
/* /*
* Accept the connection and close it. Also let the other * Accept the connection and close it. Also let the other
* side know. * side know.
*/ */
@ -121,7 +121,7 @@ static int ipc_helper(int listen_after_write) {
* data is transfered over the channel. XXX edit this comment after handle * data is transfered over the channel. XXX edit this comment after handle
* transfer is added. * transfer is added.
*/ */
uv_write_t write_req; uv_write_t write_req;
int r; int r;
uv_buf_t buf; uv_buf_t buf;
@ -131,8 +131,8 @@ static int ipc_helper(int listen_after_write) {
uv_pipe_open(&channel, 0); uv_pipe_open(&channel, 0);
ASSERT(uv_is_readable((uv_stream_t*)&channel)); ASSERT(uv_is_readable((uv_stream_t*) &channel));
ASSERT(uv_is_writable((uv_stream_t*)&channel)); ASSERT(uv_is_writable((uv_stream_t*) &channel));
r = uv_tcp_init(uv_default_loop(), &tcp_server); r = uv_tcp_init(uv_default_loop(), &tcp_server);
ASSERT(r == 0); ASSERT(r == 0);
@ -208,7 +208,7 @@ static int stdio_over_pipes_helper() {
uv_buf_t buf[ARRAY_SIZE(buffers)]; uv_buf_t buf[ARRAY_SIZE(buffers)];
int r, i; int r, i;
uv_loop_t* loop = uv_default_loop(); uv_loop_t* loop = uv_default_loop();
ASSERT(UV_NAMED_PIPE == uv_guess_handle(0)); ASSERT(UV_NAMED_PIPE == uv_guess_handle(0));
ASSERT(UV_NAMED_PIPE == uv_guess_handle(1)); ASSERT(UV_NAMED_PIPE == uv_guess_handle(1));
@ -271,6 +271,11 @@ static int maybe_run_test(int argc, char **argv) {
return ipc_helper(1); return ipc_helper(1);
} }
if (strcmp(argv[1], "ipc_send_recv_helper") == 0) {
int ipc_send_recv_helper(void); /* See test-ipc-send-recv.c */
return ipc_send_recv_helper();
}
if (strcmp(argv[1], "stdio_over_pipes_helper") == 0) { if (strcmp(argv[1], "stdio_over_pipes_helper") == 0) {
return stdio_over_pipes_helper(); return stdio_over_pipes_helper();
} }

2
deps/uv/test/runner-win.c

@ -135,7 +135,7 @@ int process_start(char *name, char *part, process_info_t *p) {
p->stdio_in = nul; p->stdio_in = nul;
p->stdio_out = file; p->stdio_out = file;
p->process = pi.hProcess; p->process = pi.hProcess;
p->name = name; p->name = part;
return 0; return 0;

5
deps/uv/test/runner.c

@ -186,7 +186,8 @@ out:
process_terminate(&processes[i]); process_terminate(&processes[i]);
} }
if (process_wait(processes, process_count - 1, -1) < 0) { if (process_count > 0 &&
process_wait(processes, process_count - 1, -1) < 0) {
FATAL("process_wait failed"); FATAL("process_wait failed");
} }
@ -194,6 +195,8 @@ out:
if (status != 0 || task->show_output) { if (status != 0 || task->show_output) {
if (status != 0) { if (status != 0) {
LOGF("\n`%s` failed: %s\n", test, errmsg); LOGF("\n`%s` failed: %s\n", test, errmsg);
} else {
LOGF("\n");
} }
for (i = 0; i < process_count; i++) { for (i = 0; i < process_count; i++) {

30
deps/uv/test/test-counters-init.c

@ -92,21 +92,21 @@ static void create_cb(uv_fs_t* req) {
TEST_IMPL(counters_init) { TEST_IMPL(counters_init) {
int r; int r;
int eio_init_prev; uint64_t eio_init_prev;
int req_init_prev; uint64_t req_init_prev;
int handle_init_prev; uint64_t handle_init_prev;
int stream_init_prev; uint64_t stream_init_prev;
int tcp_init_prev; uint64_t tcp_init_prev;
int udp_init_prev; uint64_t udp_init_prev;
int pipe_init_prev; uint64_t pipe_init_prev;
int tty_init_prev; uint64_t tty_init_prev;
int prepare_init_prev; uint64_t prepare_init_prev;
int check_init_prev; uint64_t check_init_prev;
int idle_init_prev; uint64_t idle_init_prev;
int async_init_prev; uint64_t async_init_prev;
int timer_init_prev; uint64_t timer_init_prev;
int process_init_prev; uint64_t process_init_prev;
int fs_event_init_prev; uint64_t fs_event_init_prev;
/* req_init and eio_init test by uv_fs_open() */ /* req_init and eio_init test by uv_fs_open() */
unlink("test_file"); unlink("test_file");

21
deps/uv/test/test-cwd-and-chdir.c

@ -37,17 +37,20 @@ TEST_IMPL(cwd_and_chdir) {
err = uv_cwd(buffer_orig, size); err = uv_cwd(buffer_orig, size);
ASSERT(err.code == UV_OK); ASSERT(err.code == UV_OK);
last_slash = strrchr(buffer_orig, /* Remove trailing slash unless at a root directory. */
#ifdef _WIN32 #ifdef _WIN32
'\\' last_slash = strrchr(buffer_orig, '\\');
#else
'/'
#endif
);
ASSERT(last_slash); ASSERT(last_slash);
if (last_slash > buffer_orig && *(last_slash - 1) != ':') {
*last_slash = '\0'; *last_slash = '\0';
}
#else /* Unix */
last_slash = strrchr(buffer_orig, '/');
ASSERT(last_slash);
if (last_slash != buffer_orig) {
*last_slash = '\0';
}
#endif
err = uv_chdir(buffer_orig); err = uv_chdir(buffer_orig);
ASSERT(err.code == UV_OK); ASSERT(err.code == UV_OK);

66
deps/uv/test/test-fs.c

@ -115,7 +115,7 @@ void check_permission(const char* filename, int mode) {
s = req.ptr; s = req.ptr;
#ifdef _WIN32 #ifdef _WIN32
/* /*
* On Windows, chmod can only modify S_IWUSR (_S_IWRITE) bit, * On Windows, chmod can only modify S_IWUSR (_S_IWRITE) bit,
* so only testing for the specified flags. * so only testing for the specified flags.
*/ */
@ -186,8 +186,14 @@ static void chown_cb(uv_fs_t* req) {
static void chown_root_cb(uv_fs_t* req) { static void chown_root_cb(uv_fs_t* req) {
ASSERT(req->fs_type == UV_FS_CHOWN); ASSERT(req->fs_type == UV_FS_CHOWN);
#ifdef _WIN32
/* On windows, chown is a no-op and always succeeds. */
ASSERT(req->result == 0);
#else
/* On unix, chown'ing the root directory is not allowed. */
ASSERT(req->result == -1); ASSERT(req->result == -1);
ASSERT(req->errorno == UV_EPERM); ASSERT(req->errorno == UV_EPERM);
#endif
chown_cb_count++; chown_cb_count++;
uv_fs_req_cleanup(req); uv_fs_req_cleanup(req);
} }
@ -1218,7 +1224,7 @@ TEST_IMPL(fs_symlink) {
*/ */
return 0; return 0;
} else if (uv_last_error(loop).sys_errno_ == ERROR_PRIVILEGE_NOT_HELD) { } else if (uv_last_error(loop).sys_errno_ == ERROR_PRIVILEGE_NOT_HELD) {
/* /*
* Creating a symlink is only allowed when running elevated. * Creating a symlink is only allowed when running elevated.
* We pass the test and bail out early if we get ERROR_PRIVILEGE_NOT_HELD. * We pass the test and bail out early if we get ERROR_PRIVILEGE_NOT_HELD.
*/ */
@ -1667,3 +1673,59 @@ TEST_IMPL(fs_rename_to_existing_file) {
return 0; return 0;
} }
TEST_IMPL(fs_read_file_eof) {
int r;
/* Setup. */
unlink("test_file");
loop = uv_default_loop();
r = uv_fs_open(loop, &open_req1, "test_file", O_WRONLY | O_CREAT,
S_IWRITE | S_IREAD, NULL);
ASSERT(r != -1);
ASSERT(open_req1.result != -1);
uv_fs_req_cleanup(&open_req1);
r = uv_fs_write(loop, &write_req, open_req1.result, test_buf,
sizeof(test_buf), -1, NULL);
ASSERT(r != -1);
ASSERT(write_req.result != -1);
uv_fs_req_cleanup(&write_req);
r = uv_fs_close(loop, &close_req, open_req1.result, NULL);
ASSERT(r != -1);
ASSERT(close_req.result != -1);
uv_fs_req_cleanup(&close_req);
r = uv_fs_open(loop, &open_req1, "test_file", O_RDONLY, 0, NULL);
ASSERT(r != -1);
ASSERT(open_req1.result != -1);
uv_fs_req_cleanup(&open_req1);
memset(buf, 0, sizeof(buf));
r = uv_fs_read(loop, &read_req, open_req1.result, buf, sizeof(buf), -1,
NULL);
ASSERT(r != -1);
ASSERT(read_req.result != -1);
ASSERT(strcmp(buf, test_buf) == 0);
uv_fs_req_cleanup(&read_req);
r = uv_fs_read(loop, &read_req, open_req1.result, buf, sizeof(buf),
read_req.result, NULL);
ASSERT(r == 0);
ASSERT(read_req.result == 0);
uv_fs_req_cleanup(&read_req);
r = uv_fs_close(loop, &close_req, open_req1.result, NULL);
ASSERT(r != -1);
ASSERT(close_req.result != -1);
uv_fs_req_cleanup(&close_req);
/* Cleanup */
unlink("test_file");
return 0;
}

208
deps/uv/test/test-ipc-send-recv.c

@ -0,0 +1,208 @@
/* 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>
/* See test-ipc.ctx */
void spawn_helper(uv_pipe_t* channel,
uv_process_t* process,
const char* helper);
union handles {
uv_handle_t handle;
uv_stream_t stream;
uv_pipe_t pipe;
uv_tcp_t tcp;
uv_tty_t tty;
};
struct echo_ctx {
uv_pipe_t channel;
uv_write_t write_req;
uv_handle_type expected_type;
union handles send;
union handles recv;
};
static struct echo_ctx ctx;
static int num_recv_handles;
static uv_buf_t alloc_cb(uv_handle_t* handle, size_t suggested_size) {
/* we're not actually reading anything so a small buffer is okay */
static char buf[8];
return uv_buf_init(buf, sizeof(buf));
}
static void recv_cb(uv_pipe_t* handle,
ssize_t nread,
uv_buf_t buf,
uv_handle_type pending) {
int r;
ASSERT(pending == ctx.expected_type);
ASSERT(handle == &ctx.channel);
ASSERT(nread >= 0);
if (pending == UV_NAMED_PIPE)
r = uv_pipe_init(ctx.channel.loop, &ctx.recv.pipe, 0);
else if (pending == UV_TCP)
r = uv_tcp_init(ctx.channel.loop, &ctx.recv.tcp);
else
abort();
ASSERT(r == 0);
r = uv_accept((uv_stream_t*)&ctx.channel, &ctx.recv.stream);
ASSERT(r == 0);
uv_close((uv_handle_t*)&ctx.channel, NULL);
uv_close(&ctx.send.handle, NULL);
uv_close(&ctx.recv.handle, NULL);
num_recv_handles++;
}
static int run_test(void) {
uv_process_t process;
uv_buf_t buf;
int r;
spawn_helper(&ctx.channel, &process, "ipc_send_recv_helper");
buf = uv_buf_init(".", 1);
r = uv_write2(&ctx.write_req,
(uv_stream_t*)&ctx.channel,
&buf, 1,
&ctx.send.stream,
NULL);
ASSERT(r == 0);
r = uv_read2_start((uv_stream_t*)&ctx.channel, alloc_cb, recv_cb);
ASSERT(r == 0);
r = uv_run(uv_default_loop());
ASSERT(r == 0);
ASSERT(num_recv_handles == 1);
return 0;
}
TEST_IMPL(ipc_send_recv_pipe) {
int r;
ctx.expected_type = UV_NAMED_PIPE;
r = uv_pipe_init(uv_default_loop(), &ctx.send.pipe, 1);
ASSERT(r == 0);
r = uv_pipe_bind(&ctx.send.pipe, TEST_PIPENAME);
ASSERT(r == 0);
return run_test();
}
TEST_IMPL(ipc_send_recv_tcp) {
int r;
ctx.expected_type = UV_TCP;
r = uv_tcp_init(uv_default_loop(), &ctx.send.tcp);
ASSERT(r == 0);
r = uv_tcp_bind(&ctx.send.tcp, uv_ip4_addr("127.0.0.1", TEST_PORT));
ASSERT(r == 0);
return run_test();
}
/* Everything here runs in a child process. */
static void write2_cb(uv_write_t* req, int status) {
ASSERT(status == 0);
uv_close(&ctx.recv.handle, NULL);
uv_close((uv_handle_t*)&ctx.channel, NULL);
}
static void read2_cb(uv_pipe_t* handle,
ssize_t nread,
uv_buf_t buf,
uv_handle_type pending) {
int r;
ASSERT(pending == UV_NAMED_PIPE || pending == UV_TCP);
ASSERT(handle == &ctx.channel);
ASSERT(nread >= 0);
buf = uv_buf_init(".", 1);
if (pending == UV_NAMED_PIPE)
r = uv_pipe_init(ctx.channel.loop, &ctx.recv.pipe, 0);
else if (pending == UV_TCP)
r = uv_tcp_init(ctx.channel.loop, &ctx.recv.tcp);
else
abort();
ASSERT(r == 0);
r = uv_accept((uv_stream_t*)handle, &ctx.recv.stream);
ASSERT(r == 0);
r = uv_write2(&ctx.write_req,
(uv_stream_t*)&ctx.channel,
&buf, 1,
&ctx.recv.stream,
write2_cb);
ASSERT(r == 0);
}
/* stdin is a duplex channel over which a handle is sent.
* We receive it and send it back where it came from.
*/
int ipc_send_recv_helper(void) {
int r;
memset(&ctx, 0, sizeof(ctx));
r = uv_pipe_init(uv_default_loop(), &ctx.channel, 1);
ASSERT(r == 0);
uv_pipe_open(&ctx.channel, 0);
ASSERT(uv_is_readable((uv_stream_t*)&ctx.channel));
ASSERT(uv_is_writable((uv_stream_t*)&ctx.channel));
r = uv_read2_start((uv_stream_t*)&ctx.channel, alloc_cb, read2_cb);
ASSERT(r == 0);
r = uv_run(uv_default_loop());
ASSERT(r == 0);
return 0;
}

35
deps/uv/test/test-ipc.c

@ -25,9 +25,6 @@
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
static char exepath[1024];
static size_t exepath_size = 1024;
static char* args[3];
static uv_pipe_t channel; static uv_pipe_t channel;
static uv_tcp_t tcp_server; static uv_tcp_t tcp_server;
@ -184,31 +181,44 @@ static void on_read(uv_pipe_t* pipe, ssize_t nread, uv_buf_t buf,
} }
int run_ipc_test(const char* helper) { void spawn_helper(uv_pipe_t* channel,
int r; uv_process_t* process,
const char* helper) {
uv_process_options_t options; uv_process_options_t options;
uv_process_t process; size_t exepath_size;
char exepath[1024];
char* args[3];
int r;
r = uv_pipe_init(uv_default_loop(), &channel, 1); r = uv_pipe_init(uv_default_loop(), channel, 1);
ASSERT(r == 0); ASSERT(r == 0);
ASSERT(channel.ipc); ASSERT(channel->ipc);
memset(&options, 0, sizeof(uv_process_options_t));
exepath_size = sizeof(exepath);
r = uv_exepath(exepath, &exepath_size); r = uv_exepath(exepath, &exepath_size);
ASSERT(r == 0); ASSERT(r == 0);
exepath[exepath_size] = '\0'; exepath[exepath_size] = '\0';
args[0] = exepath; args[0] = exepath;
args[1] = (char*)helper; args[1] = (char*)helper;
args[2] = NULL; args[2] = NULL;
memset(&options, 0, sizeof(options));
options.file = exepath; options.file = exepath;
options.args = args; options.args = args;
options.exit_cb = exit_cb; options.exit_cb = exit_cb;
options.stdin_stream = &channel; options.stdin_stream = channel;
r = uv_spawn(uv_default_loop(), &process, options); r = uv_spawn(uv_default_loop(), process, options);
ASSERT(r == 0); ASSERT(r == 0);
}
static int run_ipc_test(const char* helper) {
uv_process_t process;
int r;
spawn_helper(&channel, &process, helper);
uv_read2_start((uv_stream_t*)&channel, on_alloc, on_read); uv_read2_start((uv_stream_t*)&channel, on_alloc, on_read);
r = uv_run(uv_default_loop()); r = uv_run(uv_default_loop());
@ -218,6 +228,7 @@ int run_ipc_test(const char* helper) {
ASSERT(remote_conn_accepted == 1); ASSERT(remote_conn_accepted == 1);
ASSERT(read2_cb_called == 1); ASSERT(read2_cb_called == 1);
ASSERT(exit_cb_called == 1); ASSERT(exit_cb_called == 1);
return 0; return 0;
} }

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

@ -24,6 +24,8 @@ TEST_DECLARE (tty)
TEST_DECLARE (stdio_over_pipes) TEST_DECLARE (stdio_over_pipes)
TEST_DECLARE (ipc_listen_before_write) TEST_DECLARE (ipc_listen_before_write)
TEST_DECLARE (ipc_listen_after_write) TEST_DECLARE (ipc_listen_after_write)
TEST_DECLARE (ipc_send_recv_pipe)
TEST_DECLARE (ipc_send_recv_tcp)
TEST_DECLARE (tcp_ping_pong) TEST_DECLARE (tcp_ping_pong)
TEST_DECLARE (tcp_ping_pong_v6) TEST_DECLARE (tcp_ping_pong_v6)
TEST_DECLARE (pipe_ping_pong) TEST_DECLARE (pipe_ping_pong)
@ -61,6 +63,8 @@ TEST_DECLARE (pipe_connect_bad_name)
TEST_DECLARE (pipe_connect_to_file) TEST_DECLARE (pipe_connect_to_file)
TEST_DECLARE (connection_fail) TEST_DECLARE (connection_fail)
TEST_DECLARE (connection_fail_doesnt_auto_close) TEST_DECLARE (connection_fail_doesnt_auto_close)
TEST_DECLARE (shutdown_close_tcp)
TEST_DECLARE (shutdown_close_pipe)
TEST_DECLARE (shutdown_eof) TEST_DECLARE (shutdown_eof)
TEST_DECLARE (callback_stack) TEST_DECLARE (callback_stack)
TEST_DECLARE (error_message) TEST_DECLARE (error_message)
@ -81,12 +85,16 @@ TEST_DECLARE (fs_event_ref)
TEST_DECLARE (tcp_ref) TEST_DECLARE (tcp_ref)
TEST_DECLARE (tcp_ref2) TEST_DECLARE (tcp_ref2)
TEST_DECLARE (tcp_ref3) TEST_DECLARE (tcp_ref3)
TEST_DECLARE (tcp_ref4)
TEST_DECLARE (tcp_ref5)
TEST_DECLARE (udp_ref) TEST_DECLARE (udp_ref)
TEST_DECLARE (udp_ref2) TEST_DECLARE (udp_ref2)
TEST_DECLARE (udp_ref3) TEST_DECLARE (udp_ref3)
TEST_DECLARE (pipe_ref) TEST_DECLARE (pipe_ref)
TEST_DECLARE (pipe_ref2) TEST_DECLARE (pipe_ref2)
TEST_DECLARE (pipe_ref3) TEST_DECLARE (pipe_ref3)
TEST_DECLARE (pipe_ref4)
TEST_DECLARE (pipe_ref5)
TEST_DECLARE (process_ref) TEST_DECLARE (process_ref)
TEST_DECLARE (async) TEST_DECLARE (async)
TEST_DECLARE (get_currentexe) TEST_DECLARE (get_currentexe)
@ -124,6 +132,7 @@ TEST_DECLARE (fs_utime)
TEST_DECLARE (fs_futime) TEST_DECLARE (fs_futime)
TEST_DECLARE (fs_file_open_append) TEST_DECLARE (fs_file_open_append)
TEST_DECLARE (fs_stat_missing_path) TEST_DECLARE (fs_stat_missing_path)
TEST_DECLARE (fs_read_file_eof)
TEST_DECLARE (fs_event_watch_dir) TEST_DECLARE (fs_event_watch_dir)
TEST_DECLARE (fs_event_watch_file) TEST_DECLARE (fs_event_watch_file)
TEST_DECLARE (fs_event_watch_file_current_dir) TEST_DECLARE (fs_event_watch_file_current_dir)
@ -167,6 +176,8 @@ TASK_LIST_START
TEST_ENTRY (stdio_over_pipes) TEST_ENTRY (stdio_over_pipes)
TEST_ENTRY (ipc_listen_before_write) TEST_ENTRY (ipc_listen_before_write)
TEST_ENTRY (ipc_listen_after_write) TEST_ENTRY (ipc_listen_after_write)
TEST_ENTRY (ipc_send_recv_pipe)
TEST_ENTRY (ipc_send_recv_tcp)
TEST_ENTRY (tcp_ping_pong) TEST_ENTRY (tcp_ping_pong)
TEST_HELPER (tcp_ping_pong, tcp4_echo_server) TEST_HELPER (tcp_ping_pong, tcp4_echo_server)
@ -217,6 +228,11 @@ TASK_LIST_START
TEST_ENTRY (connection_fail) TEST_ENTRY (connection_fail)
TEST_ENTRY (connection_fail_doesnt_auto_close) TEST_ENTRY (connection_fail_doesnt_auto_close)
TEST_ENTRY (shutdown_close_tcp)
TEST_HELPER (shutdown_close_tcp, tcp4_echo_server)
TEST_ENTRY (shutdown_close_pipe)
TEST_HELPER (shutdown_close_pipe, pipe_echo_server)
TEST_ENTRY (shutdown_eof) TEST_ENTRY (shutdown_eof)
TEST_HELPER (shutdown_eof, tcp4_echo_server) TEST_HELPER (shutdown_eof, tcp4_echo_server)
@ -243,6 +259,10 @@ TASK_LIST_START
TEST_ENTRY (tcp_ref2) TEST_ENTRY (tcp_ref2)
TEST_ENTRY (tcp_ref3) TEST_ENTRY (tcp_ref3)
TEST_HELPER (tcp_ref3, tcp4_echo_server) TEST_HELPER (tcp_ref3, tcp4_echo_server)
TEST_ENTRY (tcp_ref4)
TEST_HELPER (tcp_ref4, tcp4_echo_server)
TEST_ENTRY (tcp_ref5)
TEST_HELPER (tcp_ref5, tcp4_echo_server)
TEST_ENTRY (udp_ref) TEST_ENTRY (udp_ref)
TEST_ENTRY (udp_ref2) TEST_ENTRY (udp_ref2)
TEST_ENTRY (udp_ref3) TEST_ENTRY (udp_ref3)
@ -251,6 +271,10 @@ TASK_LIST_START
TEST_ENTRY (pipe_ref2) TEST_ENTRY (pipe_ref2)
TEST_ENTRY (pipe_ref3) TEST_ENTRY (pipe_ref3)
TEST_HELPER (pipe_ref3, pipe_echo_server) TEST_HELPER (pipe_ref3, pipe_echo_server)
TEST_ENTRY (pipe_ref4)
TEST_HELPER (pipe_ref4, pipe_echo_server)
TEST_ENTRY (pipe_ref5)
TEST_HELPER (pipe_ref5, pipe_echo_server)
TEST_ENTRY (process_ref) TEST_ENTRY (process_ref)
TEST_ENTRY (loop_handles) TEST_ENTRY (loop_handles)
@ -308,6 +332,7 @@ TASK_LIST_START
TEST_ENTRY (fs_futime) TEST_ENTRY (fs_futime)
TEST_ENTRY (fs_symlink) TEST_ENTRY (fs_symlink)
TEST_ENTRY (fs_stat_missing_path) TEST_ENTRY (fs_stat_missing_path)
TEST_ENTRY (fs_read_file_eof)
TEST_ENTRY (fs_file_open_append) TEST_ENTRY (fs_file_open_append)
TEST_ENTRY (fs_event_watch_dir) TEST_ENTRY (fs_event_watch_dir)
TEST_ENTRY (fs_event_watch_file) TEST_ENTRY (fs_event_watch_file)

76
deps/uv/test/test-ref.c

@ -26,11 +26,39 @@
#include <string.h> #include <string.h>
static uv_write_t write_req;
static uv_shutdown_t shutdown_req;
static uv_connect_t connect_req;
static char buffer[32767];
static void fail_cb(void) { static void fail_cb(void) {
FATAL("fail_cb should not have been called"); FATAL("fail_cb should not have been called");
} }
static void write_unref_cb(uv_connect_t* req, int status) {
uv_buf_t buf = uv_buf_init(buffer, sizeof buffer);
ASSERT(req == &connect_req);
ASSERT(status == 0);
uv_write(&write_req, req->handle, &buf, 1, (uv_write_cb) fail_cb);
uv_unref(uv_default_loop()); /* uv_write refs the loop */
}
static void shutdown_unref_cb(uv_connect_t* req, int status) {
ASSERT(req == &connect_req);
ASSERT(status == 0);
uv_shutdown(&shutdown_req, req->handle, (uv_shutdown_cb) fail_cb);
uv_unref(uv_default_loop()); /* uv_shutdown refs the loop */
}
TEST_IMPL(ref) { TEST_IMPL(ref) {
uv_run(uv_default_loop()); uv_run(uv_default_loop());
return 0; return 0;
@ -142,10 +170,9 @@ TEST_IMPL(tcp_ref2) {
TEST_IMPL(tcp_ref3) { TEST_IMPL(tcp_ref3) {
struct sockaddr_in addr = uv_ip4_addr("127.0.0.1", TEST_PORT); struct sockaddr_in addr = uv_ip4_addr("127.0.0.1", TEST_PORT);
uv_connect_t req;
uv_tcp_t h; uv_tcp_t h;
uv_tcp_init(uv_default_loop(), &h); uv_tcp_init(uv_default_loop(), &h);
uv_tcp_connect(&req, &h, addr, (uv_connect_cb)fail_cb); uv_tcp_connect(&connect_req, &h, addr, (uv_connect_cb)fail_cb);
uv_unref(uv_default_loop()); uv_unref(uv_default_loop());
uv_unref(uv_default_loop()); /* connect req refs the loop */ uv_unref(uv_default_loop()); /* connect req refs the loop */
uv_run(uv_default_loop()); uv_run(uv_default_loop());
@ -153,6 +180,28 @@ TEST_IMPL(tcp_ref3) {
} }
TEST_IMPL(tcp_ref4) {
struct sockaddr_in addr = uv_ip4_addr("127.0.0.1", TEST_PORT);
uv_tcp_t h;
uv_tcp_init(uv_default_loop(), &h);
uv_tcp_connect(&connect_req, &h, addr, write_unref_cb);
uv_unref(uv_default_loop());
uv_run(uv_default_loop());
return 0;
}
TEST_IMPL(tcp_ref5) {
struct sockaddr_in addr = uv_ip4_addr("127.0.0.1", TEST_PORT);
uv_tcp_t h;
uv_tcp_init(uv_default_loop(), &h);
uv_tcp_connect(&connect_req, &h, addr, shutdown_unref_cb);
uv_unref(uv_default_loop());
uv_run(uv_default_loop());
return 0;
}
TEST_IMPL(udp_ref) { TEST_IMPL(udp_ref) {
uv_udp_t h; uv_udp_t h;
uv_udp_init(uv_default_loop(), &h); uv_udp_init(uv_default_loop(), &h);
@ -210,10 +259,9 @@ TEST_IMPL(pipe_ref2) {
TEST_IMPL(pipe_ref3) { TEST_IMPL(pipe_ref3) {
uv_connect_t req;
uv_pipe_t h; uv_pipe_t h;
uv_pipe_init(uv_default_loop(), &h, 0); uv_pipe_init(uv_default_loop(), &h, 0);
uv_pipe_connect(&req, &h, TEST_PIPENAME, (uv_connect_cb)fail_cb); uv_pipe_connect(&connect_req, &h, TEST_PIPENAME, (uv_connect_cb)fail_cb);
uv_unref(uv_default_loop()); uv_unref(uv_default_loop());
uv_unref(uv_default_loop()); /* connect req refs the loop */ uv_unref(uv_default_loop()); /* connect req refs the loop */
uv_run(uv_default_loop()); uv_run(uv_default_loop());
@ -221,6 +269,26 @@ TEST_IMPL(pipe_ref3) {
} }
TEST_IMPL(pipe_ref4) {
uv_pipe_t h;
uv_pipe_init(uv_default_loop(), &h, 0);
uv_pipe_connect(&connect_req, &h, TEST_PIPENAME, write_unref_cb);
uv_unref(uv_default_loop());
uv_run(uv_default_loop());
return 0;
}
TEST_IMPL(pipe_ref5) {
uv_pipe_t h;
uv_pipe_init(uv_default_loop(), &h, 0);
uv_pipe_connect(&connect_req, &h, TEST_PIPENAME, shutdown_unref_cb);
uv_unref(uv_default_loop());
uv_run(uv_default_loop());
return 0;
}
TEST_IMPL(process_ref) { TEST_IMPL(process_ref) {
/* spawn_helper4 blocks indefinitely. */ /* spawn_helper4 blocks indefinitely. */
char *argv[] = { NULL, "spawn_helper4", NULL }; char *argv[] = { NULL, "spawn_helper4", NULL };

101
deps/uv/test/test-shutdown-close.c

@ -0,0 +1,101 @@
/* 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.
*/
/*
* These tests verify that the uv_shutdown callback is always made, even when
* it is immediately followed by an uv_close call.
*/
#include "uv.h"
#include "task.h"
static uv_shutdown_t shutdown_req;
static uv_connect_t connect_req;
static int connect_cb_called = 0;
static int shutdown_cb_called = 0;
static int close_cb_called = 0;
static void shutdown_cb(uv_shutdown_t* req, int status) {
ASSERT(req == &shutdown_req);
ASSERT(status == 0 ||
(status == -1 && uv_last_error(uv_default_loop()).code == UV_EINTR));
shutdown_cb_called++;
}
static void close_cb(uv_handle_t* handle) {
close_cb_called++;
}
static void connect_cb(uv_connect_t* req, int status) {
int r;
ASSERT(req == &connect_req);
ASSERT(status == 0);
r = uv_shutdown(&shutdown_req, req->handle, shutdown_cb);
ASSERT(r == 0);
uv_close((uv_handle_t*) req->handle, close_cb);
connect_cb_called++;
}
TEST_IMPL(shutdown_close_tcp) {
struct sockaddr_in addr = uv_ip4_addr("127.0.0.1", TEST_PORT);
uv_tcp_t h;
int r;
r = uv_tcp_init(uv_default_loop(), &h);
ASSERT(r == 0);
r = uv_tcp_connect(&connect_req, &h, addr, connect_cb);
ASSERT(r == 0);
r = uv_run(uv_default_loop());
ASSERT(r == 0);
ASSERT(connect_cb_called == 1);
ASSERT(shutdown_cb_called == 1);
ASSERT(close_cb_called == 1);
return 0;
}
TEST_IMPL(shutdown_close_pipe) {
uv_pipe_t h;
int r;
r = uv_pipe_init(uv_default_loop(), &h, 0);
ASSERT(r == 0);
uv_pipe_connect(&connect_req, &h, TEST_PIPENAME, connect_cb);
r = uv_run(uv_default_loop());
ASSERT(r == 0);
ASSERT(connect_cb_called == 1);
ASSERT(shutdown_cb_called == 1);
ASSERT(close_cb_called == 1);
return 0;
}

64
deps/uv/test/test-tty.c

@ -22,23 +22,64 @@
#include "uv.h" #include "uv.h"
#include "task.h" #include "task.h"
#ifdef _WIN32
# include <io.h>
# include <windows.h>
#else /* Unix */
# include <fcntl.h>
# include <unistd.h>
#endif
TEST_IMPL(tty) { TEST_IMPL(tty) {
int r, width, height; int r, width, height;
uv_tty_t tty; int ttyin_fd, ttyout_fd;
uv_tty_t tty_in, tty_out;
uv_loop_t* loop = uv_default_loop(); uv_loop_t* loop = uv_default_loop();
/* Make sure we have an FD that refers to a tty */
#ifdef _WIN32
HANDLE handle;
handle = CreateFileA("conin$",
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
ASSERT(handle != INVALID_HANDLE_VALUE);
ttyin_fd = _open_osfhandle((intptr_t) handle, 0);
handle = CreateFileA("conout$",
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
ASSERT(handle != INVALID_HANDLE_VALUE);
ttyout_fd = _open_osfhandle((intptr_t) handle, 0);
#else /* unix */
ttyin_fd = open("/dev/tty", O_RDONLY, 0);
ttyout_fd = open("/dev/tty", O_WRONLY, 0);
#endif
ASSERT(ttyin_fd >= 0);
ASSERT(ttyout_fd >= 0);
ASSERT(UV_UNKNOWN_HANDLE == uv_guess_handle(-1)); ASSERT(UV_UNKNOWN_HANDLE == uv_guess_handle(-1));
/* ASSERT(UV_TTY == uv_guess_handle(ttyin_fd));
* Not necessarily a problem if this assert goes off. E.G you are piping ASSERT(UV_TTY == uv_guess_handle(ttyout_fd));
* this test to a file. 0 == stdin.
*/ r = uv_tty_init(uv_default_loop(), &tty_in, ttyin_fd, 1);
ASSERT(UV_TTY == uv_guess_handle(0)); ASSERT(r == 0);
r = uv_tty_init(uv_default_loop(), &tty, 0, 1); r = uv_tty_init(uv_default_loop(), &tty_out, ttyout_fd, 2);
ASSERT(r == 0); ASSERT(r == 0);
r = uv_tty_get_winsize(&tty, &width, &height); r = uv_tty_get_winsize(&tty_out, &width, &height);
ASSERT(r == 0); ASSERT(r == 0);
printf("width=%d height=%d\n", width, height); printf("width=%d height=%d\n", width, height);
@ -51,16 +92,17 @@ TEST_IMPL(tty) {
ASSERT(height > 10); ASSERT(height > 10);
/* Turn on raw mode. */ /* Turn on raw mode. */
r = uv_tty_set_mode(&tty, 1); r = uv_tty_set_mode(&tty_in, 1);
ASSERT(r == 0); ASSERT(r == 0);
/* Turn off raw mode. */ /* Turn off raw mode. */
r = uv_tty_set_mode(&tty, 0); r = uv_tty_set_mode(&tty_in, 0);
ASSERT(r == 0); ASSERT(r == 0);
/* TODO check the actual mode! */ /* TODO check the actual mode! */
uv_close((uv_handle_t*)&tty, NULL); uv_close((uv_handle_t*) &tty_in, NULL);
uv_close((uv_handle_t*) &tty_out, NULL);
uv_run(loop); uv_run(loop);

2
deps/uv/uv.gyp

@ -309,6 +309,7 @@
'test/test-hrtime.c', 'test/test-hrtime.c',
'test/test-idle.c', 'test/test-idle.c',
'test/test-ipc.c', 'test/test-ipc.c',
'test/test-ipc-send-recv.c',
'test/test-list.h', 'test/test-list.h',
'test/test-loop-handles.c', 'test/test-loop-handles.c',
'test/test-multiple-listen.c', 'test/test-multiple-listen.c',
@ -319,6 +320,7 @@
'test/test-platform-output.c', 'test/test-platform-output.c',
'test/test-process-title.c', 'test/test-process-title.c',
'test/test-ref.c', 'test/test-ref.c',
'test/test-shutdown-close.c',
'test/test-shutdown-eof.c', 'test/test-shutdown-eof.c',
'test/test-spawn.c', 'test/test-spawn.c',
'test/test-stdio-over-pipes.c', 'test/test-stdio-over-pipes.c',

Loading…
Cancel
Save