* fhandler.h (class fhandler_socket): Remove has_been_closed member.

* fhandler_socket.cc (fhandler_socket::recvfrom): Revert to
	overlapped I/O.
	(fhandler_socket::recvmsg): Ditto.
	(fhandler_socket::sendto): Ditto.
	(fhandler_socket::sendmsg): Ditto.
	* net.cc (wsock_event::prepare): Ditto.
	(wsock_event::wait): Ditto.  Evaluate overlapped result also after
	calling CancelIo (thanks to Patrick Samson <p_samson@yahoo.com>).
	(wsock_event::release): Remove.
	* wsock_event.h: Revert to overlapped I/O.
This commit is contained in:
Corinna Vinschen
2004-04-03 19:07:59 +00:00
parent 81961a5001
commit 321ddf2422
5 changed files with 115 additions and 164 deletions

View File

@ -50,83 +50,59 @@ extern "C"
int sscanf (const char *, const char *, ...);
} /* End of "C" section */
bool
wsock_event::prepare (int sock, long event_mask)
LPWSAOVERLAPPED
wsock_event::prepare ()
{
WSASetLastError (0);
if ((event = WSACreateEvent ()) == WSA_INVALID_EVENT)
debug_printf ("WSACreateEvent: %E");
else if (WSAEventSelect (sock, event, event_mask) == SOCKET_ERROR)
{
debug_printf ("WSAEventSelect: %E");
WSACloseEvent (event);
event = WSA_INVALID_EVENT;
}
return event != WSA_INVALID_EVENT;
}
LPWSAOVERLAPPED ret = NULL;
int
wsock_event::wait (int sock, int &closed)
{
int ret = SOCKET_ERROR;
int wsa_err = 0;
WSAEVENT ev[2] = { event, signal_arrived };
switch (WSAWaitForMultipleEvents (2, ev, FALSE, WSA_INFINITE, FALSE))
SetLastError (0);
if ((event = WSACreateEvent ()) != WSA_INVALID_EVENT)
{
case WSA_WAIT_EVENT_0:
WSANETWORKEVENTS evts;
if (!WSAEnumNetworkEvents (sock, event, &evts))
{
if (evts.lNetworkEvents & FD_READ)
{
if (evts.iErrorCode[FD_READ_BIT])
wsa_err = evts.iErrorCode[FD_READ_BIT];
else
ret = 0;
}
else if (evts.lNetworkEvents & FD_WRITE)
{
if (evts.iErrorCode[FD_WRITE_BIT])
wsa_err = evts.iErrorCode[FD_WRITE_BIT];
else
ret = 0;
}
if (evts.lNetworkEvents & FD_CLOSE)
{
closed = 1;
if (!wsa_err)
{
if (evts.iErrorCode[FD_CLOSE_BIT])
wsa_err = evts.iErrorCode[FD_CLOSE_BIT];
else
ret = 0;
}
}
if (wsa_err)
WSASetLastError (wsa_err);
}
break;
case WSA_WAIT_EVENT_0 + 1:
WSASetLastError (WSAEINTR);
break;
default:
WSASetLastError (WSAEFAULT);
memset (&ovr, 0, sizeof ovr);
ovr.hEvent = event;
ret = &ovr;
}
else if (GetLastError () == ERROR_PROC_NOT_FOUND) /* winsock2 not available */
WSASetLastError (0);
debug_printf ("%d = wsock_event::prepare ()", ret);
return ret;
}
void
wsock_event::release (int sock)
int
wsock_event::wait (int socket, LPDWORD flags)
{
int last_err = WSAGetLastError ();
/* KB 168349: NT4 fails if the event parameter is not NULL. */
WSAEventSelect (sock, NULL, 0);
int ret = SOCKET_ERROR;
WSAEVENT ev[2] = { event, signal_arrived };
DWORD len;
switch (WSAWaitForMultipleEvents (2, ev, FALSE, WSA_INFINITE, FALSE))
{
case WSA_WAIT_EVENT_0:
if (WSAGetOverlappedResult (socket, &ovr, &len, FALSE, flags))
ret = (int) len;
break;
case WSA_WAIT_EVENT_0 + 1:
if (!CancelIo ((HANDLE) socket))
{
debug_printf ("CancelIo() %E, fallback to blocking io");
WSAGetOverlappedResult (socket, &ovr, &len, TRUE, flags);
}
else if (WSAGetOverlappedResult (socket, &ovr, &len, FALSE, flags)
&& len > 0)
ret = (int) len;
else
WSASetLastError (WSAEINTR);
break;
case WSA_WAIT_FAILED:
break;
default: /* Should be impossible. *LOL* */
WSASetLastError (WSAEFAULT);
break;
}
WSACloseEvent (event);
unsigned long non_block = 0;
if (ioctlsocket (sock, FIONBIO, &non_block))
debug_printf ("return to blocking failed: %d", WSAGetLastError ());
else
WSASetLastError (last_err);
event = NULL;
return ret;
}
WSADATA wsadata;