Urgent need for advice: POLLHUP and sockets
Ove Kaaven
ovek at arcticnet.no
Wed Apr 17 05:44:09 CDT 2002
On Wed, 17 Apr 2002, Martin Wilck wrote:
> > > However, if an application uses asynchronous IO (or only asynchronous
> > > notification via WSAAsyncSelect() or WSAEventSelect()), this also inhibits
> > > reception of POLLIN events which can perfectly well occur if there are
> > > still unread data in the kernel buffers. Thus the app will never notice
> > > that there is still data to be read.
> >
> > Not quite. No more data will arrive on the socket when it's in POLLHUP
> > state, so there's no need for the server to poll.
> > Instead, it notifies the
> > app that there's still data remaining to be read next time it reads from
> > the socket (this is what the "check whether condition is satisfied
> > already" case in sock_reselect does, it explicitly does a poll even if the
> > socket is removed from the main polling loop, in order to check for
> > remaining data).
>
> Hmm - this code went away with CVS version 1.28 of sock.c.
> Perhaps we need to reintroduce it somehow.
I can send you the sock.c I have if you wish, but you may be able to check
out an earlier revision yourself.
> > Sending the app new FD_READ events only after it has read
> > old data is a documented Windows feature; further FD_READ events are held
> > back until the app reads old data, and this is what the wineserver
> > implements, especially in the POLLHUP case.
>
> Sorry, I cannot see what you are talking about, not in the current CVS
> version. All that happens after a read() is issued is
> _enable_event (FD_READ, 0, 0), and that clears the pending mask for
> FD_READ. How would that ever be set again, and FD_READ signalled ?
req->mask is here FD_READ, and the handler contains
sock->pmask &= ~req->mask;
sock->hmask &= ~req->mask;
sock->state |= req->sstate;
sock->state &= ~req->cstate;
sock_reselect( sock );
where sock_reselect includes this at the end
/* check whether condition is satisfied already */
pfd.fd = sock->obj.fd;
pfd.events = ev;
pfd.revents = 0;
poll( &pfd, 1, 0 );
if (pfd.revents)
sock_poll_event( &sock->obj, pfd.revents);
result: sock_poll_event sets FD_READ flag and notifies the application in
response to the _enable_event, i.e. after it has read something, even if
the socket is not in the main poll loop. We never got around to change the
comment to explain this additional function.
> The key probably is that sock_poll_event() was called from
> sock_reselect() if the "condition is satisfied", which is no longer the
> case in 1.28.
If this code path was removed, then you'll probably have to put it back
in.
More information about the wine-devel
mailing list