diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index a0c0fd9f4..61e2a5c5a 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,21 @@ +2006-06-26 Corinna Vinschen + + Revert patches from 2005-10-22 and 2006-06-14 to use event driven + accept and connect back to using select: + * fhandler.h (class fhandler_socket): Remove accept_mtx. + * fhandler_socket.cc (fhandler_socket::fhandler_socket): Drop + initializing accept_mtx. + (fhandler_socket::accept): Drop event handling. + (fhandler_socket.cc (fhandler_socket::connect): Ditto. + (fhandler_socket::dup): Drop accept_mtx handling. + (fhandler_socket::listen): Ditto. + (fhandler_socket::prepare): Ditto. + (fhandler_socket::release): Ditto. + (fhandler_socket::close): Ditto. + * net.cc (cygwin_accept): Revert to calling cygwin_select to + implement interuptible accept. + (cygwin_connect): Ditto for connect. + 2006-06-22 Christopher Faylor * fhandler_fifo.cc (fhandler_fifo::open): Release process lock and grab diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h index a78ae48a0..cd0ee570c 100644 --- a/winsup/cygwin/fhandler.h +++ b/winsup/cygwin/fhandler.h @@ -381,7 +381,6 @@ class fhandler_mailslot : public fhandler_base class fhandler_socket: public fhandler_base { private: - HANDLE accept_mtx; int addr_family; int type; int connect_secret[4]; diff --git a/winsup/cygwin/fhandler_socket.cc b/winsup/cygwin/fhandler_socket.cc index 68a15163b..e27949600 100644 --- a/winsup/cygwin/fhandler_socket.cc +++ b/winsup/cygwin/fhandler_socket.cc @@ -127,7 +127,6 @@ get_inet_addr (const struct sockaddr *in, int inlen, fhandler_socket::fhandler_socket () : fhandler_base (), - accept_mtx (NULL), sun_path (NULL), status () { @@ -454,7 +453,6 @@ fhandler_socket::dup (fhandler_base *child) debug_printf ("here"); fhandler_socket *fhs = (fhandler_socket *) child; - fhs->accept_mtx = NULL; fhs->addr_family = addr_family; fhs->set_socket_type (get_socket_type ()); if (get_addr_family () == AF_LOCAL) @@ -471,17 +469,6 @@ fhandler_socket::dup (fhandler_base *child) } } fhs->connect_state (connect_state ()); - if (accept_mtx) - { - if (!DuplicateHandle (hMainProc, accept_mtx, hMainProc, &nh, 0, - TRUE, DUPLICATE_SAME_ACCESS)) - { - system_printf ("DuplicateHandle(%x) failed, %E", accept_mtx); - __seterrno (); - return -1; - } - fhs->accept_mtx = nh; - } /* Since WSADuplicateSocket() fails on NT systems when the process is currently impersonating a non-privileged account, we revert @@ -512,10 +499,8 @@ fhandler_socket::dup (fhandler_base *child) if (!DuplicateHandle (hMainProc, get_io_handle (), hMainProc, &nh, 0, FALSE, DUPLICATE_SAME_ACCESS)) { - system_printf ("DuplicateHandle(%x) failed, %E", get_io_handle ()); + system_printf ("!DuplicateHandle(%x) failed, %E", get_io_handle ()); __seterrno (); - if (fhs->accept_mtx) - CloseHandle (fhs->accept_mtx); return -1; } VerifyHandle (nh); @@ -768,20 +753,7 @@ fhandler_socket::connect (const struct sockaddr *name, int namelen) return -1; } - if (is_nonblocking ()) - res = ::connect (get_socket (), (struct sockaddr *) &sin, namelen); - else - { - HANDLE evt; - if (prepare (evt, FD_CONNECT)) - { - res = ::connect (get_socket (), (struct sockaddr *) &sin, namelen); - if (res == SOCKET_ERROR - && WSAGetLastError () == WSAEWOULDBLOCK) - res = wait (evt, 0, INFINITE); - release (evt); - } - } + res = ::connect (get_socket (), (struct sockaddr *) &sin, namelen); if (!res) err = 0; @@ -831,11 +803,6 @@ fhandler_socket::connect (const struct sockaddr *name, int namelen) int fhandler_socket::listen (int backlog) { - if (!accept_mtx && !(accept_mtx = CreateMutex (&sec_all, FALSE, NULL))) - { - set_errno (ENOBUFS); - return -1; - } int res = ::listen (get_socket (), backlog); if (res) set_winsock_errno (); @@ -871,21 +838,7 @@ fhandler_socket::accept (struct sockaddr *peer, int *len) if (len && ((unsigned) *len < sizeof (struct sockaddr_in))) *len = sizeof (struct sockaddr_in); - 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); - } - } + res = ::accept (get_socket (), peer, len); if (res == (int) INVALID_SOCKET) set_winsock_errno (); @@ -980,16 +933,6 @@ fhandler_socket::getpeername (struct sockaddr *name, int *namelen) bool fhandler_socket::prepare (HANDLE &event, long event_mask) { - if (event_mask == FD_ACCEPT && accept_mtx) - { - HANDLE obj[2] = { accept_mtx, signal_arrived }; - if (WaitForMultipleObjects (2, obj, FALSE, INFINITE) != WAIT_OBJECT_0) - { - debug_printf ("signal_arrived"); - WSASetLastError (WSAEINTR); - return false; - } - } WSASetLastError (0); closed (false); if ((event = WSACreateEvent ()) == WSA_INVALID_EVENT) @@ -1114,8 +1057,6 @@ fhandler_socket::release (HANDLE event) debug_printf ("return to blocking failed: %d", WSAGetLastError ()); else WSASetLastError (last_err); - if (accept_mtx) - ReleaseMutex (accept_mtx); } int @@ -1488,8 +1429,6 @@ fhandler_socket::close () } WSASetLastError (0); } - if (!res && accept_mtx) - CloseHandle (accept_mtx); debug_printf ("%d = fhandler_socket::close()", res); return res; diff --git a/winsup/cygwin/net.cc b/winsup/cygwin/net.cc index 3bc92d2be..b8213081f 100644 --- a/winsup/cygwin/net.cc +++ b/winsup/cygwin/net.cc @@ -814,7 +814,56 @@ cygwin_connect (int fd, const struct sockaddr *name, int namelen) if (efault.faulted (EFAULT) || !fh) res = -1; else - res = fh->connect (name, namelen); + { + bool was_blocking = false; + if (!fh->is_nonblocking ()) + { + int nonblocking = 1; + fh->ioctl (FIONBIO, &nonblocking); + was_blocking = true; + } + res = fh->connect (name, namelen); + if (was_blocking) + { + if (res == -1 && get_errno () == EINPROGRESS) + { + size_t fds_size = howmany (fd + 1, NFDBITS) * sizeof (fd_mask); + fd_set *write_fds = (fd_set *) alloca (fds_size); + fd_set *except_fds = (fd_set *) alloca (fds_size); + memset (write_fds, 0, fds_size); + memset (except_fds, 0, fds_size); + FD_SET (fd, write_fds); + FD_SET (fd, except_fds); + res = cygwin_select (fd + 1, NULL, write_fds, except_fds, NULL); + if (res > 0 && FD_ISSET (fd, except_fds)) + { + res = -1; + for (;;) + { + int err; + int len = sizeof err; + cygwin_getsockopt (fd, SOL_SOCKET, SO_ERROR, + (void *) &err, &len); + if (err) + { + set_errno (err); + break; + } + low_priority_sleep (0); + } + } + else if (res > 0) + res = 0; + else + { + WSASetLastError (WSAEINPROGRESS); + set_winsock_errno (); + } + } + int nonblocking = 0; + fh->ioctl (FIONBIO, &nonblocking); + } + } syscall_printf ("%d = connect (%d, %p, %d)", res, fd, name, namelen); @@ -948,7 +997,19 @@ cygwin_accept (int fd, struct sockaddr *peer, int *len) if (efault.faulted (EFAULT) || !fh) res = -1; else - res = fh->accept (peer, len); + { + 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); + } syscall_printf ("%d = accept (%d, %p, %p)", res, fd, peer, len); return res;