diff options
author | Ryan Dahl <ry@tinyclouds.org> | 2011-07-21 06:55:12 +0400 |
---|---|---|
committer | Ryan Dahl <ry@tinyclouds.org> | 2011-07-21 06:57:03 +0400 |
commit | 133036fdadbca1099cf1cf589987eea01236722e (patch) | |
tree | e5dcf60cf26bd8faf652e1aa2d856b635e776e00 /deps | |
parent | 1b89323e92001481f7b0e1f14736d288b58b160e (diff) |
upgrade libuv to 6e50576
Diffstat (limited to 'deps')
-rw-r--r-- | deps/uv/include/uv-win.h | 2 | ||||
-rw-r--r-- | deps/uv/include/uv.h | 2 | ||||
-rw-r--r-- | deps/uv/msvs/libuv-test.vcxproj | 1 | ||||
-rw-r--r-- | deps/uv/src/uv-unix.c | 5 | ||||
-rw-r--r-- | deps/uv/src/win/core.c | 38 | ||||
-rw-r--r-- | deps/uv/src/win/error.c | 6 | ||||
-rw-r--r-- | deps/uv/src/win/handle.c | 25 | ||||
-rw-r--r-- | deps/uv/src/win/internal.h | 1 | ||||
-rw-r--r-- | deps/uv/src/win/pipe.c | 204 | ||||
-rw-r--r-- | deps/uv/test/test-async.c | 5 | ||||
-rw-r--r-- | deps/uv/test/test-callback-stack.c | 9 | ||||
-rw-r--r-- | deps/uv/test/test-delayed-accept.c | 9 | ||||
-rw-r--r-- | deps/uv/test/test-idle.c | 83 | ||||
-rw-r--r-- | deps/uv/test/test-list.h | 4 | ||||
-rw-r--r-- | deps/uv/test/test-loop-handles.c | 20 |
15 files changed, 287 insertions, 127 deletions
diff --git a/deps/uv/include/uv-win.h b/deps/uv/include/uv-win.h index 12588e96974..5bbb44612a3 100644 --- a/deps/uv/include/uv-win.h +++ b/deps/uv/include/uv-win.h @@ -103,7 +103,7 @@ typedef struct uv_buf_t { HANDLE handle; #define UV_PIPE_PRIVATE_FIELDS \ - char* name; \ + wchar_t* name; \ union { \ struct { uv_pipe_server_fields }; \ struct { uv_pipe_connection_fields }; \ diff --git a/deps/uv/include/uv.h b/deps/uv/include/uv.h index f065b9d90f8..6f302dcd176 100644 --- a/deps/uv/include/uv.h +++ b/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 * 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 \ diff --git a/deps/uv/msvs/libuv-test.vcxproj b/deps/uv/msvs/libuv-test.vcxproj index 8408735b25b..da93bd99a85 100644 --- a/deps/uv/msvs/libuv-test.vcxproj +++ b/deps/uv/msvs/libuv-test.vcxproj @@ -153,6 +153,7 @@ <ClCompile Include="..\test\test-getaddrinfo.c" /> <ClCompile Include="..\test\test-getsockname.c" /> <ClCompile Include="..\test\test-hrtime.c" /> + <ClCompile Include="..\test\test-idle.c" /> <ClCompile Include="..\test\test-loop-handles.c" /> <ClCompile Include="..\test\test-pass-always.c" /> <ClCompile Include="..\test\test-ping-pong.c" /> diff --git a/deps/uv/src/uv-unix.c b/deps/uv/src/uv-unix.c index e614f0f7b1c..ff1f80d824b 100644 --- a/deps/uv/src/uv-unix.c +++ b/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_pipe_t* pipe; uv_async_t* async; @@ -245,7 +245,6 @@ int uv_close(uv_handle_t* handle, uv_close_cb close_cb) { default: assert(0); - return -1; } 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_feed_event(EV_DEFAULT_ &handle->next_watcher, EV_IDLE); assert(ev_is_pending(&handle->next_watcher)); - - return 0; } diff --git a/deps/uv/src/win/core.c b/deps/uv/src/win/core.c index e2d5a32c8ab..ed870efebe6 100644 --- a/deps/uv/src/win/core.c +++ b/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; - DWORD bytes; + DWORD bytes, timeout; ULONG_PTR key; OVERLAPPED* overlapped; uv_req_t* req; + if (block) { + timeout = uv_get_poll_timeout(); + } else { + timeout = 0; + } + success = GetQueuedCompletionStatus(LOOP->iocp, &bytes, &key, &overlapped, - uv_get_poll_timeout()); - - uv_update_time(); + timeout); if (overlapped) { /* Package was dequeued */ @@ -118,30 +122,30 @@ static void uv_poll() { int uv_run() { - while (1) { + while (LOOP->refs > 0) { uv_update_time(); uv_process_timers(); - /* Terrible: please fix me! */ - while (LOOP->refs > 0 && - (LOOP->idle_handles || LOOP->pending_reqs_tail || LOOP->endgame_handles)) { - /* Terrible: please fix me! */ - while (LOOP->pending_reqs_tail || LOOP->endgame_handles) { - uv_process_endgames(); - uv_process_reqs(); - } - - /* Call idle callbacks */ + /* Call idle callbacks if nothing to do. */ + if (LOOP->pending_reqs_tail == NULL && LOOP->endgame_handles == NULL) { uv_idle_invoke(); } + /* 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) { + uv_process_endgames(); + uv_process_reqs(); + } + if (LOOP->refs <= 0) { break; } uv_prepare_invoke(); - uv_poll(); + uv_poll(LOOP->idle_handles == NULL); uv_check_invoke(); } diff --git a/deps/uv/src/win/error.c b/deps/uv/src/win/error.c index d44be2bb2d3..4c2cacdbe6e 100644 --- a/deps/uv/src/win/error.c +++ b/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.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; +} diff --git a/deps/uv/src/win/handle.c b/deps/uv/src/win/handle.c index 91dfba80f16..cc6d2f88b55 100644 --- a/deps/uv/src/win/handle.c +++ b/deps/uv/src/win/handle.c @@ -40,12 +40,12 @@ int uv_is_active(uv_handle_t* handle) { /* 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_pipe_t* pipe; if (handle->flags & UV_HANDLE_CLOSING) { - return 0; + return; } 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) { uv_want_endgame(handle); } - return 0; + return; case UV_NAMED_PIPE: 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) { uv_want_endgame(handle); } - return 0; + return; case UV_TIMER: uv_timer_stop((uv_timer_t*)handle); uv_want_endgame(handle); - return 0; + return; case UV_PREPARE: uv_prepare_stop((uv_prepare_t*)handle); uv_want_endgame(handle); - return 0; + return; case UV_CHECK: uv_check_stop((uv_check_t*)handle); uv_want_endgame(handle); - return 0; + return; case UV_IDLE: uv_idle_stop((uv_idle_t*)handle); uv_want_endgame(handle); - return 0; + return; case UV_ASYNC: if (!((uv_async_t*)handle)->async_sent) { uv_want_endgame(handle); } - return 0; + return; default: /* Not supported */ - assert(0); - return -1; + abort(); } } -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; - return uv_close_error(handle, uv_ok_); + uv_close_error(handle, uv_ok_); } diff --git a/deps/uv/src/win/internal.h b/deps/uv/src/win/internal.h index 33783f6eb92..87b9c37b985 100644 --- a/deps/uv/src/win/internal.h +++ b/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_t uv_new_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_ */ diff --git a/deps/uv/src/win/pipe.c b/deps/uv/src/win/pipe.c index e58b99737e9..048183083c4 100644 --- a/deps/uv/src/win/pipe.c +++ b/deps/uv/src/win/pipe.c @@ -38,6 +38,7 @@ int uv_pipe_init(uv_pipe_t* handle) { handle->reqs_pending = 0; handle->pending_accepts = NULL; handle->name = NULL; + handle->handle = INVALID_HANDLE_VALUE; uv_counters()->pipe_init++; @@ -96,20 +97,18 @@ void uv_pipe_endgame(uv_pipe_t* handle) { /* Creates a pipe server. */ -/* TODO: make this work with UTF8 name */ int uv_pipe_bind(uv_pipe_t* handle, const char* name) { - int i; + int i, errno, nameSize; uv_pipe_accept_t* req; - if (!name) { + if (handle->flags & UV_HANDLE_BOUND) { uv_set_sys_error(WSAEINVAL); return -1; } - /* Make our own copy of the pipe name */ - handle->name = _strdup(name); - if (!handle->name) { - uv_fatal_error(ERROR_OUTOFMEMORY, "malloc"); + if (!name) { + uv_set_sys_error(WSAEINVAL); + return -1; } 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; } + /* 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_BOUND; + 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); /* 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. */ - pipeHandle = CreateFile(handle->name, + pipeHandle = CreateFileW(handle->name, GENERIC_READ | GENERIC_WRITE, 0, 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, const char* name, uv_connect_cb cb) { - int errno; + int errno, nameSize; HANDLE pipeHandle; 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->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, 0, NULL, @@ -198,11 +267,6 @@ int uv_pipe_connect(uv_connect_t* req, uv_pipe_t* handle, if (pipeHandle == INVALID_HANDLE_VALUE) { if (GetLastError() == ERROR_PIPE_BUSY) { /* 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)) { errno = GetLastError(); goto error; @@ -228,6 +292,11 @@ int uv_pipe_connect(uv_connect_t* req, uv_pipe_t* handle, return 0; error: + if (handle->name) { + free(handle->name); + handle->name = NULL; + } + if (pipeHandle != INVALID_HANDLE_VALUE) { CloseHandle(pipeHandle); } @@ -243,7 +312,7 @@ void close_pipe(uv_pipe_t* handle, int* status, uv_err_t* err) { if (handle->name) { free(handle->name); - handle->name; + handle->name = NULL; } if (handle->flags & UV_HANDLE_PIPESERVER) { @@ -251,57 +320,62 @@ void close_pipe(uv_pipe_t* handle, int* status, uv_err_t* err) { pipeHandle = handle->accept_reqs[i].pipeHandle; if (pipeHandle != INVALID_HANDLE_VALUE) { CloseHandle(pipeHandle); + handle->accept_reqs[i].pipeHandle = INVALID_HANDLE_VALUE; } } } else if (handle->handle != INVALID_HANDLE_VALUE) { CloseHandle(handle->handle); + handle->handle = INVALID_HANDLE_VALUE; } handle->flags |= UV_HANDLE_SHUT; } -static void uv_pipe_queue_accept(uv_pipe_t* handle, uv_pipe_accept_t* req) { - HANDLE pipeHandle; - +static void uv_pipe_queue_accept(uv_pipe_t* handle, uv_pipe_accept_t* req, BOOL firstInstance) { assert(handle->flags & UV_HANDLE_LISTENING); - assert(req->pipeHandle == INVALID_HANDLE_VALUE); - pipeHandle = CreateNamedPipe(handle->name, - PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, - PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT, - PIPE_UNLIMITED_INSTANCES, - 65536, - 65536, - 0, - NULL); + if (!firstInstance) { + assert(req->pipeHandle == INVALID_HANDLE_VALUE); - if (pipeHandle == INVALID_HANDLE_VALUE) { - req->error = uv_new_sys_error(GetLastError()); - uv_insert_pending_req((uv_req_t*) req); - handle->reqs_pending++; - return; - } + req->pipeHandle = CreateNamedPipeW(handle->name, + PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, + PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT, + PIPE_UNLIMITED_INSTANCES, + 65536, + 65536, + 0, + NULL); - if (CreateIoCompletionPort(pipeHandle, - LOOP->iocp, - (ULONG_PTR)handle, - 0) == NULL) { - req->error = uv_new_sys_error(GetLastError()); - uv_insert_pending_req((uv_req_t*) req); - handle->reqs_pending++; - return; + if (req->pipeHandle == INVALID_HANDLE_VALUE) { + req->error = uv_new_sys_error(GetLastError()); + uv_insert_pending_req((uv_req_t*) req); + handle->reqs_pending++; + return; + } + + if (uv_set_pipe_handle(handle, req->pipeHandle)) { + CloseHandle(req->pipeHandle); + req->pipeHandle = INVALID_HANDLE_VALUE; + req->error = uv_new_sys_error(GetLastError()); + uv_insert_pending_req((uv_req_t*) req); + handle->reqs_pending++; + return; + } } + assert(req->pipeHandle != INVALID_HANDLE_VALUE); + /* Prepare the overlapped structure. */ 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) { - req->pipeHandle = pipeHandle; req->error = uv_ok_; } else { + CloseHandle(req->pipeHandle); + req->pipeHandle = INVALID_HANDLE_VALUE; /* Make this req pending reporting an error. */ 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; } - req->pipeHandle = pipeHandle; handle->reqs_pending++; } @@ -336,7 +409,7 @@ int uv_pipe_accept(uv_pipe_t* server, uv_pipe_t* client) { req->pipeHandle = INVALID_HANDLE_VALUE; if (!(server->flags & UV_HANDLE_CLOSING)) { - uv_pipe_queue_accept(server, req); + uv_pipe_queue_accept(server, req, FALSE); } 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 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 || handle->flags & UV_HANDLE_READING) { - uv_set_sys_error(UV_EALREADY); + uv_set_error(UV_EALREADY, 0); return -1; } if (!(handle->flags & UV_HANDLE_PIPESERVER)) { - uv_set_sys_error(UV_ENOTSUP); + uv_set_error(UV_ENOTSUP, 0); return -1; } handle->flags |= UV_HANDLE_LISTENING; 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++) { - uv_pipe_queue_accept(handle, &handle->accept_reqs[i]); + uv_pipe_queue_accept(handle, &handle->accept_reqs[i], i == 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) { if (!(handle->flags & UV_HANDLE_CONNECTION)) { - uv_set_sys_error(UV_EINVAL); + uv_set_error(UV_EINVAL, 0); return -1; } if (handle->flags & UV_HANDLE_READING) { - uv_set_sys_error(UV_EALREADY); + uv_set_error(UV_EALREADY, 0); return -1; } if (handle->flags & UV_HANDLE_EOF) { - uv_set_sys_error(UV_EOF); + uv_set_error(UV_EOF, 0); 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; if (bufcnt != 1) { - uv_set_sys_error(UV_ENOTSUP); + uv_set_error(UV_ENOTSUP, 0); return -1; } assert(handle->handle != INVALID_HANDLE_VALUE); if (!(handle->flags & UV_HANDLE_CONNECTION)) { - uv_set_sys_error(UV_EINVAL); + uv_set_error(UV_EINVAL, 0); return -1; } if (handle->flags & UV_HANDLE_SHUTTING) { - uv_set_sys_error(UV_EOF); + uv_set_error(UV_EOF, 0); 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) { - DWORD bytes, avail, err, mode; + DWORD bytes, avail; uv_buf_t buf; 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; } if (!(handle->flags & UV_HANDLE_CLOSING)) { - uv_pipe_queue_accept(handle, req); + uv_pipe_queue_accept(handle, req, FALSE); } } diff --git a/deps/uv/test/test-async.c b/deps/uv/test/test-async.c index f91d9b45aeb..2a3a1bfa952 100644 --- a/deps/uv/test/test-async.c +++ b/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) { - int r; - ASSERT(handle == &prepare_handle); ASSERT(status == 0); @@ -170,8 +168,7 @@ static void prepare_cb(uv_prepare_t* handle, int status) { #endif case 1: - r = uv_close((uv_handle_t*)handle, close_cb); - ASSERT(r == 0); + uv_close((uv_handle_t*)handle, close_cb); break; default: diff --git a/deps/uv/test/test-callback-stack.c b/deps/uv/test/test-callback-stack.c index 4162b22112d..6582010aab0 100644 --- a/deps/uv/test/test-callback-stack.c +++ b/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); nested++; - if (uv_close((uv_handle_t*)tcp, close_cb)) { - FATAL("uv_close failed"); - } + uv_close((uv_handle_t*)tcp, close_cb); nested--; 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) { - int r; - ASSERT(handle == &timer); ASSERT(status == 0); 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++; - r = uv_close((uv_handle_t*)handle, close_cb); - ASSERT(r == 0); + uv_close((uv_handle_t*)handle, close_cb); } diff --git a/deps/uv/test/test-delayed-accept.c b/deps/uv/test/test-delayed-accept.c index 30b63b9b6d0..8e3dfc1461a 100644 --- a/deps/uv/test/test-delayed-accept.c +++ b/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++; /* Immediately close the accepted handle. */ - r = uv_close((uv_handle_t*)accepted_handle, close_cb); - ASSERT(r == 0); + uv_close((uv_handle_t*)accepted_handle, close_cb); /* After accepting the two clients close the server handle */ if (do_accept_called == 2) { - r = uv_close((uv_handle_t*)server, close_cb); - ASSERT(r == 0); + uv_close((uv_handle_t*)server, close_cb); } /* Dispose the timer. */ - r = uv_close((uv_handle_t*)timer_handle, close_cb); - ASSERT(r == 0); + uv_close((uv_handle_t*)timer_handle, close_cb); } diff --git a/deps/uv/test/test-idle.c b/deps/uv/test/test-idle.c new file mode 100644 index 00000000000..46917d04674 --- /dev/null +++ b/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; +} diff --git a/deps/uv/test/test-list.h b/deps/uv/test/test-list.h index d1edcd3081a..8b9ecfcca7f 100644 --- a/deps/uv/test/test-list.h +++ b/deps/uv/test/test-list.h @@ -46,6 +46,7 @@ TEST_DECLARE (shutdown_eof) TEST_DECLARE (callback_stack) TEST_DECLARE (timer) TEST_DECLARE (timer_again) +TEST_DECLARE (idle_starvation) TEST_DECLARE (loop_handles) TEST_DECLARE (ref) TEST_DECLARE (idle_ref) @@ -113,6 +114,8 @@ TASK_LIST_START TEST_ENTRY (timer_again) + TEST_ENTRY (idle_starvation) + TEST_ENTRY (ref) TEST_ENTRY (idle_ref) TEST_ENTRY (async_ref) @@ -141,4 +144,3 @@ TASK_LIST_START TEST_ENTRY (pass_always) #endif TASK_LIST_END - diff --git a/deps/uv/test/test-loop-handles.c b/deps/uv/test/test-loop-handles.c index 7979a74b4ae..2e858c1d7b4 100644 --- a/deps/uv/test/test-loop-handles.c +++ b/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) { - int r; - LOG("IDLE_2_CB\n"); ASSERT(handle == &idle_2_handle); @@ -139,8 +137,7 @@ static void idle_2_cb(uv_idle_t* handle, int status) { idle_2_cb_called++; - r = uv_close((uv_handle_t*)handle, idle_2_close_cb); - ASSERT(r == 0); + uv_close((uv_handle_t*)handle, idle_2_close_cb); } @@ -230,23 +227,18 @@ static void check_cb(uv_check_t* handle, int status) { } else { /* End of the test - close all handles */ - r = uv_close((uv_handle_t*)&prepare_1_handle, prepare_1_close_cb); - ASSERT(r == 0); - r = uv_close((uv_handle_t*)&check_handle, check_close_cb); - ASSERT(r == 0); - r = uv_close((uv_handle_t*)&prepare_2_handle, prepare_2_close_cb); - ASSERT(r == 0); + uv_close((uv_handle_t*)&prepare_1_handle, prepare_1_close_cb); + uv_close((uv_handle_t*)&check_handle, check_close_cb); + uv_close((uv_handle_t*)&prepare_2_handle, prepare_2_close_cb); for (i = 0; i < IDLE_COUNT; i++) { - r = uv_close((uv_handle_t*)&idle_1_handles[i], idle_1_close_cb); - ASSERT(r == 0); + uv_close((uv_handle_t*)&idle_1_handles[i], idle_1_close_cb); } /* This handle is closed/recreated every time, close it only if it is */ /* active.*/ if (idle_2_is_active) { - r = uv_close((uv_handle_t*)&idle_2_handle, idle_2_close_cb); - ASSERT(r == 0); + uv_close((uv_handle_t*)&idle_2_handle, idle_2_close_cb); } } |