summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexis Campailla <alexis@janeasystems.com>2015-03-03 12:44:32 -0700
committerTrevor Norris <trev.norris@gmail.com>2015-03-19 12:06:56 -0700
commit3cce8ab647ff50eb309e87d165f3bcb3eab62e50 (patch)
tree868682549f8aba2d42230b9925b73f578c333846
parent2411bea0dfa9d48f94f95119bbacce122509681e (diff)
downloadnode-3cce8ab647ff50eb309e87d165f3bcb3eab62e50.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 Reviewed-By: Julien Gilli <julien.gilli@joyent.com> PR-URL: https://github.com/joyent/node/pull/9179
-rw-r--r--deps/uv/src/win/pipe.c12
-rw-r--r--deps/uv/src/win/req-inl.h11
2 files changed, 17 insertions, 6 deletions
diff --git a/deps/uv/src/win/pipe.c b/deps/uv/src/win/pipe.c
index 57fab065a..8039cac3c 100644
--- a/deps/uv/src/win/pipe.c
+++ b/deps/uv/src/win/pipe.c
@@ -1347,7 +1347,7 @@ static int uv_pipe_write_impl(uv_loop_t* loop,
}
/* Request queued by the kernel. */
- req->queued_bytes = uv__count_bufs(bufs, nbufs);
+ req->queued_bytes = bufs[0].len;
handle->write_queue_size += req->queued_bytes;
} else if (handle->flags & UV_HANDLE_BLOCKING_WRITES) {
/* Using overlapped IO, but wait for completion before returning */
@@ -1372,12 +1372,13 @@ static int uv_pipe_write_impl(uv_loop_t* loop,
/* Request completed immediately. */
req->queued_bytes = 0;
} else {
- assert(ipc_header_req != NULL);
/* Request queued by the kernel. */
- if (WaitForSingleObject(ipc_header_req->overlapped.hEvent, INFINITE) !=
+ req->queued_bytes = bufs[0].len;
+ handle->write_queue_size += req->queued_bytes;
+ if (WaitForSingleObject(req->overlapped.hEvent, INFINITE) !=
WAIT_OBJECT_0) {
err = GetLastError();
- CloseHandle(ipc_header_req->overlapped.hEvent);
+ CloseHandle(req->overlapped.hEvent);
return uv_translate_sys_error(err);
}
}
@@ -1386,7 +1387,6 @@ static int uv_pipe_write_impl(uv_loop_t* loop,
REGISTER_HANDLE_REQ(loop, handle, req);
handle->reqs_pending++;
handle->write_reqs_pending++;
- POST_COMPLETION_FOR_REQ(loop, req);
return 0;
} else {
result = WriteFile(handle->handle,
@@ -1404,7 +1404,7 @@ static int uv_pipe_write_impl(uv_loop_t* loop,
req->queued_bytes = 0;
} else {
/* Request queued by the kernel. */
- req->queued_bytes = uv__count_bufs(bufs, nbufs);
+ req->queued_bytes = bufs[0].len;
handle->write_queue_size += req->queued_bytes;
}
diff --git a/deps/uv/src/win/req-inl.h b/deps/uv/src/win/req-inl.h
index 46c7d9b10..0c825a3cd 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;