how to return from a blocked read() ? - Linux

This is a discussion on how to return from a blocked read() ? - Linux ; On Jul 18, 3:22 am, Rainer Weikusat wrote: > There was no 'thread C' in the posted example. Nonsense! What function can you call to confirm that there is no 'thread C'? How do you know some previous library function ...

+ Reply to Thread
Page 2 of 2 FirstFirst 1 2
Results 21 to 24 of 24

Thread: how to return from a blocked read() ?

  1. Re: how to return from a blocked read() ?

    On Jul 18, 3:22 am, Rainer Weikusat wrote:

    > There was no 'thread C' in the posted example.


    Nonsense! What function can you call to confirm that there is no
    'thread C'? How do you know some previous library function you called
    (maybe even 'pthread_create') didn't create a service thread?

    Perhaps you're talking about a case where you personally wrote or
    inspected all the user-space code. But then what about the next
    version of the threading library?

    > This means that your
    > claim about 'mostly working algorithms' has a hidden premise, namely
    > 'assuming there was a thread C doing unsychronized open calls, it
    > could happen that ...'. Which reduces your statement regarding the
    > 'mostly working algorithm' to 'this algorithm cannot solve any problem
    > I (meaning you) can imagine'.
    >
    > And that is a pretty useless statement.


    There is no way you can know whether or not there is a thread C. Just
    like there is no way you can know whether or not the thread was in the
    'read' or about to call it.

    What is it with you and advising people to write code that will break
    in the future and relies on guarantees you don't actually have?

    DS



  2. Re: how to return from a blocked read() ?

    David Schwartz writes:
    > On Jul 18, 2:25 am, Rainer Weikusat wrote:


    [...]

    >> It is, for instance, conceivable that their is additional
    >> locking around the read, meaning, the intention is to wake up the
    >> thread if it happens to blocked in read, instead of having been caught
    >> somewhere else.

    >
    > It can't be done. You would need an atomic 'unlock and read' function,
    > which does not exist.


    It can. A possible solution with two rwlocks: Each receiving thread
    acquires a read lock on rwlock a before calling recv. After leaving
    recv, it first releases this lock and then acquires a read lock on
    rwlock b, which it release before trying to acquire a again. The
    wakeup thread first acquires a write lock on b, then it loops sending
    signals to all receiver threads, trying to get a write lock on a
    until that succeeds and calling sched_yield in between. All threads
    except this one now either wait for rwlock a or rwlock b or will start
    to wait for rwlock a or b shortly.

    [...]

    >> During peak usages times, it presently handles in
    >> excess of 2500 requests coming in over the net per minute and the
    >> wakeup is needed once per hour, so doing two syscalls per request,
    >> instead of one would be a bad tradeoff.

    >
    > I presume you're talking about a program that handles a very small
    > number of connections.


    It is using UDP, so there are no connections.

  3. Re: how to return from a blocked read() ?

    On Jul 19, 1:49 pm, Rainer Weikusat wrote:
    > David Schwartz writes:
    > > On Jul 18, 2:25 am, Rainer Weikusat wrote:

    >
    > [...]
    >
    > >> It is, for instance, conceivable that their is additional
    > >> locking around the read, meaning, the intention is to wake up the
    > >> thread if it happens to blocked in read, instead of having been caught
    > >> somewhere else.

    >
    > > It can't be done. You would need an atomic 'unlock and read' function,
    > > which does not exist.


    > It can. A possible solution with two rwlocks: Each receiving thread
    > acquires a read lock on rwlock a before calling recv. After leaving
    > recv, it first releases this lock and then acquires a read lock on
    > rwlock b, which it release before trying to acquire a again. The
    > wakeup thread first acquires a write lock on b, then it loops sending
    > signals to all receiver threads, trying to get a write lock on a
    > until that succeeds and calling sched_yield in between. All threads
    > except this one now either wait for rwlock a or rwlock b or will start
    > to wait for rwlock a or b shortly.


    That doesn't solve the fundamental problem. The problem is that it is
    literally impossible to tell whether the thread is blocked in
    'read' (in which case, 'close' is safe) or *about* to block in
    'read' (in which case, 'close' is dangerous).

    The thread that calls 'close' must be able to do so while the thread
    is actually blocked in 'read'. Otherwise this is a waste of time. That
    means it also is capable of calling 'close' just before the thread
    calls 'read'.

    The only way around it would be an atomic "unlock and read"
    instruction.

    In other words, any solution that allows one thread to call 'close'
    while another thread is blocked in 'read' must leave open the
    possibility that the 'close' will occur just before the call to
    'read'. It is totally unavoidable.

    > >> During peak usages times, it presently handles in
    > >> excess of 2500 requests coming in over the net per minute and the
    > >> wakeup is needed once per hour, so doing two syscalls per request,
    > >> instead of one would be a bad tradeoff.

    >
    > > I presume you're talking about a program that handles a very small
    > > number of connections.

    >
    > It is using UDP, so there are no connections.


    Ahh, then your solution makes perfect sense.

    DS


  4. Re: how to return from a blocked read() ?

    You know what would be nice? Versions of operations like 'read',
    'write', 'accept', 'select', and so on that took a mutex as a
    parameter. The mutex would be unlocked while/if the operation blocked
    (and reacquired before returning).

    It actually is not as hard to implement as you might think, with
    kernel help. You would only need one function, a way to register a
    mutex with the kernel. The kernel would unlock the mutex when/if the
    thread blocks on I/O. User-space could re-acquire the mutex. (You
    would need a way to know whether the kernel released the mutex, of
    course.)

    This is actually really easy to do on Linux thanks to the futex code
    that already creates locks the kernel understands that are usable from
    user space.

    DS


+ Reply to Thread
Page 2 of 2 FirstFirst 1 2