From c2c020d1fb082baff8dfd2f2ca93c66bf7151bd0 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Sat, 22 Oct 2005 16:02:15 +0000 Subject: * fhandler_socket.cc (fhandler_socket::connect): Don't restrict WSAEINVAL -> WSAEISCONN conversion to nonblocking sockets. (fhandler_socket::accept): Use event driven technique to implement interuptible accept. (fhandler_socket::wait): Allow FD_ACCEPT handling. * net.cc (cygwin_accept): Remove workaround for allowing blocking accept. That's entirely in fhandler_socket::accept now. --- winsup/cygwin/ChangeLog | 10 ++++++++++ winsup/cygwin/fhandler_socket.cc | 27 ++++++++++++++++++++++++--- winsup/cygwin/net.cc | 14 +------------- 3 files changed, 35 insertions(+), 16 deletions(-) (limited to 'winsup') diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index e2897b750..69a7d39d3 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,13 @@ +2005-10-22 Corinna Vinschen + + * fhandler_socket.cc (fhandler_socket::connect): Don't restrict + WSAEINVAL -> WSAEISCONN conversion to nonblocking sockets. + (fhandler_socket::accept): Use event driven technique to implement + interuptible accept. + (fhandler_socket::wait): Allow FD_ACCEPT handling. + * net.cc (cygwin_accept): Remove workaround for allowing blocking + accept. That's entirely in fhandler_socket::accept now. + 2005-10-22 Corinna Vinschen * fhandler.h (class fhandler_socket): Add timeout parameter to wait() diff --git a/winsup/cygwin/fhandler_socket.cc b/winsup/cygwin/fhandler_socket.cc index f9b913729..79b59ff9b 100644 --- a/winsup/cygwin/fhandler_socket.cc +++ b/winsup/cygwin/fhandler_socket.cc @@ -710,9 +710,9 @@ fhandler_socket::connect (const struct sockaddr *name, int namelen) if (err == WSAEWOULDBLOCK) WSASetLastError (err = WSAEINPROGRESS); - else if (err == WSAEINVAL) - WSASetLastError (err = WSAEISCONN); } + if (err == WSAEINVAL) + WSASetLastError (err = WSAEISCONN); set_winsock_errno (); } @@ -779,7 +779,21 @@ fhandler_socket::accept (struct sockaddr *peer, int *len) if (len && ((unsigned) *len < sizeof (struct sockaddr_in))) *len = sizeof (struct sockaddr_in); - res = ::accept (get_socket (), peer, len); + if (is_nonblocking ()) + res = ::accept (get_socket (), peer, len); + else + { + HANDLE evt; + if (prepare (evt, FD_ACCEPT)) + { + res = wait (evt, 0, INFINITE); + if (res != -1 + || (WSAGetLastError () != WSAEINTR + && WSAGetLastError () != WSAEFAULT)) + res = ::accept (get_socket (), peer, len); + release (evt); + } + } if (res == (int) INVALID_SOCKET) set_winsock_errno (); @@ -923,6 +937,13 @@ fhandler_socket::wait (HANDLE event, int flags, DWORD timeout) break; } } + if (evts.lNetworkEvents & FD_ACCEPT) + { + if (evts.iErrorCode[FD_ACCEPT_BIT]) + wsa_err = evts.iErrorCode[FD_ACCEPT_BIT]; + else + ret = 0; + } if (evts.lNetworkEvents & FD_CONNECT) { if (evts.iErrorCode[FD_CONNECT_BIT]) diff --git a/winsup/cygwin/net.cc b/winsup/cygwin/net.cc index eccf0635f..456da37e2 100644 --- a/winsup/cygwin/net.cc +++ b/winsup/cygwin/net.cc @@ -909,19 +909,7 @@ cygwin_accept (int fd, struct sockaddr *peer, int *len) if (efault.faulted (EFAULT) || !fh) res = -1; else - { - if (!fh->is_nonblocking ()) - { - size_t fds_size = howmany (fd + 1, NFDBITS) * sizeof (fd_mask); - fd_set *read_fds = (fd_set *) alloca (fds_size); - memset (read_fds, 0, fds_size); - FD_SET (fd, read_fds); - res = cygwin_select (fd + 1, read_fds, NULL, NULL, NULL); - if (res == -1) - return -1; - } - res = fh->accept (peer, len); - } + res = fh->accept (peer, len); syscall_printf ("%d = accept (%d, %p, %p)", res, fd, peer, len); return res; -- cgit v1.2.3