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. PR-URL: https://github.com/libuv/libuv/pull/238 Reviewed-By: Bert Belder <bertbelder@gmail.com>
This commit is contained in:
parent
fc9e66e555
commit
c7ebe68fbc
@ -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;
|
||||
}
|
||||
|
||||
|
||||
@ -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;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user