* 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:
parent
883861544a
commit
fd5879c110
@ -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>
|
2006-07-27 Brian Ford <Brian.Ford@FlightSafety.com>
|
||||||
|
|
||||||
* fhandler_socket.cc (fhandler_socket::recvmsg): Remove unused tot
|
* fhandler_socket.cc (fhandler_socket::recvmsg): Remove unused tot
|
||||||
|
@ -386,7 +386,7 @@ struct wsa_event
|
|||||||
{
|
{
|
||||||
LONG serial_number;
|
LONG serial_number;
|
||||||
long events;
|
long events;
|
||||||
int errorcode;
|
int connect_errorcode;
|
||||||
pid_t owner;
|
pid_t owner;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -443,6 +443,7 @@ search_wsa_event_slot (LONG new_serial_number)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
memset (&wsa_events[slot], 0, sizeof (wsa_event));
|
||||||
wsa_events[slot].serial_number = new_serial_number;
|
wsa_events[slot].serial_number = new_serial_number;
|
||||||
ReleaseMutex (wsa_slot_mtx);
|
ReleaseMutex (wsa_slot_mtx);
|
||||||
return wsa_events + slot;
|
return wsa_events + slot;
|
||||||
@ -490,7 +491,9 @@ fhandler_socket::init_events ()
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
wsock_events = search_wsa_event_slot (new_serial_number);
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -508,9 +511,7 @@ fhandler_socket::evaluate_events (const long event_mask, long &events,
|
|||||||
LOCK_EVENTS;
|
LOCK_EVENTS;
|
||||||
wsock_events->events |= evts.lNetworkEvents;
|
wsock_events->events |= evts.lNetworkEvents;
|
||||||
if (evts.lNetworkEvents & FD_CONNECT)
|
if (evts.lNetworkEvents & FD_CONNECT)
|
||||||
wsock_events->errorcode = evts.iErrorCode[FD_CONNECT_BIT];
|
wsock_events->connect_errorcode = evts.iErrorCode[FD_CONNECT_BIT];
|
||||||
else if (evts.lNetworkEvents & FD_CLOSE)
|
|
||||||
wsock_events->errorcode = evts.iErrorCode[FD_CLOSE_BIT];
|
|
||||||
UNLOCK_EVENTS;
|
UNLOCK_EVENTS;
|
||||||
if ((evts.lNetworkEvents & FD_OOB) && wsock_events->owner)
|
if ((evts.lNetworkEvents & FD_OOB) && wsock_events->owner)
|
||||||
kill (wsock_events->owner, SIGURG);
|
kill (wsock_events->owner, SIGURG);
|
||||||
@ -520,22 +521,18 @@ fhandler_socket::evaluate_events (const long event_mask, long &events,
|
|||||||
LOCK_EVENTS;
|
LOCK_EVENTS;
|
||||||
if ((events = (wsock_events->events & event_mask)) != 0)
|
if ((events = (wsock_events->events & event_mask)) != 0)
|
||||||
{
|
{
|
||||||
if (events & (FD_CONNECT | FD_CLOSE))
|
if (events & FD_CONNECT)
|
||||||
{
|
{
|
||||||
int wsa_err = 0;
|
int wsa_err = 0;
|
||||||
if ((wsa_err = wsock_events->errorcode) != 0)
|
if ((wsa_err = wsock_events->connect_errorcode) != 0)
|
||||||
{
|
{
|
||||||
WSASetLastError (wsa_err);
|
WSASetLastError (wsa_err);
|
||||||
ret = SOCKET_ERROR;
|
ret = SOCKET_ERROR;
|
||||||
}
|
}
|
||||||
if (events & FD_CONNECT)
|
else
|
||||||
{
|
|
||||||
if (!wsock_events->errorcode)
|
|
||||||
wsock_events->events |= FD_WRITE;
|
wsock_events->events |= FD_WRITE;
|
||||||
wsock_events->events &= ~FD_CONNECT;
|
wsock_events->events &= ~FD_CONNECT;
|
||||||
}
|
wsock_events->connect_errorcode = 0;
|
||||||
if (!(events & FD_CLOSE))
|
|
||||||
wsock_events->errorcode = 0;
|
|
||||||
}
|
}
|
||||||
if (erase)
|
if (erase)
|
||||||
wsock_events->events &= ~(events & ~(FD_WRITE | FD_CLOSE));
|
wsock_events->events &= ~(events & ~(FD_WRITE | FD_CLOSE));
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/* poll.cc. Implements poll(2) via usage of select(2) call.
|
/* 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.
|
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);
|
FD_SET(fds[i].fd, read_fds);
|
||||||
if (fds[i].events & POLLOUT)
|
if (fds[i].events & POLLOUT)
|
||||||
FD_SET(fds[i].fd, write_fds);
|
FD_SET(fds[i].fd, write_fds);
|
||||||
/* On sockets, except_fds is needed to catch failed connects. */
|
if (fds[i].events & POLLPRI)
|
||||||
if ((fds[i].events & POLLPRI)
|
|
||||||
|| cygheap->fdtab[fds[i].fd]->is_socket ())
|
|
||||||
FD_SET(fds[i].fd, except_fds);
|
FD_SET(fds[i].fd, except_fds);
|
||||||
}
|
}
|
||||||
else if (fds[i].fd >= 0)
|
else if (fds[i].fd >= 0)
|
||||||
@ -127,7 +125,6 @@ poll (struct pollfd *fds, unsigned int nfds, int timeout)
|
|||||||
}
|
}
|
||||||
/* Handle failed connect. */
|
/* Handle failed connect. */
|
||||||
if (FD_ISSET(fds[i].fd, write_fds)
|
if (FD_ISSET(fds[i].fd, write_fds)
|
||||||
&& FD_ISSET(fds[i].fd, except_fds)
|
|
||||||
&& (sock = cygheap->fdtab[fds[i].fd]->is_socket ())
|
&& (sock = cygheap->fdtab[fds[i].fd]->is_socket ())
|
||||||
&& sock->connect_state () == connect_failed)
|
&& sock->connect_state () == connect_failed)
|
||||||
fds[i].revents |= (POLLIN | POLLERR);
|
fds[i].revents |= (POLLIN | POLLERR);
|
||||||
|
@ -364,21 +364,19 @@ set_bits (select_record *me, fd_set *readfds, fd_set *writefds,
|
|||||||
{
|
{
|
||||||
/* Special AF_LOCAL handling. */
|
/* Special AF_LOCAL handling. */
|
||||||
if (!me->read_ready && sock->connect_state () == connect_pending
|
if (!me->read_ready && sock->connect_state () == connect_pending
|
||||||
&& sock->af_local_connect () && me->read_selected)
|
&& sock->af_local_connect ())
|
||||||
|
{
|
||||||
|
if (me->read_selected)
|
||||||
UNIX_FD_SET (me->fd, readfds);
|
UNIX_FD_SET (me->fd, readfds);
|
||||||
|
sock->connect_state (connect_failed);
|
||||||
|
}
|
||||||
|
else
|
||||||
sock->connect_state (connected);
|
sock->connect_state (connected);
|
||||||
}
|
}
|
||||||
ready++;
|
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++;
|
ready++;
|
||||||
}
|
}
|
||||||
@ -1264,23 +1262,21 @@ peek_socket (select_record *me, bool)
|
|||||||
{
|
{
|
||||||
fhandler_socket *fh = (fhandler_socket *) me->fh;
|
fhandler_socket *fh = (fhandler_socket *) me->fh;
|
||||||
long events;
|
long events;
|
||||||
long evt_mask = (FD_CLOSE
|
/* Don't play with the settings again, unless having taken a deep look into
|
||||||
| (me->read_selected ? (FD_READ | FD_ACCEPT) : 0)
|
Richard W. Stevens Network Programming book. Thank you. */
|
||||||
| (me->write_selected ? (FD_WRITE | FD_CONNECT) : 0)
|
long evt_mask = (me->read_selected ? (FD_READ | FD_ACCEPT | FD_CLOSE) : 0)
|
||||||
| (me->except_selected ? (FD_OOB | FD_CONNECT) : 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);
|
int ret = fh->evaluate_events (evt_mask, events, false);
|
||||||
if (me->read_selected)
|
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 (me->write_selected)
|
||||||
{
|
me->write_ready |= ret || !!(events & (FD_WRITE | FD_CONNECT | FD_CLOSE));
|
||||||
if ((events & FD_CONNECT) && !ret)
|
|
||||||
me->write_ready = true;
|
|
||||||
else
|
|
||||||
me->write_ready |= !!(events & (FD_WRITE | FD_CLOSE));
|
|
||||||
}
|
|
||||||
if (me->except_selected)
|
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;
|
return me->read_ready || me->write_ready || me->except_ready;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user