static void uv_tcp_queue_accept(uv_tcp_t* handle, uv_tcp_accept_t* req) { uv_loop_t* loop = handle->loop; BOOL success; DWORD bytes; SOCKET accept_socket; short family; LPFN_ACCEPTEX pAcceptExFamily; assert(handle->flags & UV_HANDLE_LISTENING); assert(req->accept_socket == INVALID_SOCKET); /* choose family and extension function */ if ((handle->flags & UV_HANDLE_IPV6) != 0) { family = AF_INET6; pAcceptExFamily = pAcceptEx6; } else { family = AF_INET; pAcceptExFamily = pAcceptEx; } /* Open a socket for the accepted connection. */ accept_socket = socket(family, SOCK_STREAM, 0); if (accept_socket == INVALID_SOCKET) { SET_REQ_ERROR(req, WSAGetLastError()); uv_insert_pending_req(loop, (uv_req_t*)req); handle->reqs_pending++; return; } /* Prepare the overlapped structure. */ memset(&(req->overlapped), 0, sizeof(req->overlapped)); success = pAcceptExFamily(handle->socket, accept_socket, (void*)req->accept_buffer, 0, sizeof(struct sockaddr_storage), sizeof(struct sockaddr_storage), &bytes, &req->overlapped); if (UV_SUCCEEDED_WITHOUT_IOCP(success)) { /* Process the req without IOCP. */ req->accept_socket = accept_socket; handle->reqs_pending++; uv_insert_pending_req(loop, (uv_req_t*)req); } else if (UV_SUCCEEDED_WITH_IOCP(success)) { /* The req will be processed with IOCP. */ req->accept_socket = accept_socket; handle->reqs_pending++; } else { /* Make this req pending reporting an error. */ SET_REQ_ERROR(req, WSAGetLastError()); uv_insert_pending_req(loop, (uv_req_t*)req); handle->reqs_pending++; /* Destroy the preallocated client socket. */ closesocket(accept_socket); } }
int uv_tcp_write(uv_loop_t* loop, uv_write_t* req, uv_tcp_t* handle, uv_buf_t bufs[], int bufcnt, uv_write_cb cb) { int result; DWORD bytes; uv_req_init(loop, (uv_req_t*) req); req->type = UV_WRITE; req->handle = (uv_stream_t*) handle; req->cb = cb; memset(&req->overlapped, 0, sizeof(req->overlapped)); /* Prepare the overlapped structure. */ memset(&(req->overlapped), 0, sizeof(req->overlapped)); if (handle->flags & UV_HANDLE_EMULATE_IOCP) { req->event_handle = CreateEvent(NULL, 0, 0, NULL); if (!req->event_handle) { uv_fatal_error(GetLastError(), "CreateEvent"); } req->overlapped.hEvent = (HANDLE) ((ULONG_PTR) req->event_handle | 1); req->wait_handle = INVALID_HANDLE_VALUE; } result = WSASend(handle->socket, (WSABUF*)bufs, bufcnt, &bytes, 0, &req->overlapped, NULL); if (UV_SUCCEEDED_WITHOUT_IOCP(result == 0)) { /* Request completed immediately. */ req->queued_bytes = 0; handle->reqs_pending++; handle->write_reqs_pending++; REGISTER_HANDLE_REQ(loop, handle, req); uv_insert_pending_req(loop, (uv_req_t*) req); } else if (UV_SUCCEEDED_WITH_IOCP(result == 0)) { /* Request queued by the kernel. */ req->queued_bytes = uv_count_bufs(bufs, bufcnt); handle->reqs_pending++; handle->write_reqs_pending++; REGISTER_HANDLE_REQ(loop, handle, req); handle->write_queue_size += req->queued_bytes; if (handle->flags & UV_HANDLE_EMULATE_IOCP && !RegisterWaitForSingleObject(&req->wait_handle, req->event_handle, post_write_completion, (void*) req, INFINITE, WT_EXECUTEINWAITTHREAD | WT_EXECUTEONLYONCE)) { SET_REQ_ERROR(req, GetLastError()); uv_insert_pending_req(loop, (uv_req_t*)req); } } else { /* Send failed due to an error. */ uv__set_sys_error(loop, WSAGetLastError()); return -1; } return 0; }
int uv__tcp_connect6(uv_connect_t* req, uv_tcp_t* handle, struct sockaddr_in6 address, uv_connect_cb cb) { uv_loop_t* loop = handle->loop; int addrsize = sizeof(struct sockaddr_in6); BOOL success; DWORD bytes; if (!uv_allow_ipv6) { uv__set_sys_error(loop, WSAEAFNOSUPPORT); return -1; } if (handle->flags & UV_HANDLE_BIND_ERROR) { uv__set_sys_error(loop, handle->bind_error); return -1; } if (!(handle->flags & UV_HANDLE_BOUND) && uv_tcp_bind6(handle, uv_addr_ip6_any_) < 0) return -1; if (!handle->func_connectex) { if(!uv_get_connectex_function(handle->socket, &handle->func_connectex)) { uv__set_sys_error(loop, WSAEAFNOSUPPORT); return -1; } } uv_req_init(loop, (uv_req_t*) req); req->type = UV_CONNECT; req->handle = (uv_stream_t*) handle; req->cb = cb; memset(&req->overlapped, 0, sizeof(req->overlapped)); success = handle->func_connectex(handle->socket, (struct sockaddr*) &address, addrsize, NULL, 0, &bytes, &req->overlapped); if (UV_SUCCEEDED_WITHOUT_IOCP(success)) { handle->reqs_pending++; uv_ref(loop); uv_insert_pending_req(loop, (uv_req_t*)req); } else if (UV_SUCCEEDED_WITH_IOCP(success)) { handle->reqs_pending++; uv_ref(loop); } else { uv__set_sys_error(loop, WSAGetLastError()); return -1; } return 0; }
int uv__tcp_connect(uv_connect_t* req, uv_tcp_t* handle, struct sockaddr_in address, uv_connect_cb cb) { uv_loop_t* loop = handle->loop; int addrsize = sizeof(struct sockaddr_in); BOOL success; DWORD bytes; int err; if (handle->flags & UV_HANDLE_BIND_ERROR) { return handle->bind_error; } if (!(handle->flags & UV_HANDLE_BOUND)) { err = uv_tcp_bind(handle, uv_addr_ip4_any_); if (err) return err; } if (!handle->func_connectex) { if (!uv_get_connectex_function(handle->socket, &handle->func_connectex)) { return WSAEAFNOSUPPORT; } } uv_req_init(loop, (uv_req_t*) req); req->type = UV_CONNECT; req->handle = (uv_stream_t*) handle; req->cb = cb; memset(&req->overlapped, 0, sizeof(req->overlapped)); success = handle->func_connectex(handle->socket, (struct sockaddr*) &address, addrsize, NULL, 0, &bytes, &req->overlapped); if (UV_SUCCEEDED_WITHOUT_IOCP(success)) { /* Process the req without IOCP. */ handle->reqs_pending++; REGISTER_HANDLE_REQ(loop, handle, req); uv_insert_pending_req(loop, (uv_req_t*)req); } else if (UV_SUCCEEDED_WITH_IOCP(success)) { /* The req will be processed with IOCP. */ handle->reqs_pending++; REGISTER_HANDLE_REQ(loop, handle, req); } else { return WSAGetLastError(); } return 0; }
static void uv_tcp_queue_read(uv_loop_t* loop, uv_tcp_t* handle) { uv_read_t* req; uv_buf_t buf; int result; DWORD bytes, flags; assert(handle->flags & UV_HANDLE_READING); assert(!(handle->flags & UV_HANDLE_READ_PENDING)); req = &handle->read_req; memset(&req->overlapped, 0, sizeof(req->overlapped)); /* * Preallocate a read buffer if the number of active streams is below * the threshold. */ if (active_tcp_streams < uv_active_tcp_streams_threshold) { handle->flags &= ~UV_HANDLE_ZERO_READ; handle->read_buffer = handle->alloc_cb((uv_handle_t*) handle, 65536); assert(handle->read_buffer.len > 0); buf = handle->read_buffer; } else { handle->flags |= UV_HANDLE_ZERO_READ; buf.base = (char*) &uv_zero_; buf.len = 0; } flags = 0; result = WSARecv(handle->socket, (WSABUF*)&buf, 1, &bytes, &flags, &req->overlapped, NULL); if (UV_SUCCEEDED_WITHOUT_IOCP(result == 0)) { /* Process the req without IOCP. */ handle->flags |= UV_HANDLE_READ_PENDING; req->overlapped.InternalHigh = bytes; handle->reqs_pending++; uv_insert_pending_req(loop, (uv_req_t*)req); } else if (UV_SUCCEEDED_WITH_IOCP(result == 0)) { /* The req will be processed with IOCP. */ handle->flags |= UV_HANDLE_READ_PENDING; handle->reqs_pending++; } else { /* Make this req pending reporting an error. */ SET_REQ_ERROR(req, WSAGetLastError()); uv_insert_pending_req(loop, (uv_req_t*)req); handle->reqs_pending++; } }
int uv_tcp_connect6(uv_connect_t* req, uv_tcp_t* handle, struct sockaddr_in6 address, uv_connect_cb cb) { int addrsize = sizeof(struct sockaddr_in6); BOOL success; DWORD bytes; if (!uv_allow_ipv6) { uv_new_sys_error(WSAEAFNOSUPPORT); return -1; } if (handle->flags & UV_HANDLE_BIND_ERROR) { LOOP->last_error = handle->error; return -1; } if (address.sin6_family != AF_INET6) { uv_set_sys_error(WSAEFAULT); return -1; } if (!(handle->flags & UV_HANDLE_BOUND) && uv_tcp_bind6(handle, uv_addr_ip6_any_) < 0) return -1; uv_req_init((uv_req_t*) req); req->type = UV_CONNECT; req->handle = (uv_stream_t*) handle; req->cb = cb; memset(&req->overlapped, 0, sizeof(req->overlapped)); success = pConnectEx6(handle->socket, (struct sockaddr*) &address, addrsize, NULL, 0, &bytes, &req->overlapped); if (UV_SUCCEEDED_WITHOUT_IOCP(success)) { handle->reqs_pending++; uv_insert_pending_req((uv_req_t*)req); } else if (UV_SUCCEEDED_WITH_IOCP(success)) { handle->reqs_pending++; } else { uv_set_sys_error(WSAGetLastError()); return -1; } return 0; }
int uv_tcp_write(uv_loop_t* loop, uv_write_t* req, uv_tcp_t* handle, uv_buf_t bufs[], int bufcnt, uv_write_cb cb) { int result; DWORD bytes; if (!(handle->flags & UV_HANDLE_CONNECTION)) { uv__set_sys_error(loop, WSAEINVAL); return -1; } if (handle->flags & UV_HANDLE_SHUTTING) { uv__set_sys_error(loop, WSAESHUTDOWN); return -1; } uv_req_init(loop, (uv_req_t*) req); req->type = UV_WRITE; req->handle = (uv_stream_t*) handle; req->cb = cb; memset(&req->overlapped, 0, sizeof(req->overlapped)); result = WSASend(handle->socket, (WSABUF*)bufs, bufcnt, &bytes, 0, &req->overlapped, NULL); if (UV_SUCCEEDED_WITHOUT_IOCP(result == 0)) { /* Request completed immediately. */ req->queued_bytes = 0; handle->reqs_pending++; handle->write_reqs_pending++; uv_insert_pending_req(loop, (uv_req_t*) req); } else if (UV_SUCCEEDED_WITH_IOCP(result == 0)) { /* Request queued by the kernel. */ req->queued_bytes = uv_count_bufs(bufs, bufcnt); handle->reqs_pending++; handle->write_reqs_pending++; handle->write_queue_size += req->queued_bytes; } else { /* Send failed due to an error. */ uv__set_sys_error(loop, WSAGetLastError()); return -1; } return 0; }
int uv_tcp_connect(uv_connect_t* req, uv_tcp_t* handle, struct sockaddr_in address, uv_connect_cb cb) { uv_loop_t* loop = handle->loop; int addrsize = sizeof(struct sockaddr_in); BOOL success; DWORD bytes; if (handle->flags & UV_HANDLE_BIND_ERROR) { loop->last_error = handle->bind_error; return -1; } if (address.sin_family != AF_INET) { uv_set_sys_error(loop, WSAEFAULT); return -1; } if (!(handle->flags & UV_HANDLE_BOUND) && uv_tcp_bind(handle, uv_addr_ip4_any_) < 0) return -1; uv_req_init(loop, (uv_req_t*) req); req->type = UV_CONNECT; req->handle = (uv_stream_t*) handle; req->cb = cb; memset(&req->overlapped, 0, sizeof(req->overlapped)); success = pConnectEx(handle->socket, (struct sockaddr*) &address, addrsize, NULL, 0, &bytes, &req->overlapped); if (UV_SUCCEEDED_WITHOUT_IOCP(success)) { /* Process the req without IOCP. */ handle->reqs_pending++; uv_insert_pending_req(loop, (uv_req_t*)req); } else if (UV_SUCCEEDED_WITH_IOCP(success)) { /* The req will be processed with IOCP. */ handle->reqs_pending++; } else { uv_set_sys_error(loop, WSAGetLastError()); return -1; } return 0; }
static int uv__send(uv_udp_send_t* req, uv_udp_t* handle, const uv_buf_t bufs[], unsigned int nbufs, const struct sockaddr* addr, unsigned int addrlen, uv_udp_send_cb cb) { uv_loop_t* loop = handle->loop; DWORD result, bytes; uv_req_init(loop, (uv_req_t*) req); req->type = UV_UDP_SEND; req->handle = handle; req->cb = cb; memset(&req->u.io.overlapped, 0, sizeof(req->u.io.overlapped)); result = WSASendTo(handle->socket, (WSABUF*)bufs, nbufs, &bytes, 0, addr, addrlen, &req->u.io.overlapped, NULL); if (UV_SUCCEEDED_WITHOUT_IOCP(result == 0)) { /* Request completed immediately. */ req->u.io.queued_bytes = 0; handle->reqs_pending++; handle->send_queue_size += req->u.io.queued_bytes; handle->send_queue_count++; REGISTER_HANDLE_REQ(loop, handle, req); uv_insert_pending_req(loop, (uv_req_t*)req); } else if (UV_SUCCEEDED_WITH_IOCP(result == 0)) { /* Request queued by the kernel. */ req->u.io.queued_bytes = uv__count_bufs(bufs, nbufs); handle->reqs_pending++; handle->send_queue_size += req->u.io.queued_bytes; handle->send_queue_count++; REGISTER_HANDLE_REQ(loop, handle, req); } else { /* Send failed due to an error. */ return WSAGetLastError(); } return 0; }
static void uv_udp_queue_recv(uv_loop_t* loop, uv_udp_t* handle) { uv_req_t* req; uv_buf_t buf; DWORD bytes, flags; int result; assert(handle->flags & UV_HANDLE_READING); assert(!(handle->flags & UV_HANDLE_READ_PENDING)); req = &handle->recv_req; memset(&req->u.io.overlapped, 0, sizeof(req->u.io.overlapped)); handle->flags |= UV_HANDLE_ZERO_READ; buf.base = ""; buf.len = 0; flags = MSG_PEEK; result = handle->func_wsarecv(handle->socket, (WSABUF*) &buf, 1, &bytes, &flags, &req->u.io.overlapped, NULL); if (UV_SUCCEEDED_WITHOUT_IOCP(result == 0)) { /* Process the req without IOCP. */ handle->flags |= UV_HANDLE_READ_PENDING; req->u.io.overlapped.InternalHigh = bytes; handle->reqs_pending++; uv_insert_pending_req(loop, req); } else if (UV_SUCCEEDED_WITH_IOCP(result == 0)) { /* The req will be processed with IOCP. */ handle->flags |= UV_HANDLE_READ_PENDING; handle->reqs_pending++; } else { /* Make this req pending reporting an error. */ SET_REQ_ERROR(req, WSAGetLastError()); uv_insert_pending_req(loop, req); handle->reqs_pending++; } }
static int uv__udp_send(uv_udp_send_t* req, uv_udp_t* handle, uv_buf_t bufs[], int bufcnt, struct sockaddr* addr, int addr_len, uv_udp_send_cb cb) { uv_loop_t* loop = handle->loop; DWORD result, bytes; uv_req_init(loop, (uv_req_t*) req); req->type = UV_UDP_SEND; req->handle = handle; req->cb = cb; memset(&req->overlapped, 0, sizeof(req->overlapped)); result = WSASendTo(handle->socket, (WSABUF*)bufs, bufcnt, &bytes, 0, addr, addr_len, &req->overlapped, NULL); if (UV_SUCCEEDED_WITHOUT_IOCP(result == 0)) { /* Request completed immediately. */ req->queued_bytes = 0; handle->reqs_pending++; uv_ref(loop); uv_insert_pending_req(loop, (uv_req_t*)req); } else if (UV_SUCCEEDED_WITH_IOCP(result == 0)) { /* Request queued by the kernel. */ req->queued_bytes = uv_count_bufs(bufs, bufcnt); handle->reqs_pending++; uv_ref(loop); } else { /* Send failed due to an error. */ uv__set_sys_error(loop, WSAGetLastError()); return -1; } return 0; }
static void uv_udp_queue_recv(uv_loop_t* loop, uv_udp_t* handle) { uv_req_t* req; uv_buf_t buf; DWORD bytes, flags; int result; assert(handle->flags & UV_HANDLE_READING); assert(!(handle->flags & UV_HANDLE_READ_PENDING)); req = &handle->recv_req; memset(&req->u.io.overlapped, 0, sizeof(req->u.io.overlapped)); /* * Preallocate a read buffer if the number of active streams is below * the threshold. */ if (loop->active_udp_streams < uv_active_udp_streams_threshold) { handle->flags &= ~UV_HANDLE_ZERO_READ; handle->recv_buffer = uv_buf_init(NULL, 0); handle->alloc_cb((uv_handle_t*) handle, 65536, &handle->recv_buffer); if (handle->recv_buffer.base == NULL || handle->recv_buffer.len == 0) { handle->recv_cb(handle, UV_ENOBUFS, &handle->recv_buffer, NULL, 0); return; } assert(handle->recv_buffer.base != NULL); buf = handle->recv_buffer; memset(&handle->recv_from, 0, sizeof handle->recv_from); handle->recv_from_len = sizeof handle->recv_from; flags = 0; result = handle->func_wsarecvfrom(handle->socket, (WSABUF*) &buf, 1, &bytes, &flags, (struct sockaddr*) &handle->recv_from, &handle->recv_from_len, &req->u.io.overlapped, NULL); if (UV_SUCCEEDED_WITHOUT_IOCP(result == 0)) { /* Process the req without IOCP. */ handle->flags |= UV_HANDLE_READ_PENDING; req->u.io.overlapped.InternalHigh = bytes; handle->reqs_pending++; uv_insert_pending_req(loop, req); } else if (UV_SUCCEEDED_WITH_IOCP(result == 0)) { /* The req will be processed with IOCP. */ handle->flags |= UV_HANDLE_READ_PENDING; handle->reqs_pending++; } else { /* Make this req pending reporting an error. */ SET_REQ_ERROR(req, WSAGetLastError()); uv_insert_pending_req(loop, req); handle->reqs_pending++; } } else { handle->flags |= UV_HANDLE_ZERO_READ; buf.base = (char*) uv_zero_; buf.len = 0; flags = MSG_PEEK; result = handle->func_wsarecv(handle->socket, (WSABUF*) &buf, 1, &bytes, &flags, &req->u.io.overlapped, NULL); if (UV_SUCCEEDED_WITHOUT_IOCP(result == 0)) { /* Process the req without IOCP. */ handle->flags |= UV_HANDLE_READ_PENDING; req->u.io.overlapped.InternalHigh = bytes; handle->reqs_pending++; uv_insert_pending_req(loop, req); } else if (UV_SUCCEEDED_WITH_IOCP(result == 0)) { /* The req will be processed with IOCP. */ handle->flags |= UV_HANDLE_READ_PENDING; handle->reqs_pending++; } else { /* Make this req pending reporting an error. */ SET_REQ_ERROR(req, WSAGetLastError()); uv_insert_pending_req(loop, req); handle->reqs_pending++; } } }
static void uv_tcp_queue_read(uv_loop_t* loop, uv_tcp_t* handle) { uv_read_t* req; uv_buf_t buf; int result; DWORD bytes, flags; assert(handle->flags & UV_HANDLE_READING); assert(!(handle->flags & UV_HANDLE_READ_PENDING)); req = &handle->read_req; memset(&req->overlapped, 0, sizeof(req->overlapped)); /* * Preallocate a read buffer if the number of active streams is below * the threshold. */ if (loop->active_tcp_streams < uv_active_tcp_streams_threshold) { handle->flags &= ~UV_HANDLE_ZERO_READ; handle->alloc_cb((uv_handle_t*) handle, 65536, &handle->read_buffer); if (handle->read_buffer.len == 0) { handle->read_cb((uv_stream_t*) handle, UV_ENOBUFS, &handle->read_buffer); return; } assert(handle->read_buffer.base != NULL); buf = handle->read_buffer; } else { handle->flags |= UV_HANDLE_ZERO_READ; buf.base = (char*) &uv_zero_; buf.len = 0; } /* Prepare the overlapped structure. */ memset(&(req->overlapped), 0, sizeof(req->overlapped)); if (handle->flags & UV_HANDLE_EMULATE_IOCP) { assert(req->event_handle); req->overlapped.hEvent = (HANDLE) ((DWORD) req->event_handle | 1); } flags = 0; result = WSARecv(handle->socket, (WSABUF*)&buf, 1, &bytes, &flags, &req->overlapped, NULL); if (UV_SUCCEEDED_WITHOUT_IOCP(result == 0)) { /* Process the req without IOCP. */ handle->flags |= UV_HANDLE_READ_PENDING; req->overlapped.InternalHigh = bytes; handle->reqs_pending++; uv_insert_pending_req(loop, (uv_req_t*)req); } else if (UV_SUCCEEDED_WITH_IOCP(result == 0)) { /* The req will be processed with IOCP. */ handle->flags |= UV_HANDLE_READ_PENDING; handle->reqs_pending++; if (handle->flags & UV_HANDLE_EMULATE_IOCP && req->wait_handle == INVALID_HANDLE_VALUE && !pRegisterWaitForSingleObject(&req->wait_handle, req->event_handle, post_completion, (void*) req, INFINITE, WT_EXECUTEINWAITTHREAD)) { SET_REQ_ERROR(req, GetLastError()); uv_insert_pending_req(loop, (uv_req_t*)req); } } else { /* Make this req pending reporting an error. */ SET_REQ_ERROR(req, WSAGetLastError()); uv_insert_pending_req(loop, (uv_req_t*)req); handle->reqs_pending++; } }
static void uv_tcp_queue_accept(uv_tcp_t* handle, uv_tcp_accept_t* req) { uv_loop_t* loop = handle->loop; BOOL success; DWORD bytes; SOCKET accept_socket; short family; assert(handle->flags & UV_HANDLE_LISTENING); assert(req->accept_socket == INVALID_SOCKET); /* choose family and extension function */ if (handle->flags & UV_HANDLE_IPV6) { family = AF_INET6; } else { family = AF_INET; } /* Open a socket for the accepted connection. */ accept_socket = socket(family, SOCK_STREAM, 0); if (accept_socket == INVALID_SOCKET) { SET_REQ_ERROR(req, WSAGetLastError()); uv_insert_pending_req(loop, (uv_req_t*)req); handle->reqs_pending++; return; } /* Make the socket non-inheritable */ if (!SetHandleInformation((HANDLE) accept_socket, HANDLE_FLAG_INHERIT, 0)) { SET_REQ_ERROR(req, GetLastError()); uv_insert_pending_req(loop, (uv_req_t*)req); handle->reqs_pending++; closesocket(accept_socket); return; } /* Prepare the overlapped structure. */ memset(&(req->overlapped), 0, sizeof(req->overlapped)); if (handle->flags & UV_HANDLE_EMULATE_IOCP) { req->overlapped.hEvent = (HANDLE) ((DWORD) req->event_handle | 1); } success = handle->func_acceptex(handle->socket, accept_socket, (void*)req->accept_buffer, 0, sizeof(struct sockaddr_storage), sizeof(struct sockaddr_storage), &bytes, &req->overlapped); if (UV_SUCCEEDED_WITHOUT_IOCP(success)) { /* Process the req without IOCP. */ req->accept_socket = accept_socket; handle->reqs_pending++; uv_insert_pending_req(loop, (uv_req_t*)req); } else if (UV_SUCCEEDED_WITH_IOCP(success)) { /* The req will be processed with IOCP. */ req->accept_socket = accept_socket; handle->reqs_pending++; if (handle->flags & UV_HANDLE_EMULATE_IOCP && req->wait_handle == INVALID_HANDLE_VALUE && !pRegisterWaitForSingleObject(&req->wait_handle, req->event_handle, post_completion, (void*) req, INFINITE, WT_EXECUTEINWAITTHREAD)) { SET_REQ_ERROR(req, GetLastError()); uv_insert_pending_req(loop, (uv_req_t*)req); handle->reqs_pending++; return; } } else { /* Make this req pending reporting an error. */ SET_REQ_ERROR(req, WSAGetLastError()); uv_insert_pending_req(loop, (uv_req_t*)req); handle->reqs_pending++; /* Destroy the preallocated client socket. */ closesocket(accept_socket); /* Destroy the event handle */ if (handle->flags & UV_HANDLE_EMULATE_IOCP) { CloseHandle(req->overlapped.hEvent); req->event_handle = NULL; } } }
static int uv_tcp_try_connect(uv_connect_t* req, uv_tcp_t* handle, const struct sockaddr* addr, unsigned int addrlen, uv_connect_cb cb) { uv_loop_t* loop = handle->loop; const struct sockaddr* bind_addr; struct sockaddr_storage converted; BOOL success; DWORD bytes; int err; err = uv__convert_to_localhost_if_unspecified(addr, &converted); if (err) return err; if (handle->delayed_error) { return handle->delayed_error; } if (!(handle->flags & UV_HANDLE_BOUND)) { if (addrlen == sizeof(uv_addr_ip4_any_)) { bind_addr = (const struct sockaddr*) &uv_addr_ip4_any_; } else if (addrlen == sizeof(uv_addr_ip6_any_)) { bind_addr = (const struct sockaddr*) &uv_addr_ip6_any_; } else { abort(); } err = uv_tcp_try_bind(handle, bind_addr, addrlen, 0); if (err) return err; if (handle->delayed_error) return handle->delayed_error; } if (!handle->tcp.conn.func_connectex) { if (!uv_get_connectex_function(handle->socket, &handle->tcp.conn.func_connectex)) { return WSAEAFNOSUPPORT; } } UV_REQ_INIT(req, UV_CONNECT); req->handle = (uv_stream_t*) handle; req->cb = cb; memset(&req->u.io.overlapped, 0, sizeof(req->u.io.overlapped)); success = handle->tcp.conn.func_connectex(handle->socket, (const struct sockaddr*) &converted, addrlen, NULL, 0, &bytes, &req->u.io.overlapped); if (UV_SUCCEEDED_WITHOUT_IOCP(success)) { /* Process the req without IOCP. */ handle->reqs_pending++; REGISTER_HANDLE_REQ(loop, handle, req); uv_insert_pending_req(loop, (uv_req_t*)req); } else if (UV_SUCCEEDED_WITH_IOCP(success)) { /* The req will be processed with IOCP. */ handle->reqs_pending++; REGISTER_HANDLE_REQ(loop, handle, req); } else { return WSAGetLastError(); } return 0; }