diff options
author | Alexis Campailla <alexis@janeasystems.com> | 2015-03-03 12:44:32 -0700 |
---|---|---|
committer | Julien Gilli <julien.gilli@joyent.com> | 2015-03-10 16:19:16 -0700 |
commit | d6d89e353b219f6bddb5379051779a6a2121119b (patch) | |
tree | edd1b9f3132b8da8998f35c2a4d44fa7999f4da9 | |
parent | 91185f08771459145bf2b61188059dc0a305f315 (diff) | |
download | node-d6d89e353b219f6bddb5379051779a6a2121119b.tar.gz |
uv: float win pipe patch
Float patch to fix pipe on Windows. Original commit message:
win: fix pipe blocking writes
In the code path for pipe blocking writes, WriteFile is already
posting a completion packet to the I/O completion port.
POST_COMPLETION_FOR_REQ was causing the same request to get
returned twice by GetCompletionStatusEx.
Also on the same code path, we were waiting on the wrong event.
We need to update queued_bytes and write_queue_size when a
blocking write request completes asynchronously.
Ref: https://github.com/libuv/libuv/pull/238
Conflicts:
deps/uv/src/win/pipe.c
-rw-r--r-- | deps/uv/src/win/pipe.c | 12 | ||||
-rw-r--r-- | deps/uv/src/win/req-inl.h | 11 |
2 files changed, 17 insertions, 6 deletions
diff --git a/deps/uv/src/win/pipe.c b/deps/uv/src/win/pipe.c index 78d8a1875..d232efae3 100644 --- a/deps/uv/src/win/pipe.c +++ b/deps/uv/src/win/pipe.c @@ -1351,7 +1351,7 @@ static int uv_pipe_write_impl(uv_loop_t* loop, } /* Request queued by the kernel. */ - req->u.io.queued_bytes = uv__count_bufs(bufs, nbufs); + req->u.io.queued_bytes = bufs[0].len; handle->write_queue_size += req->u.io.queued_bytes; } else if (handle->flags & UV_HANDLE_BLOCKING_WRITES) { /* Using overlapped IO, but wait for completion before returning */ @@ -1376,12 +1376,13 @@ static int uv_pipe_write_impl(uv_loop_t* loop, /* Request completed immediately. */ req->u.io.queued_bytes = 0; } else { - assert(ipc_header_req != NULL); /* Request queued by the kernel. */ - if (WaitForSingleObject(ipc_header_req->u.io.overlapped.hEvent, INFINITE) != + req->u.io.queued_bytes = bufs[0].len; + handle->write_queue_size += req->u.io.queued_bytes; + if (WaitForSingleObject(req->u.io.overlapped.hEvent, INFINITE) != WAIT_OBJECT_0) { err = GetLastError(); - CloseHandle(ipc_header_req->u.io.overlapped.hEvent); + CloseHandle(req->u.io.overlapped.hEvent); return uv_translate_sys_error(err); } } @@ -1390,7 +1391,6 @@ static int uv_pipe_write_impl(uv_loop_t* loop, REGISTER_HANDLE_REQ(loop, handle, req); handle->reqs_pending++; handle->stream.conn.write_reqs_pending++; - POST_COMPLETION_FOR_REQ(loop, req); return 0; } else { result = WriteFile(handle->handle, @@ -1408,7 +1408,7 @@ static int uv_pipe_write_impl(uv_loop_t* loop, req->u.io.queued_bytes = 0; } else { /* Request queued by the kernel. */ - req->u.io.queued_bytes = uv__count_bufs(bufs, nbufs); + req->u.io.queued_bytes = bufs[0].len; handle->write_queue_size += req->u.io.queued_bytes; } diff --git a/deps/uv/src/win/req-inl.h b/deps/uv/src/win/req-inl.h index a44d9c362..b5e502eef 100644 --- a/deps/uv/src/win/req-inl.h +++ b/deps/uv/src/win/req-inl.h @@ -93,6 +93,17 @@ INLINE static uv_req_t* uv_overlapped_to_req(OVERLAPPED* overlapped) { INLINE static void uv_insert_pending_req(uv_loop_t* loop, uv_req_t* req) { req->next_req = NULL; if (loop->pending_reqs_tail) { +#ifdef _DEBUG + /* Ensure the request is not already in the queue, or the queue + * will get corrupted. + */ + uv_req_t* current = loop->pending_reqs_tail; + do { + assert(req != current); + current = current->next_req; + } while(current != loop->pending_reqs_tail); +#endif + req->next_req = loop->pending_reqs_tail->next_req; loop->pending_reqs_tail->next_req = req; loop->pending_reqs_tail = req; |