* fhandler_socket.cc: Revert misguided attempt to handle FD_CLOSE error

conditions in evaluate_events.
	(search_wsa_event_slot): Move wrongly placed memset in
	fhandler_socket::init_events here.
	(fhandler_socket::init_events): Initially set FD_WRITE event for
	connectionless sockets.
	* poll.cc (poll): Don't add sockets always to except_fds since select
	is now supposed to do it right.
	* select.cc (set_bits): Set connection state correctly for failed
	af_local_connect on local sockets.  Remove socket special handling
	for except_selected descriptors.
	(peek_socket): Try to set the read/write/exception bits actually
	correctly.
This commit is contained in:
Corinna Vinschen 2006-07-27 13:58:54 +00:00
parent 883861544a
commit fd5879c110
4 changed files with 50 additions and 44 deletions

View File

@ -1,3 +1,19 @@
2006-07-27 Corinna Vinschen <corinna@vinschen.de>
* fhandler_socket.cc: Revert misguided attempt to handle FD_CLOSE error
conditions in evaluate_events.
(search_wsa_event_slot): Move wrongly placed memset in
fhandler_socket::init_events here.
(fhandler_socket::init_events): Initially set FD_WRITE event for
connectionless sockets.
* poll.cc (poll): Don't add sockets always to except_fds since select
is now supposed to do it right.
* select.cc (set_bits): Set connection state correctly for failed
af_local_connect on local sockets. Remove socket special handling
for except_selected descriptors.
(peek_socket): Try to set the read/write/exception bits actually
correctly.
2006-07-27 Brian Ford <Brian.Ford@FlightSafety.com>
* fhandler_socket.cc (fhandler_socket::recvmsg): Remove unused tot

View File

