Skip to content
This repository has been archived by the owner on May 4, 2018. It is now read-only.

Commit

Permalink
win: use uv_req_t.overlapped.Internal field to propagate request errors
Browse files Browse the repository at this point in the history
  • Loading branch information
piscisaureus committed Aug 23, 2011
1 parent 8118287 commit 5cae6e4
Show file tree
Hide file tree
Showing 6 changed files with 58 additions and 37 deletions.
3 changes: 1 addition & 2 deletions include/uv-win.h
Expand Up @@ -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; \
Expand Down
8 changes: 0 additions & 8 deletions src/win/core.c
Expand Up @@ -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) {
Expand Down Expand Up @@ -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) {
Expand Down
28 changes: 27 additions & 1 deletion src/win/internal.h
Expand Up @@ -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, \
Expand Down Expand Up @@ -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
Expand Down
34 changes: 19 additions & 15 deletions src/win/pipe.c
Expand Up @@ -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 */
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand All @@ -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;
Expand All @@ -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++;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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--;
Expand All @@ -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;
Expand All @@ -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);
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/win/req.c
Expand Up @@ -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);
}


Expand Down
20 changes: 10 additions & 10 deletions src/win/tcp.c
Expand Up @@ -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;
Expand Down Expand Up @@ -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. */
Expand Down Expand Up @@ -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++;
}
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
}

Expand All @@ -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,
Expand Down Expand Up @@ -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,
Expand All @@ -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);
}
}
Expand Down

0 comments on commit 5cae6e4

Please sign in to comment.