
and I am dumb, sorry. Yes, you are right. In fact the code I had posted on the wiki at http://haskell.org/haskellwiki/SafeConcurrent#SampleVar is
writeSampleVar :: SampleVar a -> a -> IO () writeSampleVar svar value = do withMVar (lockedStore svar) $ \ store -> do _ <- tryTakeMVar store putMVar store value
which is functionally identical to yours. I should not write so hastily on my way out the door... Felipe Lessa wrote:
On Sun, Apr 12, 2009 at 05:12:15PM +0100, Chris Kuklewicz wrote:
Felipe Lessa wrote:
writeSampleVar :: SampleVar a -> a -> IO () writeSampleVar s x = block $ withMVar (svLock s) $ const $ do tryTakeMVar (svData s) putMVar (svData s) x That is obvious, but 'block $' is not atomic.
Threads 1 and 2 get past the tryTakeMVar.
That's why there is a "withMVar (svLock s)", the "const $ do" part is executed serially. It is impossible to have two threads past the "tryTakeMVar".
Then thread 1 succeeds with putMVar and thread 2 blocks.
Thread 2 is not supposed to block, so this is a failure to agree with the specification.
Well, it doesn't block. In the worst case I can imagine a thread could be killed after the 'tryTakeMVar', leaving the 'SampleVar' empty, but I guess the 'block' would prevent that.
-- Felipe.