Austin Group Defect Tracker

Aardvark Mark IV


Viewing Issue Simple Details Jump to Notes ] Issue History ] Print ]
ID Category Severity Type Date Submitted Last Update
0001448 [Issue 8 drafts] System Interfaces Objection Error 2021-02-02 22:12 2021-07-02 10:58
Reporter kre View Status public  
Assigned To
Priority normal Resolution Accepted As Marked  
Status Applied   Product Version Draft 1.1
Name Robert Elz
Organization
User Reference
Section XSH 3/poll()
Page Number 1399-1400
Line Number 46800-1. 46807-46813, 46820, 46824, 46867
Final Accepted Text Note: 0005386
Summary 0001448: Misleading text in description of poll()
Description This report is about wording, I do not believe I am reporting any
technical issues with the text, simply incorrect ways of saying what
it is attempting to say. If this should have been filed as "Editorial"
rather than "Objection" then please change - but note that the issues are
not (quite) simple typos, punctuation errors, or similar.

I am also filing this against issue 8 draft 1.1 as the text in poll() has
been updated from issue 7 (+TC2) but the updates do not affect the issues I see
(I believe) so it could just as easily been files against that one.

At lines 46800-1:
   The poll( ) function shall identify those file descriptors on which an
   application can read or write data, or [...]

That would imply that (given a POLLIN response in revents) that it is
possible to successfully read data, which is not true. Later the text
(correctly) says (line 46846)
    Regular files shall always poll TRUE for reading and writing.
and that's true even if the seek pointer (current offset into the file)
is at EOF, in which case there is no more data to read.

Line 46807 (and lines 46808, 46809, and 46810 which are similar)
say it better:
    POLLIN Data other than high-priority data may be read without blocking.

what's important about poll() (and select()) is that after being told
that an operation may be attempted, the application will not block when
performing the relevant operation, not that anything in particular will
be returned from the attempt.

Much the same applies to the write is OK bits in revents - but there
there's another problem, the bit set indicates that some data can be
written without blocking, but it does not promise how much. The
APPLICATION USAGE section should probably be changed from None (line 46867)
and say that applications wanting to avoid blocking when writing need
to do all of: use poll() (or select()), set non-blocking mode on the
file descriptor, and write relatively small chunks of data (where how
small will depend upon the kind of file the descriptor references) - as
no matter what poll() says, since non-blocking mode does not apply in any
useful way to regular file i/o, if an application attempts to write a
gigabyte to a file in one operation, it is going to block.

And while this (at line 46819) about POLLHUP might be true
    This event and POLLOUT are mutually-exclusive;
however the rationale given (line 46820) makes no sense:
    a stream can never be writable if a hangup has occurred.
as what poll() is indicating is that the application will not
block if it attempts to (in this case) write using the file descriptor,
which is true if a hanhup has occurred, the write simply returns immediately
with an error indication.

In line 46824
    POLLNVAL The specified fd value is invalid.

Is there a definition somewhere of what it means for a file descriptor
to be "invalid". Normally one might assume that this would (inter alia)
include negative values, as file descriptors are all >= 0, but lines 46828-9
say what happens in the case of a fd < 0, and setting POLLNVAL is not it.

So does this just mean a fd greater than the maximum permitted by the
implementation? Or does an "invalid" fd simply mean one that is not
open? (that is where a read/write (etc) would return EBADF, except in
the < 0 case). Or something different than that?

[Aside; XBD 3.136 *File Descriptor" does not define "invalid" ones, there
is no definition of "invalid" (alone) in XBD 3 that I can see, but that I
failed to find it doesn't mean that it doesn't exist somewhere.


It might also be worth bringing back the EXAMPLES section that has been
deleted for Issue 8 (which was all about STREAMS I/O, all obsolete,
and so quite rightly deleted) with an example (or two) using sockets, the
application field (along with terminal I/O) where poll() is most used.
But supplying text for that in this bug report is too much for now...
If that does happen, please do not attempt to copy the old EXAMPLES text
at all, all that nonsense about "permission to write" was simply bigus
(poll has nothing whatever to do with permissions, or any other kind of
authorisation).
Desired Action In the settence beginning on line 46801, change the words
    on which an application can read or write data
to
    on which an application can make an attempt to read or write data
    without blocking

In line 46808 change
    POLLRDNORM Normal data may be read without blocking.
to
    POLLRDNORM An attempt to read normal data will not block.

and similar changes on lines 46807, 46809, and 46810).

On line 46811 change
    POLLOUT Normal data may be written without blocking.
to
    POLLOUT An attempt to write one byte of data will not block.
                 How much data may be written without blocking depends
                 upon the object underlying the file descriptor, and its
                 current state.

and a similar change on line 46813 (because of the way it is worded, lime
46812 needs no change). Note that line 46813 (alone of all of these lines)
does not mention "without blocking", it should.

On line 46820 delete the words (and punctuation)
    ; a stream can never be writable if a hangup has occurred

On line 46824 either add an xref to the definition of "invalid" as it
applies to file descriptors, or change the words
     is invalid
to
     {something, I have no idea what this is actually trying to say}
but just maybe to:
     does not represent an open file descriptor in the process [thread ??].
     
On line 46867 change
     None
to (something like):
     When poll() indicates a read may be attempted, a resulting read()
     call may return data, indicate EOF, or indicate an error, but shall
     not block. When poll() indicates that a write may be attempted,
     the application may write one or more bytes, however, when more than
     one byte is written, there is no guarantee that no block will occur.
     Applications which desire to write more than a single byte each time
     poll() indicates that a write may occur, and which want to avoid
     blocking need to take other measures to determine how much may be
     successfully written.

     Applications should note that repeating a poll() call which indicated
     that I/O was possible on one or more of the file descriptors given,
     without causing some change to the state, either by altering the fds[]
     array, or causing appropriate input or output to occur on at least one
     file descriptor indicated as ready will simply result in ppll() busy
     waiting - a subsequent call will always return immediately indicating
     the same (or perhaps more) revents as the previous one.

It would also be useful to have more information included on how the
various flags apply to terminals and sockets (rather than the undue overload
applied to FIFOs). What constitutes an error (POLLERR) or hangup (POLLHUP)
or a terminal fd? A hangup, a revoked fd, a parity error ??? And similarly
for sockets, a closed connection? Receipt of an ICMP message (on INET[46[
sockets), a TCP RST? a TCP FIN? Lack of response (broken network) (after
how long?)

Lines 46826-7 do say:
    The significance and semantics of normal, priority, and high-priority
    data are file and device-specific.
but there is nothing similar about HUP or ERR.
Tags issue8
Attached Files

- Relationships

-  Notes
(0005386)
geoffclare (manager)
2021-06-18 14:08
edited on: 2021-06-24 15:29

In the June 17th teleconference we decided that we should align the wording for poll() with what is currently used for select(), i.e. talk about descriptors being "ready for reading/writing" (with an explanation of what that means).

I think the following changes are close to what we would have come up with if we hadn't run out of time. My aim in posting them here is that we should use this as the starting point on the June 24th call, but will be able to address any feedback in that call rather than waiting for a subsequent call.

Page and line numbers are for draft 1.1 but the changes account for the addition of ppoll() in draft 2.

In the sentence beginning on line 46801, change:
on which an application can read or write data
to:
on which an application can make an attempt to read or write data without blocking

At line 46807, change:
POLLIN Data other than high-priority data may be read without blocking.
to:
POLLIN The file descriptor is ready for reading data other than high-priority data.

In line 46808 change:
POLLRDNORM Normal data may be read without blocking.
to:
POLLRDNORM The file descriptor is ready for reading normal data.

In line 46809 change:
POLLRDBAND Priority data may be read without blocking.
to:
POLLRDBAND The file descriptor is ready for reading priority data.

In line 46810 change:
POLLPRI High-priority data may be read without blocking.
to:
POLLPRI The file descriptor is ready for reading high-priority data.

In line 46811 change:
POLLOUT Normal data may be written without blocking.
to:
POLLOUT The file descriptor is ready for writing normal data.

In line 46813 change:
POLLWRBAND Priority data may be written.
to:
POLLWRBAND The file descriptor is ready for writing priority data.

In line 46814 change:
An error has occurred on the device or stream.
to:
An error condition is present on the file descriptor. All error conditions that arise solely from the state of the object underlying the open file description and would be diagnosed by a return of -1 from a read() or write() call on the file descriptor shall be reported as a POLLERR event.

On line 46820 delete the words (and punctuation):
; a stream can never be writable if a hangup has occurred

On line 46824 change:
is invalid
to:
is not an open file descriptor

Before line 46826 insert a new paragraph:
A file descriptor shall be considered ready for reading when a call to an input function with O_NONBLOCK clear would not block, whether or not the function would transfer data successfully. (The function might return data, an end-of-file indication, or an error other than one indicating that it is blocked, and in each of these cases the descriptor is considered ready for reading.) A file descriptor shall be considered ready for writing when a call to an output function with O_NONBLOCK clear would not block, whether or not the function would transfer data successfully. How much data could be written without blocking depends upon the object underlying the open file description and its current state.

On line 46826-7 after:
The significance and semantics of normal, priority, and high-priority data are file and device-specific.
add:
The semantics of device disconnection are device-specific.

On line 46867 change APPLICATION USAGE from:
None
to:
When a poll() or ppoll() call indicates a file descriptor is ready for reading, this means that if an attempt to read data had been made at the time that the status of the file descriptor was checked, it would have returned at least one byte of data, an end-of-file indication, or an error, without blocking (even if O_NONBLOCK is clear). When a poll() or ppoll() call indicates that a file descriptor is ready for writing, this means that if an attempt to write one byte of data had been made at the time that the status of the file descriptor was checked, it would have written that byte or returned an error, without blocking. However, if an attempt to write more than one byte had been made, it might have blocked (if O_NONBLOCK is clear). In both cases, by the time the call returns and a subsequent I/O operation is attempted, the state of the file descriptor might have changed (for example, because another thread read or wrote some data) and, if O_NONBLOCK is clear, there is no guarantee that the operation will not block (unless it would not block for some other reason, such as setting MIN=0 and TIME=0 for a terminal in non-canonical mode). Therefore it is recommended that applications always set O_NONBLOCK on file descriptors whose readiness for I/O they query with poll() or ppoll().

The error conditions specified for read() and write() that are reported as POLLERR events are only those that arise solely from the state of the object underlying the open file description. They do not include, for example, [EAGAIN] as this relates to the state of the open file description not (solely) the object underlying it.

Application writers should note that repeating a poll() or ppoll() call which indicated that I/O was possible on one or more of the file descriptors given, without causing some change to the state, either by altering the fds array or causing appropriate input or output to occur on at least one file descriptor indicated as ready, will result in ``busy waiting'' - a subsequent call will always return immediately indicating the same (or perhaps more) events as the previous one.

On page 1480 line 49261 section pselect(), change APPLICATION USAGE from:
None
to:
When a pselect() or select() call indicates a file descriptor is ready for reading, this means that if an attempt to read data had been made at the time that the status of the file descriptor was checked, it would have returned at least one byte of data, an end-of-file indication, or an error, without blocking (even if O_NONBLOCK is clear). When a pselect() or select() call indicates a file descriptor is ready for writing, this means that if an attempt to write one byte of data had been made at the time that the status of the file descriptor was checked, it would have written that byte or returned an error, without blocking. However, if an attempt to write more than one byte had been made, it might have blocked (if O_NONBLOCK is clear). In both cases, by the time the call returns and a subsequent I/O operation is attempted, the state of the file descriptor might have changed (for example, because another thread read or wrote some data) and, if O_NONBLOCK is clear, there is no guarantee that the operation will not block (unless it would not block for some other reason, such as setting MIN=0 and TIME=0 for a terminal in non-canonical mode). Therefore it is recommended that applications always set O_NONBLOCK on file descriptors whose readiness for I/O they query with pselect() or select().



- Issue History
Date Modified Username Field Change
2021-02-02 22:12 kre New Issue
2021-02-02 22:12 kre Name => Robert Elz
2021-02-02 22:12 kre Section => XSH 3/poll()
2021-02-02 22:12 kre Page Number => 1399-1400
2021-02-02 22:12 kre Line Number => 46800-1. 46807-46813, 46820, 46824, 46867
2021-06-18 14:08 geoffclare Note Added: 0005386
2021-06-24 15:29 geoffclare Note Edited: 0005386
2021-06-24 15:30 geoffclare Final Accepted Text => Note: 0005386
2021-06-24 15:30 geoffclare Status New => Resolved
2021-06-24 15:30 geoffclare Resolution Open => Accepted As Marked
2021-06-24 15:31 geoffclare Tag Attached: issue8
2021-07-02 10:58 geoffclare Status Resolved => Applied


Mantis 1.1.6[^]
Copyright © 2000 - 2008 Mantis Group
Powered by Mantis Bugtracker