Hi Paolino, You wrote: > I have a doubt that this code works like I want because actual STM > implementation exposes its effects > > import Control.Concurrent > import Control.Concurrent.STM > > main = do > c <- atomically $ newTChan :: IO (TChan ()) > r <- atomically $ newTVar False > forkIO $ do > atomically $ do > r0 <- readTVar r > case r0 of > True -> return () > False -> readTChan c > myThreadId >>= killThread > threadDelay 1000000 > atomically (writeTVar r True) > > The thread stops on readTChan, but exits when I change the TVar, which > happens before the readTChan. > > Should I trust this is the correct STM behaviour , and will not change > in different implementations ?
This is correct behaviour. Remember, STM transactions execute atomically, so it doesn't make sense to think of a transaction as being blocked at a particular point in the code. A blocked transaction is just waiting for a state in which it can execute all at once. Calling "retry" is saying that this transaction is not yet ready to execute. As noted by Alberto, readTChan calls "retry" to indicate that it (and whatever transaction called it) cannot execute when the channel is empty. Putting it all together, you can see that your transaction will execute when (and only when) "r" contains True, or when "c" is not empty. Hope that helps, Matthew _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe