Messages in this thread | | | Date | Fri, 12 May 2006 17:06:20 +0200 | From | Eric Dumazet <> | Subject | Re: Linux poll() <sigh> again |
| |
linux-os (Dick Johnson) a écrit : > On Fri, 12 May 2006, jimmy wrote: > > >> Robert Hancock wrote: >> >>> linux-os (Dick Johnson) wrote: >>> >>>>> POLLHUP means "The device has been disconnected." This would obviously >>>>> be appropriate for a device such as a serial line or TTY, etc. but for a >>>>> socket it is less obvious that this return value is appropriate. >>>>> >>>>> >>>> Hardly "less obvious". SunOs has returned POLLHUP as has other >>>> Unixes like Interactive, from which the software was ported. It >>>> went from Interactive, to SunOs, to Linux. Linux was the first >>>> OS that required the hack. This was reported several years ago >>>> and I was simply excoriated for having the audacity to report >>>> such a thing. So, I just implemented a hack. Now the hack is >>>> biting me. It's about time for poll() to return the correct >>>> stuff. >>>> >>> The standard doesn't require that a close on a socket should report >>> POLLHUP. Thus this behavior may differ between UNIX implementations. If >>> your software is requiring a POLLHUP to indicate the socket is closed I >>> think it is being unnecessarily picky since read returning 0 universally >>> indicates that the connection has been closed. Such are the compromises >>> that are sometimes required to write portable software. >>> > > This is from the Linux man-page shipped with recent distributions > > > SOCKET(7) Linux ProgrammerâEUR(tm)s Manual SOCKET(7) > > > > +--------------------------------------------------------------------+ > | I/O events | > +-----------+-----------+--------------------------------------------+ > |Event | Poll flag | Occurrence | > +-----------+-----------+--------------------------------------------+ > |Read | POLLIN | New data arrived. | > +-----------+-----------+--------------------------------------------+ > |Read | POLLIN | A connection setup has been completed (for | > | | | connection-oriented sockets) | > +-----------+-----------+--------------------------------------------+ > |Read | POLLHUP | A disconnection request has been initiated | > | | | by the other end. | > +-----------+-----------+--------------------------------------------+ > |Read | POLLHUP | A connection is broken (only for connec- | > | | | tion-oriented protocols). When the socket | > | | | is written SIGPIPE is also sent. | > +-----------+-----------+--------------------------------------------+ > |Write | POLLOUT | Socket has enough send buffer space for | > | | | writing new data. | > +-----------+-----------+--------------------------------------------+ > |Read/Write | POLLIN| | An outgoing connect(2) finished. | > | | POLLOUT | | > +-----------+-----------+--------------------------------------------+ > |Read/Write | POLLERR | An asynchronous error occurred. | > +-----------+-----------+--------------------------------------------+ > |Read/Write | POLLHUP | The other end has shut down one direction. | > +-----------+-----------+--------------------------------------------+ > |Exception | POLLPRI | Urgent data arrived. SIGURG is sent then. | > +-----------+-----------+--------------------------------------------+ > > > If linux doesn't support POLLHUP, then it shouldn't be documented. > I got the same king of crap^M^M^M^Mresponse the last time I reported > this __very__ __obvious__ defect! The information is available > in the kernel. It should certainly report it, just like other > operating systems do, including <shudder> wsock32. > Hi Dick
On socket disconnection, POLLIN set in poll()->revents and recv() returning 0 is the only portable and reliable method.
This is well explained in Stevens book (The absolute reference imho). It was writen well before Linus wrote a single line of C code.
If you dont have this book (that would be a shame !!! )
Please refer to http://www.opengroup.org/onlinepubs/000095399/functions/poll.html
POLLHUP
The device has been disconnected. This event and POLLOUT are mutually-exclusive; a stream can never be writable if a hangup has occurred. However, this event and POLLIN, POLLRDNORM, POLLRDBAND, or POLLPRI are not mutually-exclusive. This flag is only valid in the /revents/ bitmask; it shall be ignored in the /events/ member.
So you should not set POLLHUP in the mem->pfd.events member, since POLLHUP is non maskable.
Also you might find this interesting : http://www.greenend.org.uk/rjk/2001/06/poll.html
More over this comment found in the linux kernel (file net/ipv4/tcp.c) is quite good :
/* * POLLHUP is certainly not done right. But poll() doesn't * have a notion of HUP in just one direction, and for a * socket the read side is more interesting. * * Some poll() documentation says that POLLHUP is incompatible * with the POLLOUT/POLLWR flags, so somebody should check this * all. But careful, it tends to be safer to return too many * bits than too few, and you can easily break real applications * if you don't tell them that something has hung up! * * Check-me. * * Check number 1. POLLHUP is _UNMASKABLE_ event (see UNIX98 and * our fs/select.c). It means that after we received EOF, * poll always returns immediately, making impossible poll() on write() * in state CLOSE_WAIT. One solution is evident --- to set POLLHUP * if and only if shutdown has been made in both directions. * Actually, it is interesting to look how Solaris and DUX * solve this dilemma. I would prefer, if PULLHUP were maskable, * then we could set it on SND_SHUTDOWN. BTW examples given * in Stevens' books assume exactly this behaviour, it explains * why PULLHUP is incompatible with POLLOUT. --ANK * * NOTE. Check for TCP_CLOSE is added. The goal is to prevent * blocking on fresh not-connected or disconnected socket. --ANK */ if (sk->sk_shutdown == SHUTDOWN_MASK || sk->sk_state == TCP_CLOSE) mask |= POLLHUP;
So basically a POLLHUP could be stick in revent if POLLOUT was not given in event, but it would be of litle interest...
Eric
- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
| |