[Haskell-cafe] Race conditions with threadWait(Read/Write) and closeFdWith

Leon Smith leon.p.smith at gmail.com
Wed Sep 3 17:40:41 UTC 2014


On Wed, Sep 3, 2014 at 4:21 AM, John Lato <jwlato at gmail.com> wrote:

> On Tue, Sep 2, 2014 at 12:26 PM, Leon Smith <leon.p.smith at gmail.com>
> wrote:
>
>> On Tue, Sep 2, 2014 at 1:31 PM, Felipe Lessa <felipe.lessa at gmail.com>
>> wrote:
>>
>>> I don't see how one could allow concurrent readers and "closers" without
>>>  leaving this small opening.  The best workaround I can think of is to
>>> create a blocking close operation that waits for readers using a
>>> semaphore.
>>
>>
>> Well yes,  I can't think of a simple lock-based solution to this problem,
>>  because you don't want to hold any kind of lock while you are blocked on
>> the file descriptor.
>>
>
> If you wanted to go this route, you could use an MVar (Maybe (Int,Fd)),
> where the Int is a count of interested threads.  Instead of using readMVar
> before threadWaitRead, you would use modifyMVar to atomically increment the
> counter and retrieve the fd.  Then, after threadWaitRead returns, decrement
> the counter.  You'd need to make sure that you never close an fd when the
> counter is greater than 0.  This would work better with a TMVar, because
> then the close operation could block until the counter has changed.
>

I think the semantics should probably be for a concurrent close to
immediately close the descriptor,  with exceptions raised in any threads
that are blocked on the descriptor.    It seems that any sort of use-case
along these lines is going to result in an exception eventually... so you
might as well make it prompt.     So I still don't see any lock-based
solution for my intended semantics.


> threadWaitReadMVar fd = (atomically . fst) =<< withMVar fd
>> threadWaitReadSTM
>>
>
>> This should work even in the presence of async exceptions, barring bugs
> in withMVar and threadWaitReadSTM.  You can implement your registerWaitRead
> using forkIO and MVars, but I think the only reason to do so would be for
> compatibility with older ghcs.  It's probably more sensible to just copy
> the definition of threadWaitReadSTM in that case, unless you want to target
> pre-STM compiler versions.
>

I think you are right;   I suppose an async exception could result in
interest registered in the descriptor without ever waiting on it,  but this
really isn't a big deal, especially as the callback will be removed from
the IO manager once the descriptor becomes readable or the descriptor is
closed.    And it shouldn't prevent the higher-level inotify "descriptor"
from being garbage-collected either,  as the IO manager doesn't know
anything about that,  so the finalizer can still close the descriptor.

Best,
Leon
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.haskell.org/pipermail/haskell-cafe/attachments/20140903/8a7af21a/attachment.html>


More information about the Haskell-Cafe mailing list