[Haskell-cafe] readMVar and the devils

Simon Marlow simonmar at microsoft.com
Fri Jul 2 06:12:36 EDT 2004


On 02 July 2004 10:16, Conor T McBride wrote:

> Hi folks
> 
> I'm having a play with Concurrent Haskell, and came across this in the
> library.
> 
>    readMVar :: MVar a -> IO a
>    This is a combination of takeMVar and putMVar; ie. it takes the
>    value from the MVar, puts it back, and also returns it.
> 
> I was just wondering if I understand things correctly. Suppose myMVar
> is nonempty and I have one thread executing
> 
>    do x <- takeMVar myMVar      -- (A)
>       putMVar myMVar x          -- (B)
>       return x
> 
> and another executing
> 
>    putMVar myMVar y             -- (C)
> 
> Questions
> 
> (1) Is it possible that an evil scheduler will execute (A) then (C)
>        and block on (B)?

Yes.  In fact, you don't need an evil scheduler, an ordinary scheduler
will do this :-)

> (2) Is it the case that if myMVar is nonempty and readMVar is chosen
>        for execution, that readMVar myMVar takes the value
>        from myMVar, guaranteed that the _same_ value will be put
>        back immediately, and also returned?

Only if there are no other threads executing putMVar on myMVar
concurrently.

> (3) If yes to both, what combination of takeMVar and putMVar manages
>        to maintain the lock in between the two?

There isn't one.

readMVar is only atomic with respect to other well-behaved threads; that
is, other threads doing strictly take-followed-by-put operations.

There are lots of similar cases in the world of MVars.  Our general
approach is that we provide combinators which help you build correct
code (eg. withMVar, modifyMVar), but you can always shoot yourself in
the foot by using the lower-level operations.

> I'm only asking, because I'm trying to cook up some kind of partial
> evaluator for programs which are being simultaneously edited by
> fiercely argumentative devils. Kind of `demonic laziness', where
> the computations decide when _they_ feel like running (eg sometime
> after the program turns up), rather than the `angelic laziness' we're
> used to. I'd like to use MVars in a write-once-read-many style, so
> that once someone fills in a bit of program, it stays put. I'd hate
> for another devil to sneak in a replacement program just in the
> twinkling of an eye between taking something out to read and putting
> it back to be read again. 
>
> I guess I could use some kind of extra semaphore MVar to ensure that
> the reader has the lock on the program MVar, but that's more like
> hard work. Is readMVar what I want?

It sounds like you want a different abstraction, but one that can almost
certainly be built using MVars.  I'm not sure exactly what it is you
need, but if you provide the signatures of the operations then I could
probably sketch an implementation.

Cheers,
	Simon


More information about the Haskell-Cafe mailing list