summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexis Campailla <alexis@janeasystems.com>2015-03-03 12:44:32 -0700
committerJulien Gilli <julien.gilli@joyent.com>2015-03-10 16:19:16 -0700
commitd6d89e353b219f6bddb5379051779a6a2121119b (patch)
treeedd1b9f3132b8da8998f35c2a4d44fa7999f4da9
parent91185f08771459145bf2b61188059dc0a305f315 (diff)
downloadnode-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.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 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;