win: use uv_req_t.overlapped.Internal field to propagate request errors

This commit is contained in:
Bert Belder 2011-08-23 20:36:52 +02:00
parent 811828719f
commit 5cae6e4e57
6 changed files with 58 additions and 37 deletions

View File

@ -157,8 +157,7 @@ typedef struct uv_buf_t {
#define UV_HANDLE_PRIVATE_FIELDS \
uv_handle_t* endgame_next; \
unsigned int flags; \
uv_err_t error;
unsigned int flags;
#define UV_ARES_TASK_PRIVATE_FIELDS \
struct uv_req_s ares_req; \

View File

@ -111,10 +111,6 @@ static void uv_poll(int block) {
/* Package was dequeued */
req = uv_overlapped_to_req(overlapped);
if (!success) {
req->error = uv_new_sys_error(GetLastError());
}
uv_insert_pending_req(req);
} else if (GetLastError() != WAIT_TIMEOUT) {
@ -150,10 +146,6 @@ static void uv_poll_ex(int block) {
for (i = 0; i < count; i++) {
/* Package was dequeued */
req = uv_overlapped_to_req(overlappeds[i].lpOverlapped);
if (overlappeds[i].lpOverlapped->Internal != STATUS_SUCCESS) {
req->error = uv_new_sys_error(pRtlNtStatusToDosError(
overlappeds[i].lpOverlapped->Internal));
}
uv_insert_pending_req(req);
}
} else if (GetLastError() != WAIT_TIMEOUT) {

View File

@ -142,7 +142,6 @@ void uv_insert_pending_req(uv_req_t* req);
void uv_process_reqs();
#define POST_COMPLETION_FOR_REQ(req) \
memset(&((req)->overlapped), 0, sizeof((req)->overlapped)); \
if (!PostQueuedCompletionStatus(LOOP->iocp, \
0, \
0, \
@ -252,6 +251,33 @@ uv_err_t uv_new_sys_error(int sys_errno);
void uv_set_sys_error(int sys_errno);
void uv_set_error(uv_err_code code, int sys_errno);
#define SET_REQ_STATUS(req, status) \
(req)->overlapped.Internal = (ULONG_PTR) (status)
#define SET_REQ_ERROR(req, error) \
SET_REQ_STATUS((req), NTSTATUS_FROM_WIN32((error)))
#define SET_REQ_SUCCESS(req) \
SET_REQ_STATUS((req), STATUS_SUCCESS)
#define GET_REQ_STATUS(req) \
((req)->overlapped.Internal)
#define REQ_SUCCESS(req) \
(NT_SUCCESS(GET_REQ_STATUS((req))))
#define GET_REQ_ERROR(req) \
(pRtlNtStatusToDosError(GET_REQ_STATUS((req))))
#define GET_REQ_SOCK_ERROR(req) \
(uv_ntstatus_to_winsock_error(GET_REQ_STATUS((req))))
#define GET_REQ_UV_ERROR(req) \
(uv_new_sys_error(GET_REQ_ERROR((req))))
#define GET_REQ_UV_SOCK_ERROR(req) \
(uv_new_sys_error(GET_REQ_SOCK_ERROR((req))))
/*
* Initialization for the windows and winsock api

View File

@ -364,9 +364,9 @@ static DWORD WINAPI pipe_connect_thread_proc(void* parameter) {
if (pipeHandle != INVALID_HANDLE_VALUE && !uv_set_pipe_handle(handle, pipeHandle)) {
handle->handle = pipeHandle;
req->error = uv_ok_;
SET_REQ_SUCCESS(req);
} else {
req->error = uv_new_sys_error(GetLastError());
SET_REQ_ERROR(req, GetLastError());
}
/* Post completed */
@ -432,7 +432,7 @@ int uv_pipe_connect(uv_connect_t* req, uv_pipe_t* handle,
handle->handle = pipeHandle;
req->error = uv_ok_;
SET_REQ_SUCCESS(req);
uv_insert_pending_req((uv_req_t*) req);
handle->reqs_pending++;
return 0;
@ -495,7 +495,7 @@ static void uv_pipe_queue_accept(uv_pipe_t* handle, uv_pipe_accept_t* req, BOOL
NULL);
if (req->pipeHandle == INVALID_HANDLE_VALUE) {
req->error = uv_new_sys_error(GetLastError());
SET_REQ_ERROR(req, GetLastError());
uv_insert_pending_req((uv_req_t*) req);
handle->reqs_pending++;
return;
@ -504,7 +504,7 @@ static void uv_pipe_queue_accept(uv_pipe_t* handle, uv_pipe_accept_t* req, BOOL
if (uv_set_pipe_handle(handle, req->pipeHandle)) {
CloseHandle(req->pipeHandle);
req->pipeHandle = INVALID_HANDLE_VALUE;
req->error = uv_new_sys_error(GetLastError());
SET_REQ_ERROR(req, GetLastError());
uv_insert_pending_req((uv_req_t*) req);
handle->reqs_pending++;
return;
@ -518,12 +518,12 @@ static void uv_pipe_queue_accept(uv_pipe_t* handle, uv_pipe_accept_t* req, BOOL
if (!ConnectNamedPipe(req->pipeHandle, &req->overlapped) && GetLastError() != ERROR_IO_PENDING) {
if (GetLastError() == ERROR_PIPE_CONNECTED) {
req->error = uv_ok_;
SET_REQ_SUCCESS(req);
} else {
CloseHandle(req->pipeHandle);
req->pipeHandle = INVALID_HANDLE_VALUE;
/* Make this req pending reporting an error. */
req->error = uv_new_sys_error(GetLastError());
SET_REQ_ERROR(req, GetLastError());
}
uv_insert_pending_req((uv_req_t*) req);
handle->reqs_pending++;
@ -640,7 +640,7 @@ static void uv_pipe_queue_read(uv_pipe_t* handle) {
if (!result && GetLastError() != ERROR_IO_PENDING) {
/* Make this req pending reporting an error. */
req->error = uv_new_sys_error(WSAGetLastError());
SET_REQ_ERROR(req, WSAGetLastError());
uv_insert_pending_req(req);
handle->reqs_pending++;
return;
@ -742,12 +742,12 @@ void uv_process_pipe_read_req(uv_pipe_t* handle, uv_req_t* req) {
handle->flags &= ~UV_HANDLE_READ_PENDING;
if (req->error.code != UV_OK) {
if (!REQ_SUCCESS(req)) {
/* An error occurred doing the 0-read. */
if (handle->flags & UV_HANDLE_READING) {
/* Stop reading and report error. */
handle->flags &= ~UV_HANDLE_READING;
LOOP->last_error = req->error;
LOOP->last_error = GET_REQ_UV_ERROR(req);
buf.base = 0;
buf.len = 0;
handle->read_cb((uv_stream_t*)handle, -1, buf);
@ -812,8 +812,12 @@ void uv_process_pipe_write_req(uv_pipe_t* handle, uv_write_t* req) {
handle->write_queue_size -= req->queued_bytes;
if (req->cb) {
LOOP->last_error = req->error;
((uv_write_cb)req->cb)(req, LOOP->last_error.code == UV_OK ? 0 : -1);
if (!REQ_SUCCESS(req)) {
LOOP->last_error = GET_REQ_UV_ERROR(req);
((uv_write_cb)req->cb)(req, -1);
} else {
((uv_write_cb)req->cb)(req, 0);
}
}
handle->write_reqs_pending--;
@ -831,7 +835,7 @@ void uv_process_pipe_accept_req(uv_pipe_t* handle, uv_req_t* raw_req) {
assert(handle->type == UV_NAMED_PIPE);
if (req->error.code == UV_OK) {
if (REQ_SUCCESS(req)) {
assert(req->pipeHandle != INVALID_HANDLE_VALUE);
req->next_pending = handle->pending_accepts;
handle->pending_accepts = req;
@ -858,11 +862,11 @@ void uv_process_pipe_connect_req(uv_pipe_t* handle, uv_connect_t* req) {
assert(handle->type == UV_NAMED_PIPE);
if (req->cb) {
if (req->error.code == UV_OK) {
if (REQ_SUCCESS(req)) {
uv_connection_init((uv_stream_t*)handle);
((uv_connect_cb)req->cb)(req, 0);
} else {
LOOP->last_error = req->error;
LOOP->last_error = GET_REQ_UV_ERROR(req);
((uv_connect_cb)req->cb)(req, -1);
}
}

View File

@ -29,7 +29,7 @@
void uv_req_init(uv_req_t* req) {
uv_counters()->req_init++;
req->type = UV_UNKNOWN_REQ;
req->error = uv_ok_;
SET_REQ_SUCCESS(req);
}

View File

@ -235,7 +235,7 @@ static void uv_tcp_queue_accept(uv_tcp_t* handle, uv_tcp_accept_t* req) {
/* Open a socket for the accepted connection. */
accept_socket = socket(family, SOCK_STREAM, 0);
if (accept_socket == INVALID_SOCKET) {
req->error = uv_new_sys_error(WSAGetLastError());
SET_REQ_ERROR(req, WSAGetLastError());
uv_insert_pending_req((uv_req_t*)req);
handle->reqs_pending++;
return;
@ -264,7 +264,7 @@ static void uv_tcp_queue_accept(uv_tcp_t* handle, uv_tcp_accept_t* req) {
handle->reqs_pending++;
} else {
/* Make this req pending reporting an error. */
req->error = uv_new_sys_error(WSAGetLastError());
SET_REQ_ERROR(req, WSAGetLastError());
uv_insert_pending_req((uv_req_t*)req);
handle->reqs_pending++;
/* Destroy the preallocated client socket. */
@ -321,7 +321,7 @@ static void uv_tcp_queue_read(uv_tcp_t* handle) {
handle->reqs_pending++;
} else {
/* Make this req pending reporting an error. */
req->error = uv_new_sys_error(WSAGetLastError());
SET_REQ_ERROR(req, WSAGetLastError());
uv_insert_pending_req(req);
handle->reqs_pending++;
}
@ -625,11 +625,11 @@ void uv_process_tcp_read_req(uv_tcp_t* handle, uv_req_t* req) {
handle->flags &= ~UV_HANDLE_READ_PENDING;
if (req->error.code != UV_OK) {
if (!REQ_SUCCESS(req)) {
/* An error occurred doing the read. */
if ((handle->flags & UV_HANDLE_READING)) {
handle->flags &= ~UV_HANDLE_READING;
LOOP->last_error = req->error;
LOOP->last_error = GET_REQ_UV_SOCK_ERROR(req);
buf = (handle->flags & UV_HANDLE_ZERO_READ) ?
uv_buf_init(NULL, 0) : handle->read_buffer;
handle->read_cb((uv_stream_t*)handle, -1, buf);
@ -718,7 +718,7 @@ void uv_process_tcp_write_req(uv_tcp_t* handle, uv_write_t* req) {
handle->write_queue_size -= req->queued_bytes;
if (req->cb) {
LOOP->last_error = req->error;
LOOP->last_error = GET_REQ_UV_SOCK_ERROR(req);
((uv_write_cb)req->cb)(req, LOOP->last_error.code == UV_OK ? 0 : -1);
}
@ -745,11 +745,11 @@ void uv_process_tcp_accept_req(uv_tcp_t* handle, uv_req_t* raw_req) {
if (handle->flags & UV_HANDLE_LISTENING) {
handle->flags &= ~UV_HANDLE_LISTENING;
if (handle->connection_cb) {
LOOP->last_error = req->error;
LOOP->last_error = GET_REQ_UV_SOCK_ERROR(req);
handle->connection_cb((uv_stream_t*)handle, -1);
}
}
} else if (req->error.code == UV_OK &&
} else if (REQ_SUCCESS(req) &&
setsockopt(req->accept_socket,
SOL_SOCKET,
SO_UPDATE_ACCEPT_CONTEXT,
@ -781,7 +781,7 @@ void uv_process_tcp_connect_req(uv_tcp_t* handle, uv_connect_t* req) {
assert(handle->type == UV_TCP);
if (req->cb) {
if (req->error.code == UV_OK) {
if (REQ_SUCCESS(req)) {
if (setsockopt(handle->socket,
SOL_SOCKET,
SO_UPDATE_CONNECT_CONTEXT,
@ -795,7 +795,7 @@ void uv_process_tcp_connect_req(uv_tcp_t* handle, uv_connect_t* req) {
((uv_connect_cb)req->cb)(req, -1);
}
} else {
LOOP->last_error = req->error;
LOOP->last_error = GET_REQ_UV_SOCK_ERROR(req);
((uv_connect_cb)req->cb)(req, -1);
}
}