Skip to content
  • Simon Marlow's avatar
    [project @ 2001-07-06 14:11:38 by simonmar] · 1c5d2a15
    Simon Marlow authored
    Fix a couple of nasty bugs in the take/putMVar implementation.
    
    Now we keep the invariant that a full MVar only has blocked putMVars
    on its queue, and an empty MVar only has blocked takeMVars on its
    queue.  It was the absence of this invariant that led to accidental
    deadlock before.
    
    The second bug is that there was a window between a blocked thread
    being restarted and it actually retrying the takeMVar/putMVar
    operation when it could receive an exception, which would also lead to
    deadlock.
    
    The solution to both these problems (as suggested by Simon P.J.) is to
    atomically wake up and perform the next blocked putMVar when we do a
    take, and vice versa.  As a side effect, takeMVar & putMVar should be
    much faster when blocking & restarting, because we now shortcut the
    retrying of the blocked operation and we use a more specialised stack
    layout for the blocked thread.  Unfortunately, things got more
    complicated too, but there are comments explaining what's going on.
    1c5d2a15