* fhandler.h (class fhandler_socket): Add timeout parameter to wait()
method. * fhandler_socket.cc (fhandler_socket::connect): Use event driven technique (prepare/wait/release) to implement interuptible connect. (fhandler_socket::wait): Add timeout parameter. Allow FD_CONNECT handling. * net.cc (cygwin_connect): Remove braindead workaround for allowing blocking connect. That's entirely in fhandler_socket::connect now.
This commit is contained in:
parent
ecebee4838
commit
152a9caf58
|
@ -1,3 +1,14 @@
|
||||||
|
2005-10-22 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
|
* fhandler.h (class fhandler_socket): Add timeout parameter to wait()
|
||||||
|
method.
|
||||||
|
* fhandler_socket.cc (fhandler_socket::connect): Use event driven
|
||||||
|
technique (prepare/wait/release) to implement interuptible connect.
|
||||||
|
(fhandler_socket::wait): Add timeout parameter. Allow FD_CONNECT
|
||||||
|
handling.
|
||||||
|
* net.cc (cygwin_connect): Remove braindead workaround for allowing
|
||||||
|
blocking connect. That's entirely in fhandler_socket::connect now.
|
||||||
|
|
||||||
2005-10-22 Corinna Vinschen <corinna@vinschen.de>
|
2005-10-22 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
* include/cygwin/version.h: Fix typo.
|
* include/cygwin/version.h: Fix typo.
|
||||||
|
|
|
@ -425,7 +425,7 @@ class fhandler_socket: public fhandler_base
|
||||||
} status;
|
} status;
|
||||||
|
|
||||||
bool prepare (HANDLE &event, long event_mask);
|
bool prepare (HANDLE &event, long event_mask);
|
||||||
int wait (HANDLE event, int flags);
|
int wait (HANDLE event, int flags, DWORD timeout = 10);
|
||||||
void release (HANDLE event);
|
void release (HANDLE event);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -681,7 +681,20 @@ fhandler_socket::connect (const struct sockaddr *name, int namelen)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
res = ::connect (get_socket (), (struct sockaddr *) &sin, namelen);
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!res)
|
if (!res)
|
||||||
err = 0;
|
err = 0;
|
||||||
|
@ -877,14 +890,14 @@ fhandler_socket::prepare (HANDLE &event, long event_mask)
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
fhandler_socket::wait (HANDLE event, int flags)
|
fhandler_socket::wait (HANDLE event, int flags, DWORD timeout)
|
||||||
{
|
{
|
||||||
int ret = SOCKET_ERROR;
|
int ret = SOCKET_ERROR;
|
||||||
int wsa_err = 0;
|
int wsa_err = 0;
|
||||||
WSAEVENT ev[2] = { event, signal_arrived };
|
WSAEVENT ev[2] = { event, signal_arrived };
|
||||||
WSANETWORKEVENTS evts;
|
WSANETWORKEVENTS evts;
|
||||||
|
|
||||||
switch (WSAWaitForMultipleEvents (2, ev, FALSE, 10, FALSE))
|
switch (WSAWaitForMultipleEvents (2, ev, FALSE, timeout, FALSE))
|
||||||
{
|
{
|
||||||
case WSA_WAIT_TIMEOUT:
|
case WSA_WAIT_TIMEOUT:
|
||||||
ret = 0;
|
ret = 0;
|
||||||
|
@ -910,7 +923,14 @@ fhandler_socket::wait (HANDLE event, int flags)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (evts.lNetworkEvents & FD_READ)
|
if (evts.lNetworkEvents & FD_CONNECT)
|
||||||
|
{
|
||||||
|
if (evts.iErrorCode[FD_CONNECT_BIT])
|
||||||
|
wsa_err = evts.iErrorCode[FD_CONNECT_BIT];
|
||||||
|
else
|
||||||
|
ret = 0;
|
||||||
|
}
|
||||||
|
else if (evts.lNetworkEvents & FD_READ)
|
||||||
{
|
{
|
||||||
if (evts.iErrorCode[FD_READ_BIT])
|
if (evts.iErrorCode[FD_READ_BIT])
|
||||||
wsa_err = evts.iErrorCode[FD_READ_BIT];
|
wsa_err = evts.iErrorCode[FD_READ_BIT];
|
||||||
|
|
|
@ -775,56 +775,7 @@ cygwin_connect (int fd, const struct sockaddr *name, int namelen)
|
||||||
if (efault.faulted (EFAULT) || !fh)
|
if (efault.faulted (EFAULT) || !fh)
|
||||||
res = -1;
|
res = -1;
|
||||||
else
|
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);
|
syscall_printf ("%d = connect (%d, %p, %d)", res, fd, name, namelen);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue