GHC issueshttps://gitlab.haskell.org/ghc/ghc/-/issues2019-12-06T20:10:02Zhttps://gitlab.haskell.org/ghc/ghc/-/issues/16707Hanging STM transaction with orElse on writeTVar2019-12-06T20:10:02ZrolandHanging STM transaction with orElse on writeTVarIn the following program the main thread's `atomically` hangs in the second iteration, although no other threads are running (and the transaction would have no reason to retry).
```haskell
import Control.Concurrent
import Control.Concur...In the following program the main thread's `atomically` hangs in the second iteration, although no other threads are running (and the transaction would have no reason to retry).
```haskell
import Control.Concurrent
import Control.Concurrent.STM
import Debug.Trace
main :: IO ()
main = (`mapM_` [1..1000]) $ \_ -> do
traceEventIO "(((("
x <- newTVarIO False
forkIO $ atomically $ writeTVar x True
traceEventIO "----"
atomically $ do -- hangs in the second iteration
_ <- readTVar x
writeTVar x True `orElse` return ()
threadDelay 100000
traceEventIO "))))"
```
Obviously, using `orElse` on `writeTVar` makes no sense, the code here is the result of boiling down a much bigger program.
```
$ ghc -debug Bug.hs
[1 of 1] Compiling Main ( Bug.hs, Bug.o )
Linking Bug ...
```
```
$ ./Bug +RTS -v
created capset 0 of type 2
created capset 1 of type 3
cap 0: initialised
assigned cap 0 to capset 0
assigned cap 0 to capset 1
cap 0: created thread 1
cap 0: running thread 1 (ThreadRunGHC)
cap 0: ((((
cap 0: created thread 2
cap 0: ----
cap 0: thread 1 stopped (blocked on a delay operation)
cap 0: running thread 2 (ThreadRunGHC)
cap 0: thread 2 stopped (finished)
cap 0: running thread 1 (ThreadRunGHC)
cap 0: thread 1 stopped (yielding)
cap 0: running thread 1 (ThreadRunGHC)
cap 0: ))))
cap 0: ((((
cap 0: created thread 3
cap 0: ----
cap 0: thread 1 stopped (yielding)
cap 0: running thread 3 (ThreadRunGHC)
cap 0: thread 3 stopped (finished)
cap 0: running thread 1 (ThreadRunGHC)
```
At this point the program hangs and uses 100% CPU. Only the main thread (1) is running (2 and 3 finished). It is past the `----`, but hasn't reached `threadDelay` yet (no `blocked on a delay operation` in the second iteration). So it must be working on the `atomically` block in between.
This is perfectly reproducible (exact same result on two different machines, tested several times).
Compiling with `-fno-omit-yields` (as suggested in
https://downloads.haskell.org/~ghc/8.6.5/docs/html/users_guide/bugs.html#bugs-in-ghc, which refers to #367) makes no difference. This also seems different to #15975, where the problem appears to be a failure to yield in between transactions. Removing either the `readTVar x` or the `` `orElse` return ()`` bit makes all 1000 iterations go through without hanging.
```
$ ghc --version
The Glorious Glasgow Haskell Compilation System, version 8.6.5
```8.8.2