Revert code reversion from 2004-04-03. So, revert to async I/O again.

* fhandler.h (status): Add "closed" flag.
	(prepare): New method declaration.
	(wait): Ditto.
	(release): Ditto.
	* fhandler_socket.cc: Don't include wsock_event.h.
	(fhandler_socket::prepare): New method, moved from wsock_event.
	(fhandler_socket::wait): Ditto.
	(fhandler_socket::release): New method.
	(fhandler_socket::recvfrom): Simplify loop.
	(fhandler_socket::recvmsg): Ditto.
	(fhandler_socket::sendto): Ditto.
	(fhandler_socket::sendmsg): Ditto.
	* net.cc: Don't include wsock_event.h.
	(wsock_event::prepare): Remove.
	(wsock_event::wait): Ditto.
	* wsock_event.h: Remove.
This commit is contained in:
Corinna Vinschen 2004-05-07 07:51:31 +00:00
parent dab22ff6e6
commit 3e101fb2cd
5 changed files with 192 additions and 142 deletions

View File

@ -1,6 +1,22 @@
2004-05-06 Christopher Faylor <cgf@alum.bu.edu> 2004-05-07 Corinna Vinschen <corinna@vinschen.de>
* Revert code reversion from 2004-04-03. So, revert to async I/O again.
* fhandler.h (status): Add "closed" flag.
(prepare): New method declaration.
(wait): Ditto.
(release): Ditto.
* fhandler_socket.cc: Don't include wsock_event.h.
(fhandler_socket::prepare): New method, moved from wsock_event.
(fhandler_socket::wait): Ditto.
(fhandler_socket::release): New method.
(fhandler_socket::recvfrom): Simplify loop.
(fhandler_socket::recvmsg): Ditto.
(fhandler_socket::sendto): Ditto.
(fhandler_socket::sendmsg): Ditto.
* net.cc: Don't include wsock_event.h.
(wsock_event::prepare): Remove.
(wsock_event::wait): Ditto.
* wsock_event.h: Remove.
2004-05-06 Christopher Faylor <cgf@alum.bu.edu> 2004-05-06 Christopher Faylor <cgf@alum.bu.edu>

View File

@ -340,14 +340,19 @@ class fhandler_socket: public fhandler_base
unsigned async_io : 1; /* async I/O */ unsigned async_io : 1; /* async I/O */
unsigned saw_shutdown_read : 1; /* Socket saw a SHUT_RD */ unsigned saw_shutdown_read : 1; /* Socket saw a SHUT_RD */
unsigned saw_shutdown_write : 1; /* Socket saw a SHUT_WR */ unsigned saw_shutdown_write : 1; /* Socket saw a SHUT_WR */
unsigned closed : 1;
unsigned connect_state : 2; unsigned connect_state : 2;
public: public:
status_flags () : status_flags () :
async_io (0), saw_shutdown_read (0), saw_shutdown_write (0), async_io (0), saw_shutdown_read (0), saw_shutdown_write (0),
connect_state (unconnected) closed (0), connect_state (unconnected)
{} {}
} status; } status;
bool prepare (HANDLE &event, long event_mask);
int wait (HANDLE event);
void release (HANDLE event);
public: public:
fhandler_socket (); fhandler_socket ();
~fhandler_socket (); ~fhandler_socket ();
@ -357,6 +362,7 @@ class fhandler_socket: public fhandler_base
IMPLEMENT_STATUS_FLAG (bool, async_io) IMPLEMENT_STATUS_FLAG (bool, async_io)
IMPLEMENT_STATUS_FLAG (bool, saw_shutdown_read) IMPLEMENT_STATUS_FLAG (bool, saw_shutdown_read)
IMPLEMENT_STATUS_FLAG (bool, saw_shutdown_write) IMPLEMENT_STATUS_FLAG (bool, saw_shutdown_write)
IMPLEMENT_STATUS_FLAG (bool, closed)
IMPLEMENT_STATUS_FLAG (conn_state, connect_state) IMPLEMENT_STATUS_FLAG (conn_state, connect_state)
int bind (const struct sockaddr *name, int namelen); int bind (const struct sockaddr *name, int namelen);

View File

@ -30,7 +30,6 @@
#include "dtable.h" #include "dtable.h"
#include "cygheap.h" #include "cygheap.h"
#include "sigproc.h" #include "sigproc.h"
#include "wsock_event.h"
#include "cygthread.h" #include "cygthread.h"
#include "select.h" #include "select.h"
#include <unistd.h> #include <unistd.h>
@ -695,6 +694,95 @@ fhandler_socket::getpeername (struct sockaddr *name, int *namelen)
return res; return res;
} }
bool
fhandler_socket::prepare (HANDLE &event, long event_mask)
{
WSASetLastError (0);
closed (false);
if ((event = WSACreateEvent ()) == WSA_INVALID_EVENT)
{
debug_printf ("WSACreateEvent: %E");
return false;
}
if (WSAEventSelect (get_socket (), event, event_mask) == SOCKET_ERROR)
{
debug_printf ("WSAEventSelect: %E");
return false;
}
return true;
}
int
fhandler_socket::wait (HANDLE event)
{
int ret = SOCKET_ERROR;
int wsa_err = 0;
WSAEVENT ev[2] = { event, signal_arrived };
WSANETWORKEVENTS evts;
switch (WSAWaitForMultipleEvents (2, ev, FALSE, WSA_INFINITE, FALSE))
{
case WSA_WAIT_EVENT_0:
if (!WSAEnumNetworkEvents (get_socket (), event, &evts))
{
if (!evts.lNetworkEvents)
{
ret = 0;
break;
}
if (evts.lNetworkEvents & FD_READ)
{
if (evts.iErrorCode[FD_READ_BIT])
wsa_err = evts.iErrorCode[FD_READ_BIT];
else
ret = 0;
}
else if (evts.lNetworkEvents & FD_WRITE)
{
if (evts.iErrorCode[FD_WRITE_BIT])
wsa_err = evts.iErrorCode[FD_WRITE_BIT];
else
ret = 0;
}
if (evts.lNetworkEvents & FD_CLOSE)
{
closed (true);
if (!wsa_err)
{
if (evts.iErrorCode[FD_CLOSE_BIT])
wsa_err = evts.iErrorCode[FD_CLOSE_BIT];
else
ret = 0;
}
}
if (wsa_err)
WSASetLastError (wsa_err);
}
break;
case WSA_WAIT_EVENT_0 + 1:
WSASetLastError (WSAEINTR);
break;
default:
WSASetLastError (WSAEFAULT);
break;
}
return ret;
}
void
fhandler_socket::release (HANDLE event)
{
int last_err = WSAGetLastError ();
/* KB 168349: NT4 fails if the event parameter is not NULL. */
WSAEventSelect (get_socket (), NULL, 0);
unsigned long non_block = 0;
if (ioctlsocket (get_socket (), FIONBIO, &non_block))
debug_printf ("return to blocking failed: %d", WSAGetLastError ());
else
WSASetLastError (last_err);
WSACloseEvent (event);
}
int int
fhandler_socket::readv (const struct iovec *const iov, const int iovcnt, fhandler_socket::readv (const struct iovec *const iov, const int iovcnt,
ssize_t tot) ssize_t tot)
@ -716,7 +804,7 @@ int
fhandler_socket::recvfrom (void *ptr, size_t len, int flags, fhandler_socket::recvfrom (void *ptr, size_t len, int flags,
struct sockaddr *from, int *fromlen) struct sockaddr *from, int *fromlen)
{ {
int res; int res = SOCKET_ERROR;
DWORD ret; DWORD ret;
flags &= MSG_WINMASK; flags &= MSG_WINMASK;
@ -728,19 +816,26 @@ fhandler_socket::recvfrom (void *ptr, size_t len, int flags,
{ {
WSABUF wsabuf = { len, (char *) ptr }; WSABUF wsabuf = { len, (char *) ptr };
if (is_nonblocking ()) if (is_nonblocking () || closed () || async_io ())
res = WSARecvFrom (get_socket (), &wsabuf, 1, &ret, (DWORD *) &flags, res = WSARecvFrom (get_socket (), &wsabuf, 1, (ret = 0, &ret),
from, fromlen, (DWORD *) &flags, from, fromlen, NULL, NULL);
NULL, NULL);
else else
{ {
wsock_event wsock_evt; HANDLE evt;
res = WSARecvFrom (get_socket (), &wsabuf, 1, &ret, (DWORD *) &flags, if (prepare (evt, FD_CLOSE | ((flags & MSG_OOB) ? FD_OOB : FD_READ)))
from, fromlen, {
wsock_evt.prepare (), NULL); do
{
if (res == SOCKET_ERROR && WSAGetLastError () == WSA_IO_PENDING) res = WSARecvFrom (get_socket (), &wsabuf, 1,
ret = res = wsock_evt.wait (get_socket (), (DWORD *) &flags); &ret, (DWORD *) &flags,
from, fromlen, NULL, NULL);
}
while (res == SOCKET_ERROR
&& WSAGetLastError () == WSAEWOULDBLOCK
&& !closed ()
&& !(res = wait (evt)));
release (evt);
}
} }
} }
@ -778,7 +873,7 @@ fhandler_socket::recvmsg (struct msghdr *msg, int flags, ssize_t tot)
struct sockaddr *from = (struct sockaddr *) msg->msg_name; struct sockaddr *from = (struct sockaddr *) msg->msg_name;
int *fromlen = from ? &msg->msg_namelen : NULL; int *fromlen = from ? &msg->msg_namelen : NULL;
int res; int res = SOCKET_ERROR;
if (!winsock2_active) if (!winsock2_active)
{ {
@ -845,21 +940,27 @@ fhandler_socket::recvmsg (struct msghdr *msg, int flags, ssize_t tot)
DWORD ret; DWORD ret;
if (is_nonblocking ()) if (is_nonblocking () || closed () || async_io ())
res = WSARecvFrom (get_socket (), res = WSARecvFrom (get_socket (),
wsabuf, iovcnt, &ret, (DWORD *) &flags, wsabuf, iovcnt, (ret = 0, &ret), (DWORD *) &flags,
from, fromlen, from, fromlen, NULL, NULL);
NULL, NULL);
else else
{ {
wsock_event wsock_evt; HANDLE evt;
res = WSARecvFrom (get_socket (), if (prepare (evt, FD_CLOSE | ((flags & MSG_OOB) ? FD_OOB : FD_READ)))
wsabuf, iovcnt, &ret, (DWORD *) &flags, {
from, fromlen, do
wsock_evt.prepare (), NULL); {
res = WSARecvFrom (get_socket (), wsabuf, iovcnt,
if (res == SOCKET_ERROR && WSAGetLastError () == WSA_IO_PENDING) &ret, (DWORD *) &flags,
ret = res = wsock_evt.wait (get_socket (), (DWORD *) &flags); from, fromlen, NULL, NULL);
}
while (res == SOCKET_ERROR
&& WSAGetLastError () == WSAEWOULDBLOCK
&& !closed ()
&& !(res = wait (evt)));
release (evt);
}
} }
if (res == SOCKET_ERROR) if (res == SOCKET_ERROR)
@ -904,7 +1005,7 @@ fhandler_socket::sendto (const void *ptr, size_t len, int flags,
if (to && !get_inet_addr (to, tolen, &sin, &tolen)) if (to && !get_inet_addr (to, tolen, &sin, &tolen))
return SOCKET_ERROR; return SOCKET_ERROR;
int res; int res = SOCKET_ERROR;
DWORD ret; DWORD ret;
if (!winsock2_active) if (!winsock2_active)
@ -915,21 +1016,29 @@ fhandler_socket::sendto (const void *ptr, size_t len, int flags,
{ {
WSABUF wsabuf = { len, (char *) ptr }; WSABUF wsabuf = { len, (char *) ptr };
if (is_nonblocking ()) if (is_nonblocking () || closed () || async_io ())
res = WSASendTo (get_socket (), &wsabuf, 1, &ret, res = WSASendTo (get_socket (), &wsabuf, 1, (ret = 0, &ret),
flags & MSG_WINMASK, flags & MSG_WINMASK,
(to ? (const struct sockaddr *) &sin : NULL), tolen, (to ? (const struct sockaddr *) &sin : NULL), tolen,
NULL, NULL); NULL, NULL);
else else
{ {
wsock_event wsock_evt; HANDLE evt;
res = WSASendTo (get_socket (), &wsabuf, 1, &ret, if (prepare (evt, FD_CLOSE | FD_WRITE))
flags & MSG_WINMASK, {
(to ? (const struct sockaddr *) &sin : NULL), tolen, do
wsock_evt.prepare (), NULL); {
res = WSASendTo (get_socket (), &wsabuf, 1, &ret,
if (res == SOCKET_ERROR && WSAGetLastError () == WSA_IO_PENDING) flags & MSG_WINMASK,
ret = res = wsock_evt.wait (get_socket (), (DWORD *) &flags); (to ? (const struct sockaddr *) &sin : NULL),
tolen, NULL, NULL);
}
while (res == SOCKET_ERROR
&& WSAGetLastError () == WSAEWOULDBLOCK
&& !(res = wait (evt))
&& !closed ());
release (evt);
}
} }
} }
@ -969,7 +1078,7 @@ fhandler_socket::sendmsg (const struct msghdr *msg, int flags, ssize_t tot)
struct iovec *const iov = msg->msg_iov; struct iovec *const iov = msg->msg_iov;
const int iovcnt = msg->msg_iovlen; const int iovcnt = msg->msg_iovlen;
int res; int res = SOCKET_ERROR;
if (!winsock2_active) if (!winsock2_active)
{ {
@ -1038,21 +1147,28 @@ fhandler_socket::sendmsg (const struct msghdr *msg, int flags, ssize_t tot)
DWORD ret; DWORD ret;
if (is_nonblocking ()) if (is_nonblocking () || closed () || async_io ())
res = WSASendTo (get_socket (), wsabuf, iovcnt, &ret, flags, res = WSASendTo (get_socket (), wsabuf, iovcnt, (ret = 0, &ret),
(struct sockaddr *) msg->msg_name, flags, (struct sockaddr *) msg->msg_name,
msg->msg_namelen, msg->msg_namelen, NULL, NULL);
NULL, NULL);
else else
{ {
wsock_event wsock_evt; HANDLE evt;
res = WSASendTo (get_socket (), wsabuf, iovcnt, &ret, flags, if (prepare (evt, FD_CLOSE | FD_WRITE))
(struct sockaddr *) msg->msg_name, {
msg->msg_namelen, do
wsock_evt.prepare (), NULL); {
res = WSASendTo (get_socket (), wsabuf, iovcnt,
if (res == SOCKET_ERROR && WSAGetLastError () == WSA_IO_PENDING) &ret, flags,
ret = res = wsock_evt.wait (get_socket (), (DWORD *) &flags); (struct sockaddr *) msg->msg_name,
msg->msg_namelen, NULL, NULL);
}
while (res == SOCKET_ERROR
&& WSAGetLastError () == WSAEWOULDBLOCK
&& !(res = wait (evt))
&& !closed ());
release (evt);
}
} }
if (res == SOCKET_ERROR) if (res == SOCKET_ERROR)

View File

@ -35,7 +35,6 @@ details. */
#include "sigproc.h" #include "sigproc.h"
#include "pinfo.h" #include "pinfo.h"
#include "registry.h" #include "registry.h"
#include "wsock_event.h"
#include "cygtls.h" #include "cygtls.h"
extern "C" extern "C"
@ -50,61 +49,6 @@ extern "C"
int sscanf (const char *, const char *, ...); int sscanf (const char *, const char *, ...);
} /* End of "C" section */ } /* End of "C" section */
LPWSAOVERLAPPED
wsock_event::prepare ()
{
LPWSAOVERLAPPED ret = NULL;
SetLastError (0);
if ((event = WSACreateEvent ()) != WSA_INVALID_EVENT)
{
memset (&ovr, 0, sizeof ovr);
ovr.hEvent = event;
ret = &ovr;
}
else if (GetLastError () == ERROR_PROC_NOT_FOUND) /* winsock2 not available */
WSASetLastError (0);
debug_printf ("%d = wsock_event::prepare ()", ret);
return ret;
}
int
wsock_event::wait (int socket, LPDWORD flags)
{
int ret = SOCKET_ERROR;
WSAEVENT ev[2] = { event, signal_arrived };
DWORD len;
switch (WSAWaitForMultipleEvents (2, ev, FALSE, WSA_INFINITE, FALSE))
{
case WSA_WAIT_EVENT_0:
if (WSAGetOverlappedResult (socket, &ovr, &len, FALSE, flags))
ret = (int) len;
break;
case WSA_WAIT_EVENT_0 + 1:
if (!CancelIo ((HANDLE) socket))
{
debug_printf ("CancelIo() %E, fallback to blocking io");
WSAGetOverlappedResult (socket, &ovr, &len, TRUE, flags);
}
else if (WSAGetOverlappedResult (socket, &ovr, &len, FALSE, flags)
&& len > 0)
ret = (int) len;
else
WSASetLastError (WSAEINTR);
break;
case WSA_WAIT_FAILED:
break;
default: /* Should be impossible. *LOL* */
WSASetLastError (WSAEFAULT);
break;
}
WSACloseEvent (event);
event = NULL;
return ret;
}
WSADATA wsadata; WSADATA wsadata;
static fhandler_socket * static fhandler_socket *

View File

@ -1,32 +0,0 @@
/* wsock_event.h: Defining the wsock_event class
Copyright 2002 Red Hat, Inc.
This file is part of Cygwin.
This software is a copyrighted work licensed under the terms of the
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
details. */
#ifndef __WSOCK_EVENT_H__
#define __WSOCK_EVENT_H__
class wsock_event
{
WSAEVENT event;
WSAOVERLAPPED ovr;
public:
wsock_event () : event (NULL) {};
~wsock_event ()
{
if (event)
WSACloseEvent (event);
event = NULL;
};
/* The methods are implemented in net.cc */
LPWSAOVERLAPPED prepare ();
int wait (int socket, LPDWORD flags);
};
#endif /* __WSOCK_EVENT_H__ */