@ -386,7 +386,7 @@ struct wsa_event
{
LONG serial_number;
long events;
int errorcode;
int connect_errorcode;
pid_t owner;
};
@ -443,6 +443,7 @@ search_wsa_event_slot (LONG new_serial_number)
return NULL;
}
}
memset (&wsa_events[slot], 0, sizeof (wsa_event));
wsa_events[slot].serial_number = new_serial_number;
ReleaseMutex (wsa_slot_mtx);
return wsa_events + slot;
@ -490,7 +491,9 @@ fhandler_socket::init_events ()
return false;
}
wsock_events = search_wsa_event_slot (new_serial_number);
memset (wsock_events, 0, sizeof *wsock_events);
/* sock type not yet set here. */
if (pc.dev == FH_UDP || pc.dev == FH_DGRAM)
wsock_events->events = FD_WRITE;
return true;
}
@ -508,9 +511,7 @@ fhandler_socket::evaluate_events (const long event_mask, long &events,
LOCK_EVENTS;
wsock_events->events |= evts.lNetworkEvents;
if (evts.lNetworkEvents & FD_CONNECT)
wsock_events->errorcode = evts.iErrorCode[FD_CONNECT_BIT];
else if (evts.lNetworkEvents & FD_CLOSE)
wsock_events->errorcode = evts.iErrorCode[FD_CLOSE_BIT];
wsock_events->connect_errorcode = evts.iErrorCode[FD_CONNECT_BIT];
UNLOCK_EVENTS;
if ((evts.lNetworkEvents & FD_OOB) && wsock_events->owner)
kill (wsock_events->owner, SIGURG);
@ -520,22 +521,18 @@ fhandler_socket::evaluate_events (const long event_mask, long &events,
LOCK_EVENTS;
if ((events = (wsock_events->events & event_mask)) != 0)
{
if (events & (FD_CONNECT | FD_CLOSE))
if (events & FD_CONNECT)
{
int wsa_err = 0;
if ((wsa_err = wsock_events->errorcode) != 0)
if ((wsa_err = wsock_events->connect_errorcode) != 0)
{
WSASetLastError (wsa_err);
ret = SOCKET_ERROR;
}
if (events & FD_CONNECT)
{
if (!wsock_events->errorcode)
wsock_events->events |= FD_WRITE;
wsock_events->events &= ~FD_CONNECT;
}
if (!(events & FD_CLOSE))
wsock_events->errorcode = 0;
else
wsock_events->events |= FD_WRITE;
wsock_events->events &= ~FD_CONNECT;
wsock_events->connect_errorcode = 0;
}
if (erase)
wsock_events->events &= ~(events & ~(FD_WRITE | FD_CLOSE));

View File

@ -1,6 +1,6 @@
/* poll.cc. Implements poll(2) via usage of select(2) call.
Copyright 2000, 2001, 2002, 2003, 2004, 2005 Red Hat, Inc.
Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006 Red Hat, Inc.
This file is part of Cygwin.
@ -63,9 +63,7 @@ poll (struct pollfd *fds, unsigned int nfds, int timeout)
FD_SET(fds[i].fd, read_fds);
if (fds[i].events & POLLOUT)
FD_SET(fds[i].fd, write_fds);
/* On sockets, except_fds is needed to catch failed connects. */
if ((fds[i].events & POLLPRI)
|| cygheap->fdtab[fds[i].fd]->is_socket ())
if (fds[i].events & POLLPRI)
FD_SET(fds[i].fd, except_fds);
}
else if (fds[i].fd >= 0)
@ -127,7 +125,6 @@ poll (struct pollfd *fds, unsigned int nfds, int timeout)
}
/* Handle failed connect. */
if (FD_ISSET(fds[i].fd, write_fds)
&& FD_ISSET(fds[i].fd, except_fds)
&& (sock = cygheap->fdtab[fds[i].fd]->is_socket ())
&& sock->connect_state () == connect_failed)
fds[i].revents |= (POLLIN | POLLERR);

View File

@ -364,22 +364,20 @@ set_bits (select_record *me, fd_set *readfds, fd_set *writefds,
{
/* Special AF_LOCAL handling. */
if (!me->read_ready && sock->connect_state () == connect_pending
&& sock->af_local_connect () && me->read_selected)
UNIX_FD_SET (me->fd, readfds);
sock->connect_state (connected);
&& sock->af_local_connect ())
{
if (me->read_selected)
UNIX_FD_SET (me->fd, readfds);
sock->connect_state (connect_failed);
}
else
sock->connect_state (connected);
}
ready++;
}
if ((me->except_selected || me->except_on_write) && me->except_ready)
if (me->except_selected && me->except_ready)
{
if (me->except_on_write) /* Only on sockets */
{
UNIX_FD_SET (me->fd, writefds);
if ((sock = me->fh->is_socket ()))
sock->connect_state (connect_failed);
}
if (me->except_selected)
UNIX_FD_SET (me->fd, exceptfds);
UNIX_FD_SET (me->fd, exceptfds);
ready++;
}
select_printf ("ready %d", ready);
@ -1264,23 +1262,21 @@ peek_socket (select_record *me, bool)
{
fhandler_socket *fh = (fhandler_socket *) me->fh;
long events;
long evt_mask = (FD_CLOSE
| (me->read_selected ? (FD_READ | FD_ACCEPT) : 0)
| (me->write_selected ? (FD_WRITE | FD_CONNECT) : 0)
| (me->except_selected ? (FD_OOB | FD_CONNECT) : 0));
/* Don't play with the settings again, unless having taken a deep look into
Richard W. Stevens Network Programming book. Thank you. */
long evt_mask = (me->read_selected ? (FD_READ | FD_ACCEPT | FD_CLOSE) : 0)
| (me->write_selected ? (FD_WRITE | FD_CONNECT | FD_CLOSE) : 0)
| (me->except_selected ? FD_OOB : 0);
int ret = fh->evaluate_events (evt_mask, events, false);
if (me->read_selected)
me->read_ready |= !!(events & (FD_READ | FD_ACCEPT | FD_CLOSE));
me->read_ready |= ret || !!(events & (FD_READ | FD_ACCEPT | FD_CLOSE));
if (me->write_selected)
{
if ((events & FD_CONNECT) && !ret)
me->write_ready = true;
else
me->write_ready |= !!(events & (FD_WRITE | FD_CLOSE));
}
me->write_ready |= ret || !!(events & (FD_WRITE | FD_CONNECT | FD_CLOSE));
if (me->except_selected)
me->except_ready |= ret || !!(events & FD_OOB);
me->except_ready |= !!(events & FD_OOB);
select_printf ("read_ready: %d, write_ready: %d, except_ready: %d",
me->read_ready, me->write_ready, me->except_ready);
return me->read_ready || me->write_ready || me->except_ready;
}