STM and TVar report incorrect results
On Haskell Cafe, I posted:
I'm getting strange behavior when using the 'many' combinator to read zero or more items off of a TQueue with readTQueue. The script that exhibits this behavior is as follows:
import Control.Concurrent.STM import Control.Concurrent import Control.Monad import Control.Applicative main = do q <- newTQueueIO atomically $ writeTQueue q True atomically $ writeTQueue q False forever $ do xs <- atomically $ many $ readTQueue q print xs threadDelay 500000
I'd expect the output of the script to be:
[True,False]   ...
However, that is not the case: the actual output of the script is:
[True,False] [True,False] [True,False] ...
If 1 element (say, True) is written into the TQueue instead of 2, then the output of the script is:
[True]   ...
Which is expected behavior, but inconsistent with the behavior when the TQueue has 2 or more elements in it.
Is this considered a bug, or undocumented behavior of TQueue?
Bas vas Dijk noted that this may be a bug in STM, and provided a condensed test case which reproduces the behavior of my original script:
$ cat stmTest.hs import Control.Concurrent.STM main = do x <- atomically $ do t <- newTVar 1 writeTVar t 2 ((readTVar t >> retry) `orElse` return ()) `orElse` return () readTVar t print x $ ghc --make stmTest.hs -fforce-recomp -threaded -o stmTest && ./stmTest [1 of 1] Compiling Main ( stmTest.hs, stmTest.o ) Linking stmTest ... 1
The program prints 1 when it should print 2.