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

* fhandler_socket.cc (fhandler_socket::fhandler_socket): Initialize
	has_been_closed to 0.
	(fhandler_socket::recvfrom): Use new asynchronous I/O driven
	wsock_event methods.
	(fhandler_socket::recvmsg): Ditto.
	(fhandler_socket::sendto): Ditto.
	(fhandler_socket::sendmsg): Ditto.
	* net.cc (wsock_event::prepare): Reimplement using asynchronous I/O.
	(wsock_event::wait): Ditto.
	(wsock_event::release): New method.
	* wsock_event.h (class wsock_event): Remove ovr member.  Accomodate
	new implementation of prepare and wait methods.  Add release method.
This commit is contained in:
Corinna Vinschen
2004-03-29 19:41:17 +00:00
parent c7f060d0da
commit 81f5200ba3
5 changed files with 142 additions and 66 deletions

View File

@ -50,58 +50,75 @@ extern "C"
int sscanf (const char *, const char *, ...);
} /* End of "C" section */
LPWSAOVERLAPPED
wsock_event::prepare ()
bool
wsock_event::prepare (int sock, long event_mask)
{
LPWSAOVERLAPPED ret = NULL;
SetLastError (0);
if ((event = WSACreateEvent ()) != WSA_INVALID_EVENT)
if ((event = WSACreateEvent ()) != WSA_INVALID_EVENT
&& WSAEventSelect (sock, event, event_mask) == SOCKET_ERROR)
{
memset (&ovr, 0, sizeof ovr);
ovr.hEvent = event;
ret = &ovr;
debug_printf ("WSAEventSelect: %E");
WSACloseEvent (event);
event = WSA_INVALID_EVENT;
}
else if (GetLastError () == ERROR_PROC_NOT_FOUND) /* winsock2 not available */
WSASetLastError (0);
debug_printf ("%d = wsock_event::prepare ()", ret);
return ret;
return event != WSA_INVALID_EVENT;
}
int
wsock_event::wait (int socket, LPDWORD flags)
wsock_event::wait (int sock, int &closed)
{
int ret = -1;
DWORD wsa_err = 0;
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;
WSANETWORKEVENTS evts;
memset (&evts, 0, sizeof evts);
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 && 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:
if (!CancelIo ((HANDLE) socket))
{
debug_printf ("CancelIo() %E, fallback to blocking io");
WSAGetOverlappedResult (socket, &ovr, &len, TRUE, flags);
}
else
WSASetLastError (WSAEINTR);
WSASetLastError (WSAEINTR);
break;
case WSA_WAIT_FAILED:
break;
default: /* Should be impossible. *LOL* */
default:
WSASetLastError (WSAEFAULT);
break;
}
WSACloseEvent (event);
event = NULL;
return ret;
}
void
wsock_event::release (int sock)
{
WSAEventSelect (sock, event, 0);
WSACloseEvent (event);
unsigned long non_block = 0;
ioctlsocket (sock, FIONBIO, &non_block);
}
WSADATA wsadata;
static fhandler_socket *