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