void uv_process_tcp_connect_req(uv_loop_t* loop, uv_tcp_t* handle, uv_connect_t* req) { int err; assert(handle->type == UV_TCP); UNREGISTER_HANDLE_REQ(loop, handle, req); err = 0; if (REQ_SUCCESS(req)) { if (setsockopt(handle->socket, SOL_SOCKET, SO_UPDATE_CONNECT_CONTEXT, NULL, 0) == 0) { uv_connection_init((uv_stream_t*)handle); handle->flags |= UV_HANDLE_READABLE | UV_HANDLE_WRITABLE; loop->active_tcp_streams++; } else { err = WSAGetLastError(); } } else { err = GET_REQ_SOCK_ERROR(req); } req->cb(req, uv_translate_sys_error(err)); DECREASE_PENDING_REQ_COUNT(handle); }
void uv_process_tcp_write_req(uv_loop_t* loop, uv_tcp_t* handle, uv_write_t* req) { int err; assert(handle->type == UV_TCP); assert(handle->write_queue_size >= req->queued_bytes); handle->write_queue_size -= req->queued_bytes; UNREGISTER_HANDLE_REQ(loop, handle, req); if (handle->flags & UV_HANDLE_EMULATE_IOCP) { if (req->wait_handle != INVALID_HANDLE_VALUE) { pUnregisterWait(req->wait_handle); req->wait_handle = INVALID_HANDLE_VALUE; } if (req->event_handle) { CloseHandle(req->event_handle); req->event_handle = NULL; } } if (req->cb) { err = GET_REQ_SOCK_ERROR(req); req->cb(req, uv_translate_sys_error(err)); } handle->write_reqs_pending--; if (handle->shutdown_req != NULL && handle->write_reqs_pending == 0) { uv_want_endgame(loop, (uv_handle_t*)handle); } DECREASE_PENDING_REQ_COUNT(handle); }
static void uv__fast_poll_process_poll_req(uv_loop_t* loop, uv_poll_t* handle, uv_req_t* req) { unsigned char mask_events; AFD_POLL_INFO* afd_poll_info; if (req == &handle->poll_req_1) { afd_poll_info = &handle->afd_poll_info_1; handle->submitted_events_1 = 0; mask_events = handle->mask_events_1; } else if (req == &handle->poll_req_2) { afd_poll_info = &handle->afd_poll_info_2; handle->submitted_events_2 = 0; mask_events = handle->mask_events_2; } else { assert(0); } /* Report an error unless the select was just interrupted. */ if (!REQ_SUCCESS(req)) { DWORD error = GET_REQ_SOCK_ERROR(req); if (error != WSAEINTR && handle->events != 0) { handle->events = 0; /* Stop the watcher */ uv__set_sys_error(loop, error); handle->poll_cb(handle, -1, 0); } } else if (afd_poll_info->NumberOfHandles >= 1) { unsigned char events = 0; if ((afd_poll_info->Handles[0].Events & (AFD_POLL_RECEIVE | AFD_POLL_DISCONNECT | AFD_POLL_ACCEPT | AFD_POLL_ABORT)) != 0) { events |= UV_READABLE; } if ((afd_poll_info->Handles[0].Events & (AFD_POLL_SEND | AFD_POLL_CONNECT_FAIL)) != 0) { events |= UV_WRITABLE; } events &= handle->events & ~mask_events; if (afd_poll_info->Handles[0].Events & AFD_POLL_LOCAL_CLOSE) { /* Stop polling. */ handle->events = 0; uv__handle_stop(handle); } if (events != 0) { handle->poll_cb(handle, 0, events); } } if ((handle->events & ~(handle->submitted_events_1 | handle->submitted_events_2)) != 0) { uv__fast_poll_submit_poll_req(loop, handle); } else if ((handle->flags & UV_HANDLE_CLOSING) && handle->submitted_events_1 == 0 && handle->submitted_events_2 == 0) { uv_want_endgame(loop, (uv_handle_t*) handle); } }
void uv_process_tcp_connect_req(uv_loop_t* loop, uv_tcp_t* handle, uv_connect_t* req) { assert(handle->type == UV_TCP); if (req->cb) { if (REQ_SUCCESS(req)) { if (setsockopt(handle->socket, SOL_SOCKET, SO_UPDATE_CONNECT_CONTEXT, NULL, 0) == 0) { uv_connection_init((uv_stream_t*)handle); active_tcp_streams++; ((uv_connect_cb)req->cb)(req, 0); } else { uv__set_sys_error(loop, WSAGetLastError()); ((uv_connect_cb)req->cb)(req, -1); } } else { uv__set_sys_error(loop, GET_REQ_SOCK_ERROR(req)); ((uv_connect_cb)req->cb)(req, -1); } } DECREASE_PENDING_REQ_COUNT(handle); }
void uv_process_tcp_write_req(uv_loop_t* loop, uv_tcp_t* handle, uv_write_t* req) { assert(handle->type == UV_TCP); assert(handle->write_queue_size >= req->queued_bytes); handle->write_queue_size -= req->queued_bytes; if (handle->flags & UV_HANDLE_EMULATE_IOCP) { if (req->wait_handle != INVALID_HANDLE_VALUE) { UnregisterWait(req->wait_handle); } if (req->event_handle) { CloseHandle(req->event_handle); } } if (req->cb) { uv__set_sys_error(loop, GET_REQ_SOCK_ERROR(req)); ((uv_write_cb)req->cb)(req, loop->last_err.code == UV_OK ? 0 : -1); } handle->write_reqs_pending--; if (handle->flags & UV_HANDLE_SHUTTING && handle->write_reqs_pending == 0) { uv_want_endgame(loop, (uv_handle_t*)handle); } DECREASE_PENDING_REQ_COUNT(handle); uv_unref(loop); }
void uv_process_udp_send_req(uv_loop_t* loop, uv_udp_t* handle, uv_udp_send_t* req) { assert(handle->type == UV_UDP); if (req->cb) { if (REQ_SUCCESS(req)) { req->cb(req, 0); } else { uv__set_sys_error(loop, GET_REQ_SOCK_ERROR(req)); req->cb(req, -1); } } DECREASE_PENDING_REQ_COUNT(handle); }
void uv_process_tcp_accept_req(uv_loop_t* loop, uv_tcp_t* handle, uv_req_t* raw_req) { uv_tcp_accept_t* req = (uv_tcp_accept_t*) raw_req; int err; assert(handle->type == UV_TCP); /* If handle->accepted_socket is not a valid socket, then */ /* uv_queue_accept must have failed. This is a serious error. We stop */ /* accepting connections and report this error to the connection */ /* callback. */ if (req->accept_socket == INVALID_SOCKET) { if (handle->flags & UV_HANDLE_LISTENING) { handle->flags &= ~UV_HANDLE_LISTENING; DECREASE_ACTIVE_COUNT(loop, handle); if (handle->connection_cb) { err = GET_REQ_SOCK_ERROR(req); handle->connection_cb((uv_stream_t*)handle, uv_translate_sys_error(err)); } } } else if (REQ_SUCCESS(req) && setsockopt(req->accept_socket, SOL_SOCKET, SO_UPDATE_ACCEPT_CONTEXT, (char*)&handle->socket, sizeof(handle->socket)) == 0) { req->next_pending = handle->pending_accepts; handle->pending_accepts = req; /* Accept and SO_UPDATE_ACCEPT_CONTEXT were successful. */ if (handle->connection_cb) { handle->connection_cb((uv_stream_t*)handle, 0); } } else { /* Error related to accepted socket is ignored because the server */ /* socket may still be healthy. If the server socket is broken */ /* uv_queue_accept will detect it. */ closesocket(req->accept_socket); req->accept_socket = INVALID_SOCKET; if (handle->flags & UV_HANDLE_LISTENING) { uv_tcp_queue_accept(handle, req); } } DECREASE_PENDING_REQ_COUNT(handle); }
void uv_process_udp_send_req(uv_loop_t* loop, uv_udp_t* handle, uv_udp_send_t* req) { int err; assert(handle->type == UV_UDP); UNREGISTER_HANDLE_REQ(loop, handle, req); if (req->cb) { err = 0; if (!REQ_SUCCESS(req)) { err = GET_REQ_SOCK_ERROR(req); } req->cb(req, uv_translate_sys_error(err)); } DECREASE_PENDING_REQ_COUNT(handle); }
void uv_process_tcp_write_req(uv_loop_t* loop, uv_tcp_t* handle, uv_write_t* req) { assert(handle->type == UV_TCP); handle->write_queue_size -= req->queued_bytes; if (req->cb) { uv__set_sys_error(loop, GET_REQ_SOCK_ERROR(req)); ((uv_write_cb)req->cb)(req, loop->last_err.code == UV_OK ? 0 : -1); } handle->write_reqs_pending--; if (handle->flags & UV_HANDLE_SHUTTING && handle->write_reqs_pending == 0) { uv_want_endgame(loop, (uv_handle_t*)handle); } DECREASE_PENDING_REQ_COUNT(handle); }
void uv_process_tcp_write_req(uv_loop_t* loop, uv_tcp_t* handle, uv_write_t* req) { int err; assert(handle->type == UV_TCP); assert(handle->write_queue_size >= req->u.io.queued_bytes); handle->write_queue_size -= req->u.io.queued_bytes; UNREGISTER_HANDLE_REQ(loop, handle, req); if (handle->flags & UV_HANDLE_EMULATE_IOCP) { if (req->wait_handle != INVALID_HANDLE_VALUE) { UnregisterWait(req->wait_handle); req->wait_handle = INVALID_HANDLE_VALUE; } if (req->event_handle) { CloseHandle(req->event_handle); req->event_handle = NULL; } } if (req->cb) { err = uv_translate_sys_error(GET_REQ_SOCK_ERROR(req)); if (err == UV_ECONNABORTED) { /* use UV_ECANCELED for consistency with Unix */ err = UV_ECANCELED; } req->cb(req, err); } handle->stream.conn.write_reqs_pending--; if (handle->stream.conn.shutdown_req != NULL && handle->stream.conn.write_reqs_pending == 0) { uv_want_endgame(loop, (uv_handle_t*)handle); } DECREASE_PENDING_REQ_COUNT(handle); }
void uv_process_udp_recv_req(uv_loop_t* loop, uv_udp_t* handle, uv_req_t* req) { uv_buf_t buf; int partial; assert(handle->type == UV_UDP); handle->flags &= ~UV_HANDLE_READ_PENDING; if (!REQ_SUCCESS(req)) { DWORD err = GET_REQ_SOCK_ERROR(req); if (err == WSAEMSGSIZE) { /* Not a real error, it just indicates that the received packet */ /* was bigger than the receive buffer. */ } else if (err == WSAECONNRESET || err == WSAENETRESET) { /* A previous sendto operation failed; ignore this error. If */ /* zero-reading we need to call WSARecv/WSARecvFrom _without_ the */ /* MSG_PEEK flag to clear out the error queue. For nonzero reads, */ /* immediately queue a new receive. */ if (!(handle->flags & UV_HANDLE_ZERO_READ)) { goto done; } } else { /* A real error occurred. Report the error to the user only if we're */ /* currently reading. */ if (handle->flags & UV_HANDLE_READING) { uv__set_sys_error(loop, err); uv_udp_recv_stop(handle); buf = (handle->flags & UV_HANDLE_ZERO_READ) ? uv_buf_init(NULL, 0) : handle->recv_buffer; handle->recv_cb(handle, -1, buf, NULL, 0); } goto done; } } if (!(handle->flags & UV_HANDLE_ZERO_READ)) { /* Successful read */ partial = !REQ_SUCCESS(req); handle->recv_cb(handle, req->overlapped.InternalHigh, handle->recv_buffer, (struct sockaddr*) &handle->recv_from, partial ? UV_UDP_PARTIAL : 0); } else if (handle->flags & UV_HANDLE_READING) { DWORD bytes, err, flags; struct sockaddr_storage from; int from_len; /* Do a nonblocking receive */ /* TODO: try to read multiple datagrams at once. FIONREAD maybe? */ buf = handle->alloc_cb((uv_handle_t*) handle, 65536); assert(buf.len > 0); memset(&from, 0, sizeof from); from_len = sizeof from; flags = 0; if (WSARecvFrom(handle->socket, (WSABUF*)&buf, 1, &bytes, &flags, (struct sockaddr*) &from, &from_len, NULL, NULL) != SOCKET_ERROR) { /* Message received */ handle->recv_cb(handle, bytes, buf, (struct sockaddr*) &from, 0); } else { err = WSAGetLastError(); if (err == WSAEMSGSIZE) { /* Message truncated */ handle->recv_cb(handle, bytes, buf, (struct sockaddr*) &from, UV_UDP_PARTIAL); } if (err == WSAEWOULDBLOCK) { /* Kernel buffer empty */ uv__set_sys_error(loop, WSAEWOULDBLOCK); handle->recv_cb(handle, 0, buf, NULL, 0); } else if (err != WSAECONNRESET && err != WSAENETRESET) { /* Serious error. WSAECONNRESET/WSANETRESET is ignored because this */ /* just indicates that a previous sendto operation failed. */ uv_udp_recv_stop(handle); uv__set_sys_error(loop, err); handle->recv_cb(handle, -1, buf, NULL, 0); } } } done: /* Post another read if still reading and not closing. */ if ((handle->flags & UV_HANDLE_READING) && !(handle->flags & UV_HANDLE_READ_PENDING)) { uv_udp_queue_recv(loop, handle); } DECREASE_PENDING_REQ_COUNT(handle); }
void uv_process_tcp_read_req(uv_loop_t* loop, uv_tcp_t* handle, uv_req_t* req) { DWORD bytes, flags, err; uv_buf_t buf; assert(handle->type == UV_TCP); handle->flags &= ~UV_HANDLE_READ_PENDING; if (!REQ_SUCCESS(req)) { /* An error occurred doing the read. */ if ((handle->flags & UV_HANDLE_READING) || !(handle->flags & UV_HANDLE_ZERO_READ)) { handle->flags &= ~UV_HANDLE_READING; DECREASE_ACTIVE_COUNT(loop, handle); buf = (handle->flags & UV_HANDLE_ZERO_READ) ? uv_buf_init(NULL, 0) : handle->read_buffer; err = GET_REQ_SOCK_ERROR(req); if (err == WSAECONNABORTED) { /* * Turn WSAECONNABORTED into UV_ECONNRESET to be consistent with Unix. */ err = WSAECONNRESET; } handle->read_cb((uv_stream_t*)handle, uv_translate_sys_error(err), &buf); } } else { if (!(handle->flags & UV_HANDLE_ZERO_READ)) { /* The read was done with a non-zero buffer length. */ if (req->overlapped.InternalHigh > 0) { /* Successful read */ handle->read_cb((uv_stream_t*)handle, req->overlapped.InternalHigh, &handle->read_buffer); /* Read again only if bytes == buf.len */ if (req->overlapped.InternalHigh < handle->read_buffer.len) { goto done; } } else { /* Connection closed */ if (handle->flags & UV_HANDLE_READING) { handle->flags &= ~UV_HANDLE_READING; DECREASE_ACTIVE_COUNT(loop, handle); } handle->flags &= ~UV_HANDLE_READABLE; buf.base = 0; buf.len = 0; handle->read_cb((uv_stream_t*)handle, UV_EOF, &handle->read_buffer); goto done; } } /* Do nonblocking reads until the buffer is empty */ while (handle->flags & UV_HANDLE_READING) { handle->alloc_cb((uv_handle_t*) handle, 65536, &buf); if (buf.len == 0) { handle->read_cb((uv_stream_t*) handle, UV_ENOBUFS, &buf); break; } assert(buf.base != NULL); flags = 0; if (WSARecv(handle->socket, (WSABUF*)&buf, 1, &bytes, &flags, NULL, NULL) != SOCKET_ERROR) { if (bytes > 0) { /* Successful read */ handle->read_cb((uv_stream_t*)handle, bytes, &buf); /* Read again only if bytes == buf.len */ if (bytes < buf.len) { break; } } else { /* Connection closed */ handle->flags &= ~(UV_HANDLE_READING | UV_HANDLE_READABLE); DECREASE_ACTIVE_COUNT(loop, handle); handle->read_cb((uv_stream_t*)handle, UV_EOF, &buf); break; } } else { err = WSAGetLastError(); if (err == WSAEWOULDBLOCK) { /* Read buffer was completely empty, report a 0-byte read. */ handle->read_cb((uv_stream_t*)handle, 0, &buf); } else { /* Ouch! serious error. */ handle->flags &= ~UV_HANDLE_READING; DECREASE_ACTIVE_COUNT(loop, handle); if (err == WSAECONNABORTED) { /* Turn WSAECONNABORTED into UV_ECONNRESET to be consistent with */ /* Unix. */ err = WSAECONNRESET; } handle->read_cb((uv_stream_t*)handle, uv_translate_sys_error(err), &buf); } break; } } done: /* Post another read if still reading and not closing. */ if ((handle->flags & UV_HANDLE_READING) && !(handle->flags & UV_HANDLE_READ_PENDING)) { uv_tcp_queue_read(loop, handle); } } DECREASE_PENDING_REQ_COUNT(handle); }
void uv_process_tcp_read_req(uv_loop_t* loop, uv_tcp_t* handle, uv_req_t* req) { DWORD bytes, flags, err; uv_buf_t buf; assert(handle->type == UV_TCP); handle->flags &= ~UV_HANDLE_READ_PENDING; if (!REQ_SUCCESS(req)) { /* An error occurred doing the read. */ if ((handle->flags & UV_HANDLE_READING)) { handle->flags &= ~UV_HANDLE_READING; uv__set_sys_error(loop, GET_REQ_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); } } else { if (!(handle->flags & UV_HANDLE_ZERO_READ)) { /* The read was done with a non-zero buffer length. */ if (req->overlapped.InternalHigh > 0) { /* Successful read */ handle->read_cb((uv_stream_t*)handle, req->overlapped.InternalHigh, handle->read_buffer); /* Read again only if bytes == buf.len */ if (req->overlapped.InternalHigh < handle->read_buffer.len) { goto done; } } else { /* Connection closed */ handle->flags &= ~UV_HANDLE_READING; handle->flags |= UV_HANDLE_EOF; uv__set_error(loop, UV_EOF, ERROR_SUCCESS); buf.base = 0; buf.len = 0; handle->read_cb((uv_stream_t*)handle, -1, handle->read_buffer); goto done; } } /* Do nonblocking reads until the buffer is empty */ while (handle->flags & UV_HANDLE_READING) { buf = handle->alloc_cb((uv_handle_t*) handle, 65536); assert(buf.len > 0); flags = 0; if (WSARecv(handle->socket, (WSABUF*)&buf, 1, &bytes, &flags, NULL, NULL) != SOCKET_ERROR) { if (bytes > 0) { /* Successful read */ handle->read_cb((uv_stream_t*)handle, bytes, buf); /* Read again only if bytes == buf.len */ if (bytes < buf.len) { break; } } else { /* Connection closed */ handle->flags &= ~UV_HANDLE_READING; handle->flags |= UV_HANDLE_EOF; uv__set_error(loop, UV_EOF, ERROR_SUCCESS); handle->read_cb((uv_stream_t*)handle, -1, buf); break; } } else { err = WSAGetLastError(); if (err == WSAEWOULDBLOCK) { /* Read buffer was completely empty, report a 0-byte read. */ uv__set_sys_error(loop, WSAEWOULDBLOCK); handle->read_cb((uv_stream_t*)handle, 0, buf); } else { /* Ouch! serious error. */ uv__set_sys_error(loop, err); handle->flags &= ~UV_HANDLE_READING; handle->read_cb((uv_stream_t*)handle, -1, buf); } break; } } done: /* Post another read if still reading and not closing. */ if ((handle->flags & UV_HANDLE_READING) && !(handle->flags & UV_HANDLE_READ_PENDING)) { uv_tcp_queue_read(loop, handle); } } DECREASE_PENDING_REQ_COUNT(handle); }
void uv_process_udp_recv_req(uv_loop_t* loop, uv_udp_t* handle, uv_req_t* req) { uv_buf_t buf; int partial; assert(handle->type == UV_UDP); handle->flags &= ~UV_HANDLE_READ_PENDING; if (!REQ_SUCCESS(req) && GET_REQ_STATUS(req) != STATUS_RECEIVE_EXPEDITED) { /* An error occurred doing the read. */ if ((handle->flags & UV_HANDLE_READING)) { uv__set_sys_error(loop, GET_REQ_SOCK_ERROR(req)); uv_udp_recv_stop(handle); #if 0 buf = (handle->flags & UV_HANDLE_ZERO_READ) ? uv_buf_init(NULL, 0) : handle->recv_buffer; #else buf = handle->recv_buffer; #endif handle->recv_cb(handle, -1, buf, NULL, 0); } goto done; } #if 0 if (!(handle->flags & UV_HANDLE_ZERO_READ)) { #endif /* Successful read */ partial = (GET_REQ_STATUS(req) == STATUS_RECEIVE_EXPEDITED); handle->recv_cb(handle, req->overlapped.InternalHigh, handle->recv_buffer, (struct sockaddr*) &handle->recv_from, partial ? UV_UDP_PARTIAL : 0); #if 0 } else { DWORD bytes, err, flags; struct sockaddr_storage from; int from_len; /* Do a nonblocking receive */ /* TODO: try to read multiple datagrams at once. FIONREAD maybe? */ buf = handle->alloc_cb((uv_handle_t*) handle, 65536); assert(buf.len > 0); memset(&from, 0, sizeof from); from_len = sizeof from; flags = MSG_PARTIAL; if (WSARecvFrom(handle->socket, (WSABUF*)&buf, 1, &bytes, &flags, (struct sockaddr*) &from, &from_len, NULL, NULL) != SOCKET_ERROR) { /* Message received */ handle->recv_cb(handle, bytes, buf, (struct sockaddr*) &from, (flags & MSG_PARTIAL) ? UV_UDP_PARTIAL : 0); } else { err = WSAGetLastError(); if (err == WSAEWOULDBLOCK) { uv__set_sys_error(loop, WSAEWOULDBLOCK); handle->recv_cb(handle, 0, buf, NULL, 0); } else { /* Ouch! serious error. */ uv__set_sys_error(loop, err); handle->recv_cb(handle, -1, buf, NULL, 0); } } } #endif done: /* Post another read if still reading and not closing. */ if ((handle->flags & UV_HANDLE_READING) && !(handle->flags & UV_HANDLE_READ_PENDING)) { uv_udp_queue_recv(loop, handle); } DECREASE_PENDING_REQ_COUNT(handle); }