diff options
author | Corinna Vinschen <corinna@vinschen.de> | 2003-06-03 14:05:17 +0000 |
---|---|---|
committer | Corinna Vinschen <corinna@vinschen.de> | 2003-06-03 14:05:17 +0000 |
commit | fb6b1418e4ccbbcb5697779908229121832f5fb9 (patch) | |
tree | 2f8f0b80aed71e84de12aaeb81320901265a1fd4 /winsup/cygwin/net.cc | |
parent | 0c8fe172781f9f2fc2aa2cd07effbbcca58a9a4e (diff) | |
download | cygnal-fb6b1418e4ccbbcb5697779908229121832f5fb9.tar.gz cygnal-fb6b1418e4ccbbcb5697779908229121832f5fb9.tar.bz2 cygnal-fb6b1418e4ccbbcb5697779908229121832f5fb9.zip |
* fhandler_socket.cc (connect_thread): Remove.
(accept_thread): Remove.
(fhandler_socket::connect): Remove all special blocking handling.
(fhandler_socket::accept): Ditto.
* net.cc (cygwin_connect): Make blocking sockets temporarily
non-blocking and call cygwin_select on them to be interruptible.
(cygwin_accept): Ditto.
Diffstat (limited to 'winsup/cygwin/net.cc')
-rw-r--r-- | winsup/cygwin/net.cc | 65 |
1 files changed, 63 insertions, 2 deletions
diff --git a/winsup/cygwin/net.cc b/winsup/cygwin/net.cc index dda0e3113..7890c9bc4 100644 --- a/winsup/cygwin/net.cc +++ b/winsup/cygwin/net.cc @@ -773,7 +773,56 @@ cygwin_connect (int fd, const struct sockaddr *name, int namelen) if (__check_invalid_read_ptr_errno (name, namelen) || !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); @@ -1051,7 +1100,19 @@ cygwin_accept (int fd, struct sockaddr *peer, int *len) || !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; |