select() returns Success when device referred by fd no longer exists - Linux

This is a discussion on select() returns Success when device referred by fd no longer exists - Linux ; Hi all, I establish a bluetooth connection and created a virtual serial port called /dev/rfcomm0. I open this device and wait for data in select() . I receive data from another PC and process it properly. But when i disconnect, ...

+ Reply to Thread
Results 1 to 19 of 19

Thread: select() returns Success when device referred by fd no longer exists

  1. select() returns Success when device referred by fd no longer exists

    Hi all,

    I establish a bluetooth connection and created a virtual serial port
    called /dev/rfcomm0. I open this device and wait for data in
    select() . I receive data from another PC and process it properly. But
    when i disconnect, select() returns SUCCESS which seems to be strange.

    Any idea of what may be wrong? I could post code id needed.

  2. Re: select() returns Success when device referred by fd no longerexists

    Harry wrote:

    > Hi all,
    >
    > I establish a bluetooth connection and created a virtual serial port
    > called /dev/rfcomm0. I open this device and wait for data in
    > select() . I receive data from another PC and process it properly. But
    > when i disconnect, select() returns SUCCESS which seems to be strange.
    >


    select() doesn't return SUCCESS.

    from man select:

    "On success, select() and pselect() return the number of file descriptors
    contained in the three returned descriptor sets (that is, the total
    number of bits that are set in readfds, writefds, exceptfds) which may be
    zero if the timeout expires before anything interesting happens. On error,
    -1 is returned, and errno is set appropriately; the sets and timeout become
    undefined, so do not rely on their contents after an error."


    --
    SF

    Games are very educational. Scrabble teaches us vocabulary, Monopoly teaches
    us cash-flow management, and Dungeons & Dragons teaches us to loot dead bodies.

  3. Re: select() returns Success when device referred by fd no longerexists

    I am sorry for that "SUCCESS". You are right, but i don't get either
    -1 or 0.
    By SUCCESS i meant the same thing.

    On Aug 28, 5:14 pm, Dildo Bogumil di Boscopelo
    wrote:
    > Harry wrote:
    > > Hi all,

    >
    > > I establish a bluetooth connection and created a virtual serial port
    > > called /dev/rfcomm0. I open this device and wait for data in
    > > select() . I receive data from another PC and process it properly. But
    > > when i disconnect, select() returns SUCCESS which seems to be strange.

    >
    > select() doesn't return SUCCESS.
    >
    > from man select:
    >
    > "On success, select() and pselect() return the number of file descriptors
    > contained in the three returned descriptor sets (that is, the total
    > number of bits that are set in readfds, writefds, exceptfds) which may be
    > zero if the timeout expires before anything interesting happens. On error,
    > -1 is returned, and errno is set appropriately; the sets and timeout become
    > undefined, so do not rely on their contents after an error."
    >
    > --
    > SF
    >
    > Games are very educational. Scrabble teaches us vocabulary, Monopoly teaches
    > us cash-flow management, and Dungeons & Dragons teaches us to loot dead bodies.



  4. Re: select() returns Success when device referred by fd no longer exists

    Harry wrote:
    > I establish a bluetooth connection and created a virtual serial port
    > called /dev/rfcomm0. I open this device and wait for data in
    > select() . I receive data from another PC and process it properly. But
    > when i disconnect, select() returns SUCCESS which seems to be strange.


    I guess what happens here is the common confusion about what
    select() tells you. It doesn't tell you that there's something
    you can read but that there's a file descriptor you can call
    read() on without getting blocked. And that's true when the
    writing side closes the connection: the next call of read()
    will return 0 immediately without blocking, indicating that
    the connection is closed.

    select() only returns -1 if you either invoked it with invalid
    arguments (e.g. one of the file descriptors is invalid, the
    highest file descriptors to monitor is negative or the timeout
    value is invalid), a signal gets caught or if it runs out of
    memory.
    Regards, Jens
    --
    \ Jens Thoms Toerring ___ jt@toerring.de
    \__________________________ http://toerring.de

  5. Re: select() returns Success when device referred by fd no longer exists

    On August 28, 2008 09:29, in comp.os.linux.development.apps, Harry
    (gehariprasath@gmail.com) wrote:

    > I am sorry for that "SUCCESS". You are right, but i don't get either
    > -1 or 0.


    Why would you expect to?

    select() is, in effect, looking for state changes in the specified fds. If
    one or more of the selected fd's receives data, or goes to EOF, or has any
    other change that will result in read() or write() not blocking, then
    select() will return a positive count. select() would only return a count
    of 0 when the timeout occurs first, and a -1 if some error caused select()
    to terminate early.

    You'll probably find that the fd associated with your bluetooth connection
    has either gone to EOF, or has had an exception, and thus select() will
    have modified the appropriate fd bitlist (the readfds or exceptfds list).

    > By SUCCESS i meant the same thing.
    >
    > On Aug 28, 5:14 pm, Dildo Bogumil di Boscopelo
    > wrote:
    >> Harry wrote:
    >> > Hi all,

    >>
    >> > I establish a bluetooth connection and created a virtual serial port
    >> > called /dev/rfcomm0. I open this device and wait for data in
    >> > select() . I receive data from another PC and process it properly. But
    >> > when i disconnect, select() returns SUCCESS which seems to be strange.

    >>
    >> select() doesn't return SUCCESS.
    >>
    >> from man select:
    >>
    >> "On success, select() and pselect() return the number of file
    >> descriptors
    >> contained in the three returned descriptor sets (that is, the total
    >> number of bits that are set in readfds, writefds, exceptfds) which
    >> may be
    >> zero if the timeout expires before anything interesting happens. On
    >> error, -1 is returned, and errno is set appropriately; the sets and
    >> timeout become
    >> undefined, so do not rely on their contents after an error."
    >>
    >> --
    >> SF
    >>
    >> Games are very educational. Scrabble teaches us vocabulary, Monopoly
    >> teaches us cash-flow management, and Dungeons & Dragons teaches us to
    >> loot dead bodies.


    --
    Lew Pitcher

    Master Codewright & JOAT-in-training | Registered Linux User #112576
    http://pitcher.digitalfreehold.ca/ | GPG public key available by request
    ---------- Slackware - Because I know what I'm doing. ------



  6. Re: select() returns Success when device referred by fd no longerexists

    On Aug 28, 7:00*am, j...@toerring.de (Jens Thoms Toerring) wrote:

    > I guess what happens here is the common confusion about what
    > select() tells you. It doesn't tell you that there's something
    > you can read but that there's a file descriptor you can call
    > read() on without getting blocked.


    That's a very inaccurate statement of what 'select' is telling you.
    It's like saying that 'statfs' tells you how much disk space you can
    use without getting a 'disk full' error. The return from 'select' is
    not remembered somehow to turn the next 'read' call into a non-
    blocking one.

    DS


  7. Re: select() returns Success when device referred by fd no longer ?exists

    David Schwartz wrote:
    > On Aug 28, 7:00*am, j...@toerring.de (Jens Thoms Toerring) wrote:


    > > I guess what happens here is the common confusion about what
    > > select() tells you. It doesn't tell you that there's something
    > > you can read but that there's a file descriptor you can call
    > > read() on without getting blocked.


    > That's a very inaccurate statement of what 'select' is telling you.
    > It's like saying that 'statfs' tells you how much disk space you can
    > use without getting a 'disk full' error. The return from 'select' is
    > not remembered somehow to turn the next 'read' call into a non-
    > blocking one.


    Ok, I try to be more precise: If select() returns 1 and one
    of the entries in the returned fd_set for reading is set,
    then one is guaranteed that a read() call for the corres-
    ponding file won't block. But that doesn't guarantee that
    read() will return a single byte from the file descriptor,
    it may also return 0, either because whatever was writing
    to that file descriptor has closed, because the end of the
    file had already been reached or because it's a descriptor
    for something that was opened in non-blocking mode (but then
    calling select() for that file descriptor hardy makes sense).

    What I think is important to understand is that select() tells
    you "for one of the files descriptors I am waiting for in the
    set of read/write descriptors the next I/O operation will not
    block" and not "there are data to be read or data can be writ-
    ten for one of these file descriptors".

    Regards, Jens
    --
    \ Jens Thoms Toerring ___ jt@toerring.de
    \__________________________ http://toerring.de

  8. Re: select() returns Success when device referred by fd no longer exists

    David Schwartz writes:
    > On Aug 28, 7:00*am, j...@toerring.de (Jens Thoms Toerring) wrote:
    >> I guess what happens here is the common confusion about what
    >> select() tells you. It doesn't tell you that there's something
    >> you can read but that there's a file descriptor you can call
    >> read() on without getting blocked.

    >
    > That's a very inaccurate statement of what 'select' is telling you.


    It is almost literally identical to the definition of select:

    A descriptor shall be considered ready for reading when a call
    to an input function with O_NONBLOCK clear would not block[1]

    Which means the same as 'read can be called without blocking[2]' (it
    still doesn't mean 'had read been called, the call would not have
    blocked'[3*])
    [*] I'll try this in German, maybe someone is capable doing
    a better translation into English than me:

    [1] Ein Dateibeischreiber soll als lesbar angesehen werden, wenn
    ein read-Aufruf nicht blockieren wuerde.

    [2] Read kann aufgerufen werden ohne das der Aufruf blockieren
    wird.

    [3] Waere read (anstelle von select) aufgerufen worden,
    haette der Aufruf nicht blockiert.

    > It's like saying that 'statfs' tells you how much disk space you can
    > use without getting a 'disk full' error.


    This is still a wrong analogy: 'statfs' returns the amount of free
    disk space at the time of the call. Under normal conditions, the
    amount can change at any time because the disk (being mounted
    somewhere in the filesystem tree) is a resource shared by all running
    processes, each of which may consume (or free) diskspace whenever it
    actually runs. If the resource whose status select has reported is
    shared depends both on the resource and on the execution history of
    the system, ie which other processes can acess it, for instance,
    because they have an open file descriptor refering to it, too. It need
    not be shared, although it may.

    > The return from 'select' is not remembered somehow to turn the next
    > 'read' call into a nonblocking one.


    The condition which caused select to indicate that a particular
    descriptor would be readable is 'remembered somehow' (otherwise,
    select couldn't have checked it) and without 'something' happening
    which changes this state, it won't change.

  9. Re: select() returns Success when device referred by fd no longer?exists

    On Aug 28, 10:06*am, j...@toerring.de (Jens Thoms Toerring) wrote:

    > Ok, I try to be more precise: If select() returns 1 and one
    > of the entries in the returned fd_set for reading is set,
    > then one is guaranteed that a read() call for the corres-
    > ponding file won't block.


    Nope, that's not true. No system call makes that kind of future
    guarantee.

    > But that doesn't guarantee that
    > read() will return a single byte from the file descriptor,
    > it may also return 0, either because whatever was writing
    > to that file descriptor has closed, because the end of the
    > file had already been reached or because it's a descriptor
    > for something that was opened in non-blocking mode (but then
    > calling select() for that file descriptor hardy makes sense).


    Or, it might block.

    > What I think is important to understand is that select() tells
    > you "for one of the files descriptors I am waiting for in the
    > set of read/write descriptors the next I/O operation will not
    > block" and not "there are data to be read or data can be writ-
    > ten for one of these file descriptors".


    No, it doesn't predict the future. This is a common misunderstanding,
    and it's a very serious one. Just as 'access' doesn't guarantee you
    that a subsequent access will actually succeed, so 'select' doesn't
    tell you that a subsequent access won't block.

    What both of these functions tell you is that a particular status
    existed during at least some instant in-between when you called the
    status-reporting function and when that function returned. None of the
    functions guarantee that this status will still be the case later when
    you decide to act on it.

    DS

  10. Re: select() returns Success when device referred by fd no longerexists

    On Aug 28, 10:16*am, Rainer Weikusat wrote:

    > It is almost literally identical to the definition of select:
    >
    > * * * * A descriptor shall be considered ready for reading when acall
    > * * * * to an input function with O_NONBLOCK clear would not block[1]


    No, notice the "would". This is *very* different from "will". This
    "would" is referring to a hypothetical concurrent operation, not a
    future actual one.

    > Which means the same as 'read can be called without blocking[2]' (it
    > still doesn't mean 'had read been called, the call would not have
    > blocked'[3*])


    Nope, not so. For example, the documentation for "access" could have
    read "A file shall be considered accessible for reading when a call to
    an open function for reading would not return a permission error".
    This *definitely* doesn't mean a future open is guaranteed to succeed.

    > > It's like saying that 'statfs' tells you how much disk space you can
    > > use without getting a 'disk full' error.


    > This is still a wrong analogy: 'statfs' returns the amount of free
    > disk space at the time of the call.


    Bingo. Same with 'select'. It tells you that the socket *was* readable
    for at least some instant in-between when you called 'select' and when
    it returned.

    > Under normal conditions, the
    > amount can change at any time because the disk (being mounted
    > somewhere in the filesystem tree) is a resource shared by all running
    > processes, each of which may consume (or free) diskspace whenever it
    > actually runs. If the resource whose status select has reported is
    > shared depends both on the resource and on the execution history of
    > the system, ie which other processes can acess it, for instance,
    > because they have an open file descriptor refering to it, too. It need
    > not be shared, although it may.


    Exactly. Network connections are always shared, because they have more
    than one end. UDP sockets consume memory reserved for network protocol
    data, which may or may not be a shared resource. In practice, there is
    no way to know what is a shared resource on a given system, and you
    pretty much have to assume everything might be shared.

    > > The return from 'select' is not remembered somehow to turn the next
    > > 'read' call into a nonblocking one.


    > The condition which caused select to indicate that a particular
    > descriptor would be readable is 'remembered somehow' (otherwise,
    > select couldn't have checked it)


    Huh? The 'select' function checked it, but that check is immediately
    forgotten. The semantics of a remembered 'select' are impossible to
    define. For example, suppose you call 'select' and get an indication.
    This doesn't assure you that the system that the next 'read' operation
    will be the one you expected not to block. There is no way to figure
    out which read is the "subsequent read" you were thinking of. You
    might decide not to call 'read' then and later call 'read' in a
    completely independent code path.

    Having a 'select' affect the semantics of the "subsequent" operation
    would be impossible.

    > and without 'something' happening
    > which changes this state, it won't change.


    Right, but something can happen. The system might run low on memory
    and have to drop some network packets. The other end might change the
    state of the network connection. Another thread or process might
    operate on the connection. You are not guaranteed that the state will
    remain to a subsequent operation because there is no unambiguous way
    to figure out which operation is subsequent.

    DS

  11. Re: select() returns Success when device referred by fd no longer ??exists

    David Schwartz wrote:
    > On Aug 28, 10:06*am, j...@toerring.de (Jens Thoms Toerring) wrote:


    > > Ok, I try to be more precise: If select() returns 1 and one
    > > of the entries in the returned fd_set for reading is set,
    > > then one is guaranteed that a read() call for the corres-
    > > ponding file won't block.


    > Nope, that's not true. No system call makes that kind of future
    > guarantee.


    > > But that doesn't guarantee that
    > > read() will return a single byte from the file descriptor,
    > > it may also return 0, either because whatever was writing
    > > to that file descriptor has closed, because the end of the
    > > file had already been reached or because it's a descriptor
    > > for something that was opened in non-blocking mode (but then
    > > calling select() for that file descriptor hardy makes sense).


    > Or, it might block.


    > > What I think is important to understand is that select() tells
    > > you "for one of the files descriptors I am waiting for in the
    > > set of read/write descriptors the next I/O operation will not
    > > block" and not "there are data to be read or data can be writ-
    > > ten for one of these file descriptors".


    > No, it doesn't predict the future. This is a common misunderstanding,
    > and it's a very serious one. Just as 'access' doesn't guarantee you
    > that a subsequent access will actually succeed, so 'select' doesn't
    > tell you that a subsequent access won't block.


    > What both of these functions tell you is that a particular status
    > existed during at least some instant in-between when you called the
    > status-reporting function and when that function returned. None of the
    > functions guarantee that this status will still be the case later when
    > you decide to act on it.


    Good argument! On the other hand there's the POSIX (SUSv3) de-
    scription of select(). I read there (obviously snipped down to
    the parts I think are relevant, so I might overlooking something
    important!):

    The pselect() function shall examine the file descriptor sets
    whose addresses are passed in the readfds, writefds, and errorfds
    parameters to see whether some of their descriptors are ready
    for reading, are ready for writing, or have an exceptional
    condition pending, respectively.

    This is followed by a few restrictions of what select() doesn't do
    in comparison to pselect() but that don't seem to me to be relevant
    to the topic under discussion here. Further on there is a defintion
    of what "ready for reading/writing" means:

    A 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 des-
    criptor shall be considered ready for reading.)

    A 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.

    As far as I understand this it looks to me more or less like what
    I wrote, i.e. that if select() indicates that a file descriptor is
    readable a read() call won't block (but nothing else). So my inter-
    pretation is that select() actually makes a promise about what will
    happen in the future.

    The man page on my system is even more straight to the point:

    A file descriptor is considered ready if it is possible to
    perform the corresponding I/O operation (e.g., read(2))
    without blocking.

    While I can easily follow your argument about access() and what
    guarantees it's not making, I am not yet convinced that this is
    also valid for select(). With access() you make a query for an
    a file that your process hasn't any direct connection with (you
    just pass it the name of a file you didn't open (yet0 and which
    could go away or be changed at any moment). But with select()
    you make a query for an "object" (file, pipe, socket etc.) you
    already did open, so you should get some more reliable informa-
    tion about what you can or can't do with it. Certainly making
    predictions about the future is extremely difficult but according
    to my reading of POSIX I would assume that this is what's expected
    from select() (and having been at the "promising end" when writing
    a device driver that supported a select() call I understand that
    it's something not always trivial to get right).

    Thank you for the interesting discussion, I am looking forward to
    your reply (but it's now time to go to bed over herer, so don't
    expect replies from me tonight anymore;-). Perhaps we should take
    this to comp.unix.programmer since to me it does not seem to be
    just Linux specific but a question concerning all versions of
    UNIX versions that try to be POSIX compliant.

    Best regards, Jens
    --
    \ Jens Thoms Toerring ___ jt@toerring.de
    \__________________________ http://toerring.de

  12. Re: select() returns Success when device referred by fd no longer??exists

    On Aug 28, 4:53*pm, j...@toerring.de (Jens Thoms Toerring) wrote:

    > * A 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 des-
    > * criptor shall be considered ready for reading.)


    > * A 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.


    Notice again the "would", not "will".

    > As far as I understand this it looks to me more or less like what
    > I wrote, i.e. that if select() indicates that a file descriptor is
    > readable a read() call won't block (but nothing else).


    A read call *WOULD* not block, had there been one at the time.

    This is the same for 'access'. Access indicates that an open would not
    fail (if issued at the time).

    > So my inter-
    > pretation is that select() actually makes a promise about what will
    > happen in the future.


    Nope. Where does it say that?

    No status-reporting function makes a promise about what will happen in
    the future. And make no mistake about it, select is a status-reporting
    function. "Ready to read" is a status.

    > The man page on my system is even more straight to the point:


    > * *A file descriptor *is considered ready if it is possible to
    > * *perform the corresponding I/O operation (e.g., read(2))
    > * *without blocking.


    This is correct. This is telling us what "ready" means. This doesn't
    say that if a socket *was* ready, it must still be ready. If you try
    to define precisely when it must still be ready, you'll notice very
    quickly that it's impossible.

    > While I can easily follow your argument about access() and what
    > guarantees it's not making, I am not yet convinced that this is
    > also valid for select(). With access() you make a query for an
    > a file that your process hasn't any direct connection with (you
    > just pass it the name of a file you didn't open (yet0 and which
    > could go away or be changed at any moment). But with *select()
    > you make a query for an "object" (file, pipe, socket etc.) you
    > already did open, so you should get some more reliable informa-
    > tion about what you can or can't do with it.


    It would be the same if 'access' took a file descriptor. It's still a
    shared resource, just like a network connection is.

    > Certainly making
    > predictions about the future is extremely difficult but according
    > to my reading of POSIX I would assume that this is what's expected
    > from select() (and having been at the "promising end" when writing
    > a device driver that supported a select() call I understand that
    > it's something not always trivial to get right).


    It's actually *impossible* to get right. (Remember, this guarantee is
    not TCP-specific, it's supposed to apply to any protocol that 'select'
    could ever be used on, even hypothetical ones. It's trivial to create
    a protocol where such a requirement is impossible to meet.)

    > Thank you for the interesting discussion, I am looking forward to
    > your reply (but it's now time to go to bed over herer, so don't
    > expect replies from me tonight anymore;-). Perhaps we should take
    > this to comp.unix.programmer since to me it does not seem to be
    > just Linux specific but a question concerning all versions of
    > UNIX versions that try to be POSIX compliant.


    I'm pretty sure it's already been discussed to death. In any event, in
    practice, existing systems do not guarantee this and programs that
    have assumed it have failed, in documented cases this has had security
    implications.

    DS

  13. Re: select() returns Success when device referred by fd no longer ???exists

    David Schwartz wrote:
    > On Aug 28, 4:53*pm, j...@toerring.de (Jens Thoms Toerring) wrote:


    > > * A 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 des-
    > > * criptor shall be considered ready for reading.)


    > > * A 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.


    > Notice again the "would", not "will".


    > > As far as I understand this it looks to me more or less like what
    > > I wrote, i.e. that if select() indicates that a file descriptor is
    > > readable a read() call won't block (but nothing else).


    > A read call *WOULD* not block, had there been one at the time.


    Ok, i see your point after re-reading those sentences for about
    20 times;-) Sorry for being a bit dense, but then English isn't
    my first language and this is a bit of legalese...

    > This is the same for 'access'. Access indicates that an open would not
    > fail (if issued at the time).


    > > So my inter-
    > > pretation is that select() actually makes a promise about what will
    > > happen in the future.


    > Nope. Where does it say that?


    > No status-reporting function makes a promise about what will happen in
    > the future. And make no mistake about it, select is a status-reporting
    > function. "Ready to read" is a status.


    Basically, that means that the use of select() I have seen at
    more than once, i.e. calls of select() when waiting for some-
    thing to read with a timeout in order not to wait longer than
    a certain amount of time, can backfire badly if one of the file
    descriptors becomes ready for reading, the process than calls
    read() but in the mean time the status has changed again and
    the process now waits for an arbitrary long time, being blocked
    until it can really read.

    So one would either need some kind of "atomic" select and do I/O
    function to get it right or, without that existing, one would have
    to switch to non-blocking mode before the I/O operation is done in
    all cases where one wants to make sure one doesn't wait more than a
    certain time. Correct?

    David, thank you for the free lesson;-)

    Best regards, Jens
    --
    \ Jens Thoms Toerring ___ jt@toerring.de
    \__________________________ http://toerring.de

  14. Re: select() returns Success when device referred by fd no longer???exists

    On 2008-08-29, Jens Thoms Toerring wrote:

    > So one would either need some kind of "atomic" select and do I/O
    > function to get it right or, without that existing, one would have
    > to switch to non-blocking mode before the I/O operation is done in
    > all cases where one wants to make sure one doesn't wait more than a
    > certain time. Correct?


    Correct. If you want to make sure you don't block in an I/O
    operation you must use non-blocking I/O calls. The results of
    select() aren't a guarantee, just a very strong hint. Many
    people who write apps using select() in combination with
    blocking I/O calls will never have any problems, but if you
    wan't to do it the "right" way, you use non-blocking I/O.

    --
    Grant Edwards grante Yow! FROZEN ENTREES may
    at be flung by members of
    visi.com opposing SWANSON SECTS ...

  15. Re: select() returns Success when device referred by fd no longer ???exists

    jt@toerring.de (Jens Thoms Toerring) writes:
    > David Schwartz wrote:
    >> On Aug 28, 4:53*pm, j...@toerring.de (Jens Thoms Toerring) wrote:

    >
    >> > * A 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 des-
    >> > * criptor shall be considered ready for reading.)

    >
    >> > * A 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.

    >
    >> Notice again the "would", not "will".

    >
    >> > As far as I understand this it looks to me more or less like what
    >> > I wrote, i.e. that if select() indicates that a file descriptor is
    >> > readable a read() call won't block (but nothing else).

    >
    >> A read call *WOULD* not block, had there been one at the time.

    >
    > Ok, i see your point after re-reading those sentences for about
    > 20 times;-) Sorry for being a bit dense, but then English isn't
    > my first language and this is a bit of legalese...


    David is still wrong. He is (and will likely continue this way
    forever) confusing a subjunctive refering to a hypothetical past event
    with a subjunctive refering to a [future] possibility. The German
    (grammar) names for these two would be 'Irrealis' and 'Potentialis'.

  16. Re: select() returns Success when device referred by fd no longer ???exists

    Grant Edwards writes:
    > On 2008-08-29, Jens Thoms Toerring wrote:
    >> So one would either need some kind of "atomic" select and do I/O
    >> function to get it right or, without that existing, one would have
    >> to switch to non-blocking mode before the I/O operation is done in
    >> all cases where one wants to make sure one doesn't wait more than a
    >> certain time. Correct?

    >
    > Correct. If you want to make sure you don't block in an I/O
    > operation you must use non-blocking I/O calls. The results of
    > select() aren't a guarantee, just a very strong hint.


    The result of 'select' is 'a guarantee' that a certain condition
    was true at the time 'select' checked it. And this condition will not
    'automagically' change on its own. Something needs to change it.
    For a file descriptor (minus implementation quirks), this must be
    something another process which posesses an open file descriptor
    refering to the same resource has done in the meantime.

  17. Re: select() returns Success when device referred by fd no longer exists

    David Schwartz writes:
    > On Aug 28, 10:16*am, Rainer Weikusat wrote:
    >> It is almost literally identical to the definition of select:
    >>
    >> * * * * A descriptor shall be considered ready for reading when a call
    >> * * * * to an input function with O_NONBLOCK clear would not block[1]

    >
    > No, notice the "would". This is *very* different from "will". This
    > "would" is referring to a hypothetical concurrent operation, not a
    > future actual one.


    It refer to a future possible one. Otherwise, the sentence would
    need to use some 'past tense form' ('would not have blocked', which
    is, AFAIK, formally incorrect, or 'had not blocked', which, again
    AFAIK, would be formally correct).

    [...]

    >> > It's like saying that 'statfs' tells you how much disk space you can
    >> > use without getting a 'disk full' error.

    >
    >> This is still a wrong analogy: 'statfs' returns the amount of free
    >> disk space at the time of the call. Under normal conditions, the
    >> amount can change at any time because the disk (being mounted
    >> somewhere in the filesystem tree) is a resource shared by all running
    >> processes, each of which may consume (or free) diskspace whenever it
    >> actually runs. If the resource whose status select has reported is
    >> shared depends both on the resource and on the execution history of
    >> the system, ie which other processes can acess it, for instance,
    >> because they have an open file descriptor refering to it, too. It need
    >> not be shared, although it may.
    >>


    [ incorrect interjection removed ]

    > Exactly. Network connections are always shared, because they have more
    > than one end.


    This discussion refers only to the state on the local system, which
    the remote system cannot change. At best, it could send a message
    requesting such a change.

    [...]

    >> The condition which caused select to indicate that a particular
    >> descriptor would be readable is 'remembered somehow' (otherwise,
    >> select couldn't have checked it)

    >
    > Huh? The 'select' function checked it, but that check is immediately
    > forgotten.


    That's why I was writing about the condition.

    [...]

    >> and without 'something' happening
    >> which changes this state, it won't change.

    >
    > Right, but something can happen. The system might run low on memory
    > and have to drop some network packets.


    If you ever implement that buggy kernel, please put a BIG note on it:
    This has been written to demonstrate that received data is trash.
    Don't use.

  18. Re: select() returns Success when device referred by fd no longer???exists

    On Aug 29, 4:35*am, j...@toerring.de (Jens Thoms Toerring) wrote:

    > Basically, that means that the use of select() I have seen at
    > more than once, i.e. calls of *select() when waiting for some-
    > thing to read with a timeout in order not to wait longer than
    > a certain amount of time, can backfire badly if one of the file
    > descriptors becomes ready for reading, the process than calls
    > read() but in the mean time the status has changed again and
    > the process now waits for an arbitrary long time, being blocked
    > until it can really read.


    Only if the code was broken to begin with. You cannot make bricks out
    of straw. If you want non-blocking operation, all that POSIX asks is
    that you set your sockets non-blocking.

    > So one would either need some kind of "atomic" select and do I/O
    > function to get it right or, without that existing, one would have
    > to switch to non-blocking mode before the I/O operation is done in
    > all cases where one wants to make sure one doesn't wait more than a
    > certain time. Correct?


    You should definitely use non-blocking socket operations if you don't
    want to block. Things do get ugly if you need to combine both blocking
    and non-blocking socket operations. Sorry, that's just the way it is.

    > David, thank you for the free lesson;-)


    My pleasure.

    DS

  19. Re: select() returns Success when device referred by fd no longer???exists

    On Aug 29, 9:21*am, Rainer Weikusat wrote:

    > The result of 'select' is 'a guarantee' that a certain condition
    > was true at the time 'select' checked it. And this condition will not
    > 'automagically' change on its own. Something needs to change it.
    > For a file descriptor (minus implementation quirks), this must be
    > something another process which posesses an open file descriptor
    > refering to the same resource has done in the meantime.


    There are three problems with this:

    1) All sockets are shared resources that can be changed by network
    activity.

    2) Things like system memory are shared resources. UDP datagrams can
    be discarded, for example, changing the readability of a UDP socket.

    3) There might be something you can't think of that might change the
    status. This may strike at the worst possible moment. (There are,
    sadly, many such stories. Consider, for example, if you receive a
    packet with a bad UDP checksum, it triggers a select hit, then someone
    turns off UDP checksum checking, then the application call 'recvmsg'.)

    The simple point is, there's no guarantee. POSIX doesn't make one.
    Real-world systems don't honor them.

    DS

+ Reply to Thread