All of lore.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.