From 81f5200ba36593a020f74766827aa25bd2402d75 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Mon, 29 Mar 2004 19:41:17 +0000 Subject: * 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. --- winsup/cygwin/net.cc | 77 ++++++++++++++++++++++++++++++++-------------------- 1 file changed, 47 insertions(+), 30 deletions(-) (limited to 'winsup/cygwin/net.cc') diff --git a/winsup/cygwin/net.cc b/winsup/cygwin/net.cc index 8c4090b28..3d76a433b 100644 --- a/winsup/cygwin/net.cc +++ b/winsup/cygwin/net.cc @@ -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; - break; - case WSA_WAIT_EVENT_0 + 1: - if (!CancelIo ((HANDLE) socket)) + 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) { - debug_printf ("CancelIo() %E, fallback to blocking io"); - WSAGetOverlappedResult (socket, &ovr, &len, TRUE, flags); + closed = 1; + if (!wsa_err && evts.iErrorCode[FD_CLOSE_BIT]) + wsa_err = evts.iErrorCode[FD_CLOSE_BIT]; + else + ret = 0; } - else - WSASetLastError (WSAEINTR); + if (wsa_err) + WSASetLastError (wsa_err); break; - case WSA_WAIT_FAILED: + case WSA_WAIT_EVENT_0 + 1: + WSASetLastError (WSAEINTR); 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 * -- cgit v1.2.3