
On 2/20/08, Bulat Ziganshin
STM operations can be repeated if first transaction was unsuccessful. so, you may se here only operations that may be safely repeated - say, reading/writing memory areas, or reading/writing files, or even sending network message as long as its duplication is ok
Actually, you have to be even more careful than that; you may only include not just operations that may be safely repeated, but operations that may be erroneously executed. Consider the following snippet: badNews:: TVar Int -> TVar Int -> IO () badNews xRef yRef = atomically $ do x <- xRef y <- yRef if (x < y) then unsafeIOToSTM launchMissiles else return () (where launchMissiles has serious side effects, but can be called repeatedly without problem; the missiles will already have been launched in the second call). Even if (x < y) is never "atomically" true, launchMissiles could get executed during the evaluation of this STM action if it was run concurrently with another action that wrote new values to x and y in some order, such as the following snippet safe :: TVar Int -> TVar Int -> IO () safe xRef yRef = do atomically $ do writeTVar xRef 15 writeTVar yRef 13 main :: IO () main = do xRef <- newTVar 10 yRef <- newTVar 8 forkIO safe forkIO badNews If "badNews" runs to the point of reading from xRef, then "safe" runs in its entirety and commits successfully, then badNews resumes, launchMissiles will get called and then badNews will fail to commit and be restarted. The second runthrough of badNews will read the values, determine that x >= y, and just return (), but it's too late, the missiles have already been launched. -- ryan