summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2003-06-03 14:05:17 +0000
committerCorinna Vinschen <corinna@vinschen.de>2003-06-03 14:05:17 +0000
commitfb6b1418e4ccbbcb5697779908229121832f5fb9 (patch)
tree2f8f0b80aed71e84de12aaeb81320901265a1fd4
parent0c8fe172781f9f2fc2aa2cd07effbbcca58a9a4e (diff)
downloadcygnal-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.
-rw-r--r--winsup/cygwin/ChangeLog11
-rw-r--r--winsup/cygwin/fhandler_socket.cc56
-rw-r--r--winsup/cygwin/net.cc65
3 files changed, 77 insertions, 55 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index b34f09400..91c68ce6a 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,3 +1,14 @@
+2003-06-03 Corinna Vinschen <corinna@vinschen.de>
+ Thomas Pfaff <tpfaff@gmx.net>
+
+ * 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.
+
2003-06-02 Christopher Faylor <cgf@redhat.com>
* spawn.cc (spawn_guts): Don't hang around if the parent doesn't exist.
diff --git a/winsup/cygwin/fhandler_socket.cc b/winsup/cygwin/fhandler_socket.cc
index c335f314b..894e980e6 100644
--- a/winsup/cygwin/fhandler_socket.cc
+++ b/winsup/cygwin/fhandler_socket.cc
@@ -33,6 +33,7 @@
#include "sigproc.h"
#include "wsock_event.h"
#include "cygthread.h"
+#include "select.h"
#include <unistd.h>
#define ENTROPY_SOURCE_DEV_UNIT 9
@@ -120,30 +121,6 @@ get_inet_addr (const struct sockaddr *in, int inlen,
}
}
-struct sock_thread_data
-{
- int socket;
- sockaddr *peer;
- int *len;
- int ret;
-};
-
-static DWORD WINAPI
-connect_thread (void *arg)
-{
- sock_thread_data *std = (sock_thread_data *) arg;
- std->ret = ::connect (std->socket, std->peer, *std->len);
- return 0;
-}
-
-static DWORD WINAPI
-accept_thread (void *arg)
-{
- sock_thread_data *std = (sock_thread_data *) arg;
- std->ret = ::accept (std->socket, std->peer, std->len);
- return 0;
-}
-
/**********************************************************************/
/* fhandler_socket */
@@ -520,7 +497,6 @@ out:
int
fhandler_socket::connect (const struct sockaddr *name, int namelen)
{
- BOOL interrupted = FALSE;
int res = -1;
BOOL secret_check_failed = FALSE;
BOOL in_progress = FALSE;
@@ -530,18 +506,7 @@ fhandler_socket::connect (const struct sockaddr *name, int namelen)
if (!get_inet_addr (name, namelen, &sin, &namelen, secret))
return -1;
- if (!is_nonblocking ())
- {
- sock_thread_data cd = { get_socket (), (sockaddr *) &sin, &namelen, -1 };
- cygthread *thread = new cygthread (connect_thread, &cd, "connect");
- HANDLE waitevt = CreateEvent(&sec_none_nih, FALSE, TRUE, NULL);
- interrupted = thread->detach (waitevt);
- CloseHandle (waitevt);
- if (!interrupted)
- res = cd.ret;
- }
- else
- res = ::connect (get_socket (), (sockaddr *) &sin, namelen);
+ res = ::connect (get_socket (), (sockaddr *) &sin, namelen);
if (res)
{
@@ -596,9 +561,6 @@ fhandler_socket::connect (const struct sockaddr *name, int namelen)
else
set_connect_state (CONNECTED);
- if (interrupted)
- set_errno (EINTR);
-
return res;
}
@@ -638,19 +600,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 ())
- {
- sock_thread_data ad = { get_socket (), peer, len, -1 };
- cygthread *thread = new cygthread (accept_thread, &ad, "accept");
- HANDLE waitevt = CreateEvent(&sec_none_nih, FALSE, TRUE, NULL);
- BOOL interrupted = thread->detach (waitevt);
- CloseHandle (waitevt);
- if (interrupted)
- return -1;
- res = ad.ret;
- }
- else
- res = ::accept (get_socket (), peer, len);
+ res = ::accept (get_socket (), peer, len);
if ((SOCKET) res == INVALID_SOCKET && WSAGetLastError () == WSAEWOULDBLOCK)
in_progress = TRUE;
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;