public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Eric Dumazet <dada1@cosmosbay.com>
To: "linux-os (Dick Johnson)" <linux-os@analogic.com>
Cc: jimmy <jimmyb@huawei.com>, Robert Hancock <hancockr@shaw.ca>,
	linux-kernel <linux-kernel@vger.kernel.org>
Subject: Re: Linux poll() <sigh> again
Date: Fri, 12 May 2006 17:06:20 +0200	[thread overview]
Message-ID: <4464A46C.50101@cosmosbay.com> (raw)
In-Reply-To: <Pine.LNX.4.61.0605121050060.9212@chaos.analogic.com>

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




  reply	other threads:[~2006-05-12 15:06 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <6bkl7-56Y-11@gated-at.bofh.it>
2006-05-12  0:08 ` Linux poll() <sigh> again Robert Hancock
2006-05-12 11:53   ` linux-os (Dick Johnson)
2006-05-12 14:32     ` Robert Hancock
2006-05-12 14:46       ` jimmy
2006-05-12 14:57         ` linux-os (Dick Johnson)
2006-05-12 15:06           ` Eric Dumazet [this message]
2006-05-12 15:12           ` Davide Libenzi
2006-05-12 18:49         ` David Schwartz
2006-05-11 14:25 linux-os (Dick Johnson)
2006-05-11 20:47 ` Nishanth Aravamudan
2006-05-11 21:04   ` linux-os (Dick Johnson)
2006-05-11 21:16     ` Nishanth Aravamudan
2006-05-12 11:42       ` linux-os (Dick Johnson)
2006-05-12 10:37     ` Jan Engelhardt
2006-05-12  5:26 ` David Schwartz

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4464A46C.50101@cosmosbay.com \
    --to=dada1@cosmosbay.com \
    --cc=hancockr@shaw.ca \
    --cc=jimmyb@huawei.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-os@analogic.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox