Upgrade libuv to ca633920f564167158d0bb82989d842a47c27d56

This commit is contained in:
Bert Belder 2011-08-11 04:00:39 +02:00
parent fcf9cfa137
commit 74e8fa2e57
2 changed files with 75 additions and 26 deletions

View File

@ -56,9 +56,9 @@ int uv_pipe_init_with_handle(uv_pipe_t* handle, HANDLE pipeHandle) {
int err = uv_pipe_init(handle); int err = uv_pipe_init(handle);
if (!err) { if (!err) {
/* /*
* At this point we don't know whether the pipe will be used as a client * At this point we don't know whether the pipe will be used as a client
* or a server. So, we assume that it will be a client until * or a server. So, we assume that it will be a client until
* uv_listen is called. * uv_listen is called.
*/ */
handle->handle = pipeHandle; handle->handle = pipeHandle;
@ -144,23 +144,58 @@ static int uv_set_pipe_handle(uv_pipe_t* handle, HANDLE pipeHandle) {
} }
static DWORD WINAPI pipe_shutdown_thread_proc(void* parameter) {
int errno;
uv_pipe_t* handle;
uv_shutdown_t* req;
req = (uv_shutdown_t*) parameter;
assert(req);
handle = (uv_pipe_t*) req->handle;
assert(handle);
FlushFileBuffers(handle->handle);
/* Post completed */
if (!PostQueuedCompletionStatus(LOOP->iocp,
0,
0,
&req->overlapped)) {
uv_fatal_error(GetLastError(), "PostQueuedCompletionStatus");
}
return 0;
}
void uv_pipe_endgame(uv_pipe_t* handle) { void uv_pipe_endgame(uv_pipe_t* handle) {
uv_err_t err; uv_err_t err;
int status; int status;
unsigned int uv_alloced; unsigned int uv_alloced;
DWORD result;
if (handle->flags & UV_HANDLE_SHUTTING && if (handle->flags & UV_HANDLE_SHUTTING &&
!(handle->flags & UV_HANDLE_SHUT) && !(handle->flags & UV_HANDLE_SHUT) &&
handle->write_reqs_pending == 0) { handle->write_reqs_pending == 0) {
close_pipe(handle, &status, &err);
if (handle->shutdown_req->cb) { /* TODO: Try to avoid using the thread pool. Maybe we can somehow figure */
if (status == -1) { /* out how much data is left in the kernel buffer? */
LOOP->last_error = err; result = QueueUserWorkItem(pipe_shutdown_thread_proc,
} handle->shutdown_req,
handle->shutdown_req->cb(handle->shutdown_req, status); WT_EXECUTELONGFUNCTION);
if (result) {
/* Mark the handle as shut now to avoid going through this again. */
handle->flags |= UV_HANDLE_SHUT;
} else {
/* Failure. */
uv_set_sys_error(GetLastError());
handle->shutdown_req->cb(handle->shutdown_req, -1);
handle->flags &= ~UV_HANDLE_SHUTTING;
DECREASE_PENDING_REQ_COUNT(handle);
} }
handle->reqs_pending--;
return;
} }
if (handle->flags & UV_HANDLE_CLOSING && if (handle->flags & UV_HANDLE_CLOSING &&
@ -518,7 +553,7 @@ int uv_pipe_listen(uv_pipe_t* handle, int backlog, uv_connection_cb cb) {
return -1; return -1;
} }
if (!(handle->flags & UV_HANDLE_BOUND) && if (!(handle->flags & UV_HANDLE_BOUND) &&
!(handle->flags & UV_HANDLE_GIVEN_OS_HANDLE)) { !(handle->flags & UV_HANDLE_GIVEN_OS_HANDLE)) {
uv_set_error(UV_EINVAL, 0); uv_set_error(UV_EINVAL, 0);
return -1; return -1;
@ -530,7 +565,7 @@ int uv_pipe_listen(uv_pipe_t* handle, int backlog, uv_connection_cb cb) {
return -1; return -1;
} }
if (!(handle->flags & UV_HANDLE_PIPESERVER) && if (!(handle->flags & UV_HANDLE_PIPESERVER) &&
!(handle->flags & UV_HANDLE_GIVEN_OS_HANDLE)) { !(handle->flags & UV_HANDLE_GIVEN_OS_HANDLE)) {
uv_set_error(UV_ENOTSUP, 0); uv_set_error(UV_ENOTSUP, 0);
return -1; return -1;
@ -718,7 +753,10 @@ void uv_process_pipe_read_req(uv_pipe_t* handle, uv_req_t* req) {
break; break;
} }
/* TODO: do we need to check avail > 0? */ if (avail == 0) {
// Nothing to read after all
break;
}
buf = handle->alloc_cb((uv_stream_t*)handle, avail); buf = handle->alloc_cb((uv_stream_t*)handle, avail);
assert(buf.len > 0); assert(buf.len > 0);
@ -728,20 +766,10 @@ void uv_process_pipe_read_req(uv_pipe_t* handle, uv_req_t* req) {
buf.len, buf.len,
&bytes, &bytes,
NULL)) { NULL)) {
if (bytes > 0) { /* Successful read */
/* Successful read */ handle->read_cb((uv_stream_t*)handle, bytes, buf);
handle->read_cb((uv_stream_t*)handle, bytes, buf); /* Read again only if bytes == buf.len */
/* Read again only if bytes == buf.len */ if (bytes <= buf.len) {
if (bytes <= buf.len) {
break;
}
} else {
/* Connection closed */
handle->flags &= ~UV_HANDLE_READING;
handle->flags |= UV_HANDLE_EOF;
LOOP->last_error.code = UV_EOF;
LOOP->last_error.sys_errno_ = ERROR_SUCCESS;
handle->read_cb((uv_stream_t*)handle, -1, buf);
break; break;
} }
} else { } else {
@ -826,3 +854,17 @@ void uv_process_pipe_connect_req(uv_pipe_t* handle, uv_connect_t* req) {
DECREASE_PENDING_REQ_COUNT(handle); DECREASE_PENDING_REQ_COUNT(handle);
} }
void uv_process_pipe_shutdown_req(uv_pipe_t* handle, uv_shutdown_t* req) {
assert(handle->type == UV_NAMED_PIPE);
CloseHandle(handle->handle);
handle->handle = INVALID_HANDLE_VALUE;
if (req->cb) {
((uv_shutdown_cb) req->cb)(req, 0);
}
DECREASE_PENDING_REQ_COUNT(handle);
}

View File

@ -110,6 +110,13 @@ void uv_process_reqs() {
DELEGATE_STREAM_REQ((uv_connect_t*) req, connect, handle); DELEGATE_STREAM_REQ((uv_connect_t*) req, connect, handle);
break; break;
case UV_SHUTDOWN:
/* Tcp shutdown requests don't come here. */
assert(((uv_shutdown_t*) req)->handle->type == UV_NAMED_PIPE);
uv_process_pipe_shutdown_req(
(uv_pipe_t*) ((uv_shutdown_t*) req)->handle, req);
break;
case UV_WAKEUP: case UV_WAKEUP:
uv_process_async_wakeup_req((uv_async_t*) req->data, req); uv_process_async_wakeup_req((uv_async_t*) req->data, req);
break; break;