Browse Source

upgrade libuv to 6e50576

v0.7.4-release
Ryan Dahl 14 years ago
parent
commit
133036fdad
  1. 2
      deps/uv/include/uv-win.h
  2. 2
      deps/uv/include/uv.h
  3. 1
      deps/uv/msvs/libuv-test.vcxproj
  4. 5
      deps/uv/src/uv-unix.c
  5. 34
      deps/uv/src/win/core.c
  6. 6
      deps/uv/src/win/error.c
  7. 25
      deps/uv/src/win/handle.c
  8. 1
      deps/uv/src/win/internal.h
  9. 170
      deps/uv/src/win/pipe.c
  10. 5
      deps/uv/test/test-async.c
  11. 9
      deps/uv/test/test-callback-stack.c
  12. 9
      deps/uv/test/test-delayed-accept.c
  13. 83
      deps/uv/test/test-idle.c
  14. 4
      deps/uv/test/test-list.h
  15. 20
      deps/uv/test/test-loop-handles.c
  16. 11
      src/handle_wrap.cc

2
deps/uv/include/uv-win.h

@ -103,7 +103,7 @@ typedef struct uv_buf_t {
HANDLE handle; HANDLE handle;
#define UV_PIPE_PRIVATE_FIELDS \ #define UV_PIPE_PRIVATE_FIELDS \
char* name; \ wchar_t* name; \
union { \ union { \
struct { uv_pipe_server_fields }; \ struct { uv_pipe_server_fields }; \
struct { uv_pipe_connection_fields }; \ struct { uv_pipe_connection_fields }; \

2
deps/uv/include/uv.h

@ -229,7 +229,7 @@ int uv_is_active(uv_handle_t* handle);
* Request handle to be closed. close_cb will be called asynchronously after * Request handle to be closed. close_cb will be called asynchronously after
* this call. This MUST be called on each handle before memory is released. * this call. This MUST be called on each handle before memory is released.
*/ */
int uv_close(uv_handle_t* handle, uv_close_cb close_cb); void uv_close(uv_handle_t* handle, uv_close_cb close_cb);
#define UV_STREAM_FIELDS \ #define UV_STREAM_FIELDS \

1
deps/uv/msvs/libuv-test.vcxproj

@ -153,6 +153,7 @@
<ClCompile Include="..\test\test-getaddrinfo.c" /> <ClCompile Include="..\test\test-getaddrinfo.c" />
<ClCompile Include="..\test\test-getsockname.c" /> <ClCompile Include="..\test\test-getsockname.c" />
<ClCompile Include="..\test\test-hrtime.c" /> <ClCompile Include="..\test\test-hrtime.c" />
<ClCompile Include="..\test\test-idle.c" />
<ClCompile Include="..\test\test-loop-handles.c" /> <ClCompile Include="..\test\test-loop-handles.c" />
<ClCompile Include="..\test\test-pass-always.c" /> <ClCompile Include="..\test\test-pass-always.c" />
<ClCompile Include="..\test\test-ping-pong.c" /> <ClCompile Include="..\test\test-ping-pong.c" />

5
deps/uv/src/uv-unix.c

@ -186,7 +186,7 @@ static uv_err_t uv_err_new(uv_handle_t* handle, int sys_error) {
} }
int uv_close(uv_handle_t* handle, uv_close_cb close_cb) { void uv_close(uv_handle_t* handle, uv_close_cb close_cb) {
uv_tcp_t* tcp; uv_tcp_t* tcp;
uv_pipe_t* pipe; uv_pipe_t* pipe;
uv_async_t* async; uv_async_t* async;
@ -245,7 +245,6 @@ int uv_close(uv_handle_t* handle, uv_close_cb close_cb) {
default: default:
assert(0); assert(0);
return -1;
} }
uv_flag_set(handle, UV_CLOSING); uv_flag_set(handle, UV_CLOSING);
@ -254,8 +253,6 @@ int uv_close(uv_handle_t* handle, uv_close_cb close_cb) {
ev_idle_start(EV_DEFAULT_ &handle->next_watcher); ev_idle_start(EV_DEFAULT_ &handle->next_watcher);
ev_feed_event(EV_DEFAULT_ &handle->next_watcher, EV_IDLE); ev_feed_event(EV_DEFAULT_ &handle->next_watcher, EV_IDLE);
assert(ev_is_pending(&handle->next_watcher)); assert(ev_is_pending(&handle->next_watcher));
return 0;
} }

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

@ -85,20 +85,24 @@ void uv_unref() {
} }
static void uv_poll() { static void uv_poll(int block) {
BOOL success; BOOL success;
DWORD bytes; DWORD bytes, timeout;
ULONG_PTR key; ULONG_PTR key;
OVERLAPPED* overlapped; OVERLAPPED* overlapped;
uv_req_t* req; uv_req_t* req;
if (block) {
timeout = uv_get_poll_timeout();
} else {
timeout = 0;
}
success = GetQueuedCompletionStatus(LOOP->iocp, success = GetQueuedCompletionStatus(LOOP->iocp,
&bytes, &bytes,
&key, &key,
&overlapped, &overlapped,
uv_get_poll_timeout()); timeout);
uv_update_time();
if (overlapped) { if (overlapped) {
/* Package was dequeued */ /* Package was dequeued */
@ -118,30 +122,30 @@ static void uv_poll() {
int uv_run() { int uv_run() {
while (1) { while (LOOP->refs > 0) {
uv_update_time(); uv_update_time();
uv_process_timers(); uv_process_timers();
/* Terrible: please fix me! */ /* Call idle callbacks if nothing to do. */
while (LOOP->refs > 0 && if (LOOP->pending_reqs_tail == NULL && LOOP->endgame_handles == NULL) {
(LOOP->idle_handles || LOOP->pending_reqs_tail || LOOP->endgame_handles)) { uv_idle_invoke();
/* Terrible: please fix me! */ }
/* Completely flush all pending reqs and endgames. */
/* We do even when we just called the idle callbacks because those may */
/* have closed handles or started requests that short-circuited. */
while (LOOP->pending_reqs_tail || LOOP->endgame_handles) { while (LOOP->pending_reqs_tail || LOOP->endgame_handles) {
uv_process_endgames(); uv_process_endgames();
uv_process_reqs(); uv_process_reqs();
} }
/* Call idle callbacks */
uv_idle_invoke();
}
if (LOOP->refs <= 0) { if (LOOP->refs <= 0) {
break; break;
} }
uv_prepare_invoke(); uv_prepare_invoke();
uv_poll(); uv_poll(LOOP->idle_handles == NULL);
uv_check_invoke(); uv_check_invoke();
} }

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

@ -132,3 +132,9 @@ void uv_set_sys_error(int sys_errno) {
LOOP->last_error.code = uv_translate_sys_error(sys_errno); LOOP->last_error.code = uv_translate_sys_error(sys_errno);
LOOP->last_error.sys_errno_ = sys_errno; LOOP->last_error.sys_errno_ = sys_errno;
} }
void uv_set_error(uv_err_code code, int sys_errno) {
LOOP->last_error.code = code;
LOOP->last_error.sys_errno_ = sys_errno;
}

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

@ -40,12 +40,12 @@ int uv_is_active(uv_handle_t* handle) {
/* TODO: integrate this with uv_close. */ /* TODO: integrate this with uv_close. */
static int uv_close_error(uv_handle_t* handle, uv_err_t e) { static void uv_close_error(uv_handle_t* handle, uv_err_t e) {
uv_tcp_t* tcp; uv_tcp_t* tcp;
uv_pipe_t* pipe; uv_pipe_t* pipe;
if (handle->flags & UV_HANDLE_CLOSING) { if (handle->flags & UV_HANDLE_CLOSING) {
return 0; return;
} }
handle->error = e; handle->error = e;
@ -66,7 +66,7 @@ static int uv_close_error(uv_handle_t* handle, uv_err_t e) {
if (tcp->reqs_pending == 0) { if (tcp->reqs_pending == 0) {
uv_want_endgame(handle); uv_want_endgame(handle);
} }
return 0; return;
case UV_NAMED_PIPE: case UV_NAMED_PIPE:
pipe = (uv_pipe_t*)handle; pipe = (uv_pipe_t*)handle;
@ -75,45 +75,44 @@ static int uv_close_error(uv_handle_t* handle, uv_err_t e) {
if (pipe->reqs_pending == 0) { if (pipe->reqs_pending == 0) {
uv_want_endgame(handle); uv_want_endgame(handle);
} }
return 0; return;
case UV_TIMER: case UV_TIMER:
uv_timer_stop((uv_timer_t*)handle); uv_timer_stop((uv_timer_t*)handle);
uv_want_endgame(handle); uv_want_endgame(handle);
return 0; return;
case UV_PREPARE: case UV_PREPARE:
uv_prepare_stop((uv_prepare_t*)handle); uv_prepare_stop((uv_prepare_t*)handle);
uv_want_endgame(handle); uv_want_endgame(handle);
return 0; return;
case UV_CHECK: case UV_CHECK:
uv_check_stop((uv_check_t*)handle); uv_check_stop((uv_check_t*)handle);
uv_want_endgame(handle); uv_want_endgame(handle);
return 0; return;
case UV_IDLE: case UV_IDLE:
uv_idle_stop((uv_idle_t*)handle); uv_idle_stop((uv_idle_t*)handle);
uv_want_endgame(handle); uv_want_endgame(handle);
return 0; return;
case UV_ASYNC: case UV_ASYNC:
if (!((uv_async_t*)handle)->async_sent) { if (!((uv_async_t*)handle)->async_sent) {
uv_want_endgame(handle); uv_want_endgame(handle);
} }
return 0; return;
default: default:
/* Not supported */ /* Not supported */
assert(0); abort();
return -1;
} }
} }
int uv_close(uv_handle_t* handle, uv_close_cb close_cb) { void uv_close(uv_handle_t* handle, uv_close_cb close_cb) {
handle->close_cb = close_cb; handle->close_cb = close_cb;
return uv_close_error(handle, uv_ok_); uv_close_error(handle, uv_ok_);
} }

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

@ -215,6 +215,7 @@ void uv_fatal_error(const int errorno, const char* syscall);
uv_err_code uv_translate_sys_error(int sys_errno); uv_err_code uv_translate_sys_error(int sys_errno);
uv_err_t uv_new_sys_error(int sys_errno); uv_err_t uv_new_sys_error(int sys_errno);
void uv_set_sys_error(int sys_errno); void uv_set_sys_error(int sys_errno);
void uv_set_error(uv_err_code code, int sys_errno);
#endif /* UV_WIN_INTERNAL_H_ */ #endif /* UV_WIN_INTERNAL_H_ */

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

@ -38,6 +38,7 @@ int uv_pipe_init(uv_pipe_t* handle) {
handle->reqs_pending = 0; handle->reqs_pending = 0;
handle->pending_accepts = NULL; handle->pending_accepts = NULL;
handle->name = NULL; handle->name = NULL;
handle->handle = INVALID_HANDLE_VALUE;
uv_counters()->pipe_init++; uv_counters()->pipe_init++;
@ -96,20 +97,18 @@ void uv_pipe_endgame(uv_pipe_t* handle) {
/* Creates a pipe server. */ /* Creates a pipe server. */
/* TODO: make this work with UTF8 name */
int uv_pipe_bind(uv_pipe_t* handle, const char* name) { int uv_pipe_bind(uv_pipe_t* handle, const char* name) {
int i; int i, errno, nameSize;
uv_pipe_accept_t* req; uv_pipe_accept_t* req;
if (!name) { if (handle->flags & UV_HANDLE_BOUND) {
uv_set_sys_error(WSAEINVAL); uv_set_sys_error(WSAEINVAL);
return -1; return -1;
} }
/* Make our own copy of the pipe name */ if (!name) {
handle->name = _strdup(name); uv_set_sys_error(WSAEINVAL);
if (!handle->name) { return -1;
uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
} }
for (i = 0; i < COUNTOF(handle->accept_reqs); i++) { for (i = 0; i < COUNTOF(handle->accept_reqs); i++) {
@ -121,8 +120,67 @@ int uv_pipe_bind(uv_pipe_t* handle, const char* name) {
req->next_pending = NULL; req->next_pending = NULL;
} }
/* Convert name to UTF16. */
nameSize = uv_utf8_to_utf16(name, NULL, 0) * sizeof(wchar_t);
handle->name = (wchar_t*)malloc(nameSize);
if (!handle->name) {
uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
}
if (!uv_utf8_to_utf16(name, handle->name, nameSize / sizeof(wchar_t))) {
uv_set_sys_error(GetLastError());
return -1;
}
/*
* Attempt to create the first pipe with FILE_FLAG_FIRST_PIPE_INSTANCE.
* If this fails then there's already a pipe server for the given pipe name.
*/
handle->accept_reqs[0].pipeHandle = CreateNamedPipeW(handle->name,
PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED | FILE_FLAG_FIRST_PIPE_INSTANCE,
PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT,
PIPE_UNLIMITED_INSTANCES,
65536,
65536,
0,
NULL);
if (handle->accept_reqs[0].pipeHandle == INVALID_HANDLE_VALUE) {
errno = GetLastError();
if (errno == ERROR_ACCESS_DENIED) {
uv_set_error(UV_EADDRINUSE, errno);
handle->error = LOOP->last_error;
handle->flags |= UV_HANDLE_BIND_ERROR;
} else if (errno == ERROR_PATH_NOT_FOUND || errno == ERROR_INVALID_NAME) {
uv_set_error(UV_EADDRNOTAVAIL, errno);
} else {
uv_set_sys_error(errno);
}
goto error;
}
if (uv_set_pipe_handle(handle, handle->accept_reqs[0].pipeHandle)) {
uv_set_sys_error(GetLastError());
goto error;
}
handle->flags |= UV_HANDLE_PIPESERVER; handle->flags |= UV_HANDLE_PIPESERVER;
handle->flags |= UV_HANDLE_BOUND;
return 0; return 0;
error:
if (handle->name) {
free(handle->name);
handle->name = NULL;
}
if (handle->accept_reqs[0].pipeHandle != INVALID_HANDLE_VALUE) {
CloseHandle(handle->accept_reqs[0].pipeHandle);
handle->accept_reqs[0].pipeHandle = INVALID_HANDLE_VALUE;
}
return -1;
} }
@ -138,9 +196,9 @@ static DWORD WINAPI pipe_connect_thread_proc(void* parameter) {
assert(handle); assert(handle);
/* We're here because CreateFile on a pipe returned ERROR_PIPE_BUSY. We wait for the pipe to become available with WaitNamedPipe. */ /* We're here because CreateFile on a pipe returned ERROR_PIPE_BUSY. We wait for the pipe to become available with WaitNamedPipe. */
while (WaitNamedPipe(handle->name, 30000)) { while (WaitNamedPipeW(handle->name, 30000)) {
/* The pipe is now available, try to connect. */ /* The pipe is now available, try to connect. */
pipeHandle = CreateFile(handle->name, pipeHandle = CreateFileW(handle->name,
GENERIC_READ | GENERIC_WRITE, GENERIC_READ | GENERIC_WRITE,
0, 0,
NULL, NULL,
@ -174,10 +232,9 @@ static DWORD WINAPI pipe_connect_thread_proc(void* parameter) {
} }
/* TODO: make this work with UTF8 name */
int uv_pipe_connect(uv_connect_t* req, uv_pipe_t* handle, int 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) {
int errno; int errno, nameSize;
HANDLE pipeHandle; HANDLE pipeHandle;
handle->handle = INVALID_HANDLE_VALUE; handle->handle = INVALID_HANDLE_VALUE;
@ -187,7 +244,19 @@ int uv_pipe_connect(uv_connect_t* req, uv_pipe_t* handle,
req->handle = (uv_stream_t*) handle; req->handle = (uv_stream_t*) handle;
req->cb = cb; req->cb = cb;
pipeHandle = CreateFile(name, /* Convert name to UTF16. */
nameSize = uv_utf8_to_utf16(name, NULL, 0) * sizeof(wchar_t);
handle->name = (wchar_t*)malloc(nameSize);
if (!handle->name) {
uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
}
if (!uv_utf8_to_utf16(name, handle->name, nameSize / sizeof(wchar_t))) {
errno = GetLastError();
goto error;
}
pipeHandle = CreateFileW(handle->name,
GENERIC_READ | GENERIC_WRITE, GENERIC_READ | GENERIC_WRITE,
0, 0,
NULL, NULL,
@ -198,11 +267,6 @@ int uv_pipe_connect(uv_connect_t* req, uv_pipe_t* handle,
if (pipeHandle == INVALID_HANDLE_VALUE) { 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. */
handle->name = _strdup(name);
if (!handle->name) {
uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
}
if (!QueueUserWorkItem(&pipe_connect_thread_proc, req, WT_EXECUTELONGFUNCTION)) { if (!QueueUserWorkItem(&pipe_connect_thread_proc, req, WT_EXECUTELONGFUNCTION)) {
errno = GetLastError(); errno = GetLastError();
goto error; goto error;
@ -228,6 +292,11 @@ int uv_pipe_connect(uv_connect_t* req, uv_pipe_t* handle,
return 0; return 0;
error: error:
if (handle->name) {
free(handle->name);
handle->name = NULL;
}
if (pipeHandle != INVALID_HANDLE_VALUE) { if (pipeHandle != INVALID_HANDLE_VALUE) {
CloseHandle(pipeHandle); CloseHandle(pipeHandle);
} }
@ -243,7 +312,7 @@ void close_pipe(uv_pipe_t* handle, int* status, uv_err_t* err) {
if (handle->name) { if (handle->name) {
free(handle->name); free(handle->name);
handle->name; handle->name = NULL;
} }
if (handle->flags & UV_HANDLE_PIPESERVER) { if (handle->flags & UV_HANDLE_PIPESERVER) {
@ -251,24 +320,26 @@ void close_pipe(uv_pipe_t* handle, int* status, uv_err_t* err) {
pipeHandle = handle->accept_reqs[i].pipeHandle; pipeHandle = handle->accept_reqs[i].pipeHandle;
if (pipeHandle != INVALID_HANDLE_VALUE) { if (pipeHandle != INVALID_HANDLE_VALUE) {
CloseHandle(pipeHandle); CloseHandle(pipeHandle);
handle->accept_reqs[i].pipeHandle = INVALID_HANDLE_VALUE;
} }
} }
} else if (handle->handle != INVALID_HANDLE_VALUE) { } else if (handle->handle != INVALID_HANDLE_VALUE) {
CloseHandle(handle->handle); CloseHandle(handle->handle);
handle->handle = INVALID_HANDLE_VALUE;
} }
handle->flags |= UV_HANDLE_SHUT; handle->flags |= UV_HANDLE_SHUT;
} }
static void uv_pipe_queue_accept(uv_pipe_t* handle, uv_pipe_accept_t* req) { static void uv_pipe_queue_accept(uv_pipe_t* handle, uv_pipe_accept_t* req, BOOL firstInstance) {
HANDLE pipeHandle;
assert(handle->flags & UV_HANDLE_LISTENING); assert(handle->flags & UV_HANDLE_LISTENING);
if (!firstInstance) {
assert(req->pipeHandle == INVALID_HANDLE_VALUE); assert(req->pipeHandle == INVALID_HANDLE_VALUE);
pipeHandle = CreateNamedPipe(handle->name, req->pipeHandle = CreateNamedPipeW(handle->name,
PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,
PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT, PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT,
PIPE_UNLIMITED_INSTANCES, PIPE_UNLIMITED_INSTANCES,
@ -277,31 +348,34 @@ static void uv_pipe_queue_accept(uv_pipe_t* handle, uv_pipe_accept_t* req) {
0, 0,
NULL); NULL);
if (pipeHandle == INVALID_HANDLE_VALUE) { if (req->pipeHandle == INVALID_HANDLE_VALUE) {
req->error = uv_new_sys_error(GetLastError()); req->error = uv_new_sys_error(GetLastError());
uv_insert_pending_req((uv_req_t*) req); uv_insert_pending_req((uv_req_t*) req);
handle->reqs_pending++; handle->reqs_pending++;
return; return;
} }
if (CreateIoCompletionPort(pipeHandle, if (uv_set_pipe_handle(handle, req->pipeHandle)) {
LOOP->iocp, CloseHandle(req->pipeHandle);
(ULONG_PTR)handle, req->pipeHandle = INVALID_HANDLE_VALUE;
0) == NULL) {
req->error = uv_new_sys_error(GetLastError()); req->error = uv_new_sys_error(GetLastError());
uv_insert_pending_req((uv_req_t*) req); uv_insert_pending_req((uv_req_t*) req);
handle->reqs_pending++; handle->reqs_pending++;
return; return;
} }
}
assert(req->pipeHandle != INVALID_HANDLE_VALUE);
/* Prepare the overlapped structure. */ /* Prepare the overlapped structure. */
memset(&(req->overlapped), 0, sizeof(req->overlapped)); memset(&(req->overlapped), 0, sizeof(req->overlapped));
if (!ConnectNamedPipe(pipeHandle, &req->overlapped) && GetLastError() != ERROR_IO_PENDING) { if (!ConnectNamedPipe(req->pipeHandle, &req->overlapped) && GetLastError() != ERROR_IO_PENDING) {
if (GetLastError() == ERROR_PIPE_CONNECTED) { if (GetLastError() == ERROR_PIPE_CONNECTED) {
req->pipeHandle = pipeHandle;
req->error = uv_ok_; req->error = uv_ok_;
} else { } else {
CloseHandle(req->pipeHandle);
req->pipeHandle = INVALID_HANDLE_VALUE;
/* Make this req pending reporting an error. */ /* Make this req pending reporting an error. */
req->error = uv_new_sys_error(GetLastError()); req->error = uv_new_sys_error(GetLastError());
} }
@ -310,7 +384,6 @@ static void uv_pipe_queue_accept(uv_pipe_t* handle, uv_pipe_accept_t* req) {
return; return;
} }
req->pipeHandle = pipeHandle;
handle->reqs_pending++; handle->reqs_pending++;
} }
@ -336,7 +409,7 @@ int uv_pipe_accept(uv_pipe_t* server, uv_pipe_t* client) {
req->pipeHandle = INVALID_HANDLE_VALUE; req->pipeHandle = INVALID_HANDLE_VALUE;
if (!(server->flags & UV_HANDLE_CLOSING)) { if (!(server->flags & UV_HANDLE_CLOSING)) {
uv_pipe_queue_accept(server, req); uv_pipe_queue_accept(server, req, FALSE);
} }
return 0; return 0;
@ -347,22 +420,35 @@ int uv_pipe_accept(uv_pipe_t* server, uv_pipe_t* client) {
int uv_pipe_listen(uv_pipe_t* handle, uv_connection_cb cb) { int uv_pipe_listen(uv_pipe_t* handle, uv_connection_cb cb) {
int i, errno; int i, errno;
if (handle->flags & UV_HANDLE_BIND_ERROR) {
LOOP->last_error = handle->error;
return -1;
}
if (!(handle->flags & UV_HANDLE_BOUND)) {
uv_set_error(UV_ENOTCONN, 0);
return -1;
}
if (handle->flags & UV_HANDLE_LISTENING || if (handle->flags & UV_HANDLE_LISTENING ||
handle->flags & UV_HANDLE_READING) { handle->flags & UV_HANDLE_READING) {
uv_set_sys_error(UV_EALREADY); uv_set_error(UV_EALREADY, 0);
return -1; return -1;
} }
if (!(handle->flags & UV_HANDLE_PIPESERVER)) { if (!(handle->flags & UV_HANDLE_PIPESERVER)) {
uv_set_sys_error(UV_ENOTSUP); uv_set_error(UV_ENOTSUP, 0);
return -1; return -1;
} }
handle->flags |= UV_HANDLE_LISTENING; handle->flags |= UV_HANDLE_LISTENING;
handle->connection_cb = cb; handle->connection_cb = cb;
/* First pipe handle should have already been created in uv_pipe_bind */
assert(handle->accept_reqs[0].pipeHandle != INVALID_HANDLE_VALUE);
for (i = 0; i < COUNTOF(handle->accept_reqs); i++) { for (i = 0; i < COUNTOF(handle->accept_reqs); i++) {
uv_pipe_queue_accept(handle, &handle->accept_reqs[i]); uv_pipe_queue_accept(handle, &handle->accept_reqs[i], i == 0);
} }
return 0; return 0;
@ -403,17 +489,17 @@ static void uv_pipe_queue_read(uv_pipe_t* handle) {
int uv_pipe_read_start(uv_pipe_t* handle, uv_alloc_cb alloc_cb, uv_read_cb read_cb) { int uv_pipe_read_start(uv_pipe_t* handle, uv_alloc_cb alloc_cb, uv_read_cb read_cb) {
if (!(handle->flags & UV_HANDLE_CONNECTION)) { if (!(handle->flags & UV_HANDLE_CONNECTION)) {
uv_set_sys_error(UV_EINVAL); uv_set_error(UV_EINVAL, 0);
return -1; return -1;
} }
if (handle->flags & UV_HANDLE_READING) { if (handle->flags & UV_HANDLE_READING) {
uv_set_sys_error(UV_EALREADY); uv_set_error(UV_EALREADY, 0);
return -1; return -1;
} }
if (handle->flags & UV_HANDLE_EOF) { if (handle->flags & UV_HANDLE_EOF) {
uv_set_sys_error(UV_EOF); uv_set_error(UV_EOF, 0);
return -1; return -1;
} }
@ -435,19 +521,19 @@ int uv_pipe_write(uv_write_t* req, uv_pipe_t* handle, uv_buf_t bufs[], int bufcn
int result; int result;
if (bufcnt != 1) { if (bufcnt != 1) {
uv_set_sys_error(UV_ENOTSUP); uv_set_error(UV_ENOTSUP, 0);
return -1; return -1;
} }
assert(handle->handle != INVALID_HANDLE_VALUE); assert(handle->handle != INVALID_HANDLE_VALUE);
if (!(handle->flags & UV_HANDLE_CONNECTION)) { if (!(handle->flags & UV_HANDLE_CONNECTION)) {
uv_set_sys_error(UV_EINVAL); uv_set_error(UV_EINVAL, 0);
return -1; return -1;
} }
if (handle->flags & UV_HANDLE_SHUTTING) { if (handle->flags & UV_HANDLE_SHUTTING) {
uv_set_sys_error(UV_EOF); uv_set_error(UV_EOF, 0);
return -1; return -1;
} }
@ -485,7 +571,7 @@ int uv_pipe_write(uv_write_t* req, uv_pipe_t* handle, uv_buf_t bufs[], int bufcn
void uv_process_pipe_read_req(uv_pipe_t* handle, uv_req_t* req) { void uv_process_pipe_read_req(uv_pipe_t* handle, uv_req_t* req) {
DWORD bytes, avail, err, mode; DWORD bytes, avail;
uv_buf_t buf; uv_buf_t buf;
assert(handle->type == UV_NAMED_PIPE); assert(handle->type == UV_NAMED_PIPE);
@ -601,7 +687,7 @@ void uv_process_pipe_accept_req(uv_pipe_t* handle, uv_req_t* raw_req) {
req->pipeHandle = INVALID_HANDLE_VALUE; req->pipeHandle = INVALID_HANDLE_VALUE;
} }
if (!(handle->flags & UV_HANDLE_CLOSING)) { if (!(handle->flags & UV_HANDLE_CLOSING)) {
uv_pipe_queue_accept(handle, req); uv_pipe_queue_accept(handle, req, FALSE);
} }
} }

5
deps/uv/test/test-async.c

@ -146,8 +146,6 @@ static void async2_cb(uv_handle_t* handle, int status) {
static void prepare_cb(uv_prepare_t* handle, int status) { static void prepare_cb(uv_prepare_t* handle, int status) {
int r;
ASSERT(handle == &prepare_handle); ASSERT(handle == &prepare_handle);
ASSERT(status == 0); ASSERT(status == 0);
@ -170,8 +168,7 @@ static void prepare_cb(uv_prepare_t* handle, int status) {
#endif #endif
case 1: case 1:
r = uv_close((uv_handle_t*)handle, close_cb); uv_close((uv_handle_t*)handle, close_cb);
ASSERT(r == 0);
break; break;
default: default:

9
deps/uv/test/test-callback-stack.c

@ -83,9 +83,7 @@ static void read_cb(uv_stream_t* tcp, ssize_t nread, uv_buf_t buf) {
ASSERT(uv_last_error().code == UV_EOF); ASSERT(uv_last_error().code == UV_EOF);
nested++; nested++;
if (uv_close((uv_handle_t*)tcp, close_cb)) { uv_close((uv_handle_t*)tcp, close_cb);
FATAL("uv_close failed");
}
nested--; nested--;
return; return;
@ -111,8 +109,6 @@ static void read_cb(uv_stream_t* tcp, ssize_t nread, uv_buf_t buf) {
static void timer_cb(uv_timer_t* handle, int status) { static void timer_cb(uv_timer_t* handle, int status) {
int r;
ASSERT(handle == &timer); ASSERT(handle == &timer);
ASSERT(status == 0); ASSERT(status == 0);
ASSERT(nested == 0 && "timer_cb must be called from a fresh stack"); ASSERT(nested == 0 && "timer_cb must be called from a fresh stack");
@ -127,8 +123,7 @@ static void timer_cb(uv_timer_t* handle, int status) {
timer_cb_called++; timer_cb_called++;
r = uv_close((uv_handle_t*)handle, close_cb); uv_close((uv_handle_t*)handle, close_cb);
ASSERT(r == 0);
} }

9
deps/uv/test/test-delayed-accept.c

@ -71,18 +71,15 @@ static void do_accept(uv_timer_t* timer_handle, int status) {
do_accept_called++; do_accept_called++;
/* Immediately close the accepted handle. */ /* Immediately close the accepted handle. */
r = uv_close((uv_handle_t*)accepted_handle, close_cb); uv_close((uv_handle_t*)accepted_handle, close_cb);
ASSERT(r == 0);
/* After accepting the two clients close the server handle */ /* After accepting the two clients close the server handle */
if (do_accept_called == 2) { if (do_accept_called == 2) {
r = uv_close((uv_handle_t*)server, close_cb); uv_close((uv_handle_t*)server, close_cb);
ASSERT(r == 0);
} }
/* Dispose the timer. */ /* Dispose the timer. */
r = uv_close((uv_handle_t*)timer_handle, close_cb); uv_close((uv_handle_t*)timer_handle, close_cb);
ASSERT(r == 0);
} }

83
deps/uv/test/test-idle.c

@ -0,0 +1,83 @@
/* 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"
static uv_timer_t timer_handle;
static uv_idle_t idle_handle;
static int idle_cb_called = 0;
static int timer_cb_called = 0;
static int close_cb_called = 0;
static void close_cb(uv_handle_t* handle) {
close_cb_called++;
}
static void timer_cb(uv_timer_t* handle, int status) {
ASSERT(handle == &timer_handle);
ASSERT(status == 0);
uv_close((uv_handle_t*) &idle_handle, close_cb);
uv_close((uv_handle_t*) &timer_handle, close_cb);
timer_cb_called++;
LOGF("timer_cb %d\n", timer_cb_called);
}
static void idle_cb(uv_idle_t* handle, int status) {
ASSERT(handle == &idle_handle);
ASSERT(status == 0);
idle_cb_called++;
LOGF("idle_cb %d\n", idle_cb_called);
}
TEST_IMPL(idle_starvation) {
int r;
uv_init();
r = uv_idle_init(&idle_handle);
ASSERT(r == 0);
r = uv_idle_start(&idle_handle, idle_cb);
ASSERT(r == 0);
r = uv_timer_init(&timer_handle);
ASSERT(r == 0);
r = uv_timer_start(&timer_handle, timer_cb, 50, 0);
ASSERT(r == 0);
r = uv_run();
ASSERT(r == 0);
ASSERT(idle_cb_called > 0);
ASSERT(timer_cb_called == 1);
ASSERT(close_cb_called == 2);
return 0;
}

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

@ -46,6 +46,7 @@ TEST_DECLARE (shutdown_eof)
TEST_DECLARE (callback_stack) TEST_DECLARE (callback_stack)
TEST_DECLARE (timer) TEST_DECLARE (timer)
TEST_DECLARE (timer_again) TEST_DECLARE (timer_again)
TEST_DECLARE (idle_starvation)
TEST_DECLARE (loop_handles) TEST_DECLARE (loop_handles)
TEST_DECLARE (ref) TEST_DECLARE (ref)
TEST_DECLARE (idle_ref) TEST_DECLARE (idle_ref)
@ -113,6 +114,8 @@ TASK_LIST_START
TEST_ENTRY (timer_again) TEST_ENTRY (timer_again)
TEST_ENTRY (idle_starvation)
TEST_ENTRY (ref) TEST_ENTRY (ref)
TEST_ENTRY (idle_ref) TEST_ENTRY (idle_ref)
TEST_ENTRY (async_ref) TEST_ENTRY (async_ref)
@ -141,4 +144,3 @@ TASK_LIST_START
TEST_ENTRY (pass_always) TEST_ENTRY (pass_always)
#endif #endif
TASK_LIST_END TASK_LIST_END

20
deps/uv/test/test-loop-handles.c

@ -130,8 +130,6 @@ static void idle_2_close_cb(uv_handle_t* handle) {
static void idle_2_cb(uv_idle_t* handle, int status) { static void idle_2_cb(uv_idle_t* handle, int status) {
int r;
LOG("IDLE_2_CB\n"); LOG("IDLE_2_CB\n");
ASSERT(handle == &idle_2_handle); ASSERT(handle == &idle_2_handle);
@ -139,8 +137,7 @@ static void idle_2_cb(uv_idle_t* handle, int status) {
idle_2_cb_called++; idle_2_cb_called++;
r = uv_close((uv_handle_t*)handle, idle_2_close_cb); uv_close((uv_handle_t*)handle, idle_2_close_cb);
ASSERT(r == 0);
} }
@ -230,23 +227,18 @@ static void check_cb(uv_check_t* handle, int status) {
} else { } else {
/* End of the test - close all handles */ /* End of the test - close all handles */
r = uv_close((uv_handle_t*)&prepare_1_handle, prepare_1_close_cb); uv_close((uv_handle_t*)&prepare_1_handle, prepare_1_close_cb);
ASSERT(r == 0); uv_close((uv_handle_t*)&check_handle, check_close_cb);
r = uv_close((uv_handle_t*)&check_handle, check_close_cb); uv_close((uv_handle_t*)&prepare_2_handle, prepare_2_close_cb);
ASSERT(r == 0);
r = uv_close((uv_handle_t*)&prepare_2_handle, prepare_2_close_cb);
ASSERT(r == 0);
for (i = 0; i < IDLE_COUNT; i++) { for (i = 0; i < IDLE_COUNT; i++) {
r = uv_close((uv_handle_t*)&idle_1_handles[i], idle_1_close_cb); uv_close((uv_handle_t*)&idle_1_handles[i], idle_1_close_cb);
ASSERT(r == 0);
} }
/* This handle is closed/recreated every time, close it only if it is */ /* This handle is closed/recreated every time, close it only if it is */
/* active.*/ /* active.*/
if (idle_2_is_active) { if (idle_2_is_active) {
r = uv_close((uv_handle_t*)&idle_2_handle, idle_2_close_cb); uv_close((uv_handle_t*)&idle_2_handle, idle_2_close_cb);
ASSERT(r == 0);
} }
} }

11
src/handle_wrap.cc

@ -40,18 +40,11 @@ Handle<Value> HandleWrap::Close(const Arguments& args) {
UNWRAP UNWRAP
assert(!wrap->object_.IsEmpty()); assert(!wrap->object_.IsEmpty());
int r = uv_close(wrap->handle__, OnClose); uv_close(wrap->handle__, OnClose);
wrap->StateChange(); wrap->StateChange();
if (r) { return v8::Null();
SetErrno(uv_last_error().code);
wrap->object_->SetPointerInInternalField(0, NULL);
wrap->object_.Dispose();
wrap->object_.Clear();
}
return scope.Close(Integer::New(r));
} }

Loading…
Cancel
Save