This is the mail archive of the
cygwin-developers@cygwin.com
mailing list for the Cygwin project.
Re: [tolj@wapme-systems.de: Re: Problem with accept?!!
Thomas,
On Tue, Jun 03, 2003 at 02:01:15PM +0200, Corinna Vinschen wrote:
> FYI, I've just switch accept() to use cygwin_select instead of its own
> thread. Works like a charm. fhandler_socket::accept looks like this:
> [...]
I have a complete new implementation now, using cygwin_select. It seems
to work really nicely. However, would you mind to have a look into this
before I check it in? Again, all my tests are working fine, this time
even the message when trying to connect an already connected socket makes
sense :-)
I've attached the patch related to current CVS. Note that I've moved
the cygwin_select stuff into cygwin_connect and cygwin_accept in net.cc
since there's the natural point at which the file descriptor is still
accessible (instead of propagating the descriptor to the fhandler_socket
method).
Corinna
* 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.
Index: fhandler_socket.cc
===================================================================
RCS file: /cvs/src/src/winsup/cygwin/fhandler_socket.cc,v
retrieving revision 1.102
diff -u -p -r1.102 fhandler_socket.cc
--- fhandler_socket.cc 2 Jun 2003 21:20:22 -0000 1.102
+++ fhandler_socket.cc 3 Jun 2003 12:43:04 -0000
@@ -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
}
}
-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 s
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 s
else
set_connect_state (CONNECTED);
- if (interrupted)
- set_errno (EINTR);
-
return res;
}
@@ -638,19 +600,7 @@ fhandler_socket::accept (struct sockaddr
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;
Index: net.cc
===================================================================
RCS file: /cvs/src/src/winsup/cygwin/net.cc,v
retrieving revision 1.143
diff -u -p -r1.143 net.cc
--- net.cc 13 Mar 2003 11:31:24 -0000 1.143
+++ net.cc 3 Jun 2003 12:43:04 -0000
@@ -773,7 +773,56 @@ cygwin_connect (int fd, const struct soc
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, write_fds))
+ res = 0;
+ else if (res > 0)
+ {
+ 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
+ {
+ 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 *
|| !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;
--
Corinna Vinschen Please, send mails regarding Cygwin to
Cygwin Developer mailto:cygwin@cygwin.com
Red Hat, Inc.