Browse Source

uv: upgrade to 6e8eb332

v0.9.1-release
Bert Belder 13 years ago
parent
commit
7887e68ff7
  1. 90
      deps/uv/src/win/tcp.c

90
deps/uv/src/win/tcp.c

@ -28,7 +28,6 @@
#include "req-inl.h"
/*
* Threshold of active tcp streams for which to preallocate tcp read buffers.
* (Due to node slab allocator performing poorly under this pattern,
@ -1292,31 +1291,88 @@ int uv_tcp_simultaneous_accepts(uv_tcp_t* handle, int enable) {
}
void uv_tcp_close(uv_loop_t* loop, uv_tcp_t* tcp) {
static int uv_tcp_try_cancel_io(uv_tcp_t* tcp) {
SOCKET socket = tcp->socket;
int non_ifs_lsp;
/* Check if we have any non-IFS LSPs stacked on top of TCP */
non_ifs_lsp = (tcp->flags & UV_HANDLE_IPV6) ? uv_tcp_non_ifs_lsp_ipv6 :
uv_tcp_non_ifs_lsp_ipv4;
/* If there are non-ifs LSPs then try to obtain a base handle for the */
/* socket. This will always fail on Windows XP/3k. */
if (non_ifs_lsp) {
DWORD bytes;
if (WSAIoctl(socket,
SIO_BASE_HANDLE,
NULL,
0,
&socket,
sizeof socket,
&bytes,
NULL,
NULL) != 0) {
/* Failed. We can't do CancelIo. */
return -1;
}
}
assert(socket != 0 && socket != INVALID_SOCKET);
if (!CancelIo((HANDLE) socket)) {
return -1;
}
/* It worked. */
return 0;
}
void uv_tcp_close(uv_loop_t* loop, uv_tcp_t* tcp) {
int close_socket = 1;
/*
* In order for winsock to do a graceful close there must not be
* any pending reads.
*/
if (tcp->flags & UV_HANDLE_READ_PENDING) {
/* Just do shutdown on non-shared sockets, which ensures graceful close. */
/* In order for winsock to do a graceful close there must not be any */
/* any pending reads, or the socket must be shut down for writing */
if (!(tcp->flags & UV_HANDLE_SHARED_TCP_SOCKET)) {
/* Just do shutdown on non-shared sockets, which ensures graceful close. */
shutdown(tcp->socket, SD_SEND);
tcp->flags |= UV_HANDLE_SHUT;
} else if (uv_tcp_try_cancel_io(tcp) == 0) {
/* In case of a shared socket, we try to cancel all outstanding I/O, */
/* If that works, don't close the socket yet - wait for the read req to */
/* return and close the socket in uv_tcp_endgame. */
close_socket = 0;
} else {
/* Check if we have any non-IFS LSPs stacked on top of TCP */
non_ifs_lsp = (tcp->flags & UV_HANDLE_IPV6) ? uv_tcp_non_ifs_lsp_ipv6 :
uv_tcp_non_ifs_lsp_ipv4;
/* When cancelling isn't possible - which could happen when an LSP is */
/* present on an old Windows version, we will have to close the socket */
/* with a read pending. That is not nice because trailing sent bytes */
/* may not make it to the other side. */
}
if (!non_ifs_lsp) {
/*
* Shared socket with no non-IFS LSPs, request to cancel pending I/O.
* The socket will be closed inside endgame.
*/
CancelIo((HANDLE)tcp->socket);
close_socket = 0;
} else if ((tcp->flags & UV_HANDLE_SHARED_TCP_SOCKET) &&
tcp->accept_reqs != NULL) {
/* Under normal circumstances closesocket() will ensure that all pending */
/* accept reqs are canceled. However, when the socket is shared the */
/* presence of another reference to the socket in another process will */
/* keep the accept reqs going, so we have to ensure that these are */
/* canceled. */
if (uv_tcp_try_cancel_io(tcp) != 0) {
/* When cancellation is not possible, there is another option: we can */
/* close the incoming sockets, which will also cancel the accept */
/* operations. However this is not cool because we might inadvertedly */
/* close a socket that just accepted a new connection, which will */
/* cause the connection to be aborted. */
unsigned int i;
for (i = 0; i < uv_simultaneous_server_accepts; i++) {
uv_tcp_accept_t* req = &tcp->accept_reqs[i];
if (req->accept_socket != INVALID_SOCKET &&
!HasOverlappedIoCompleted(&req->overlapped)) {
closesocket(req->accept_socket);
req->accept_socket = INVALID_SOCKET;
}
}
}
}

Loading…
Cancel
Save