Fix issue with identifying only-read STM transactions as only creating new CTVars.

This commit is contained in:
Michael Walker 2015-07-08 18:18:56 +01:00
parent 426707f382
commit 05e2d2f1e4
3 changed files with 15 additions and 14 deletions

View File

@ -231,12 +231,12 @@ stepThread fixed runconc runstm action idSource tid threads = case action of
let oldctvid = _nextCTVId idSource
(res, newctvid) <- runstm stm oldctvid
case res of
Success touched val
| any (<=oldctvid) touched ->
let (threads', woken) = wake (OnCTVar touched) threads
in return $ Right (knows (map Right touched) tid $ goto (c val) tid threads', idSource { _nextCTVId = newctvid }, STM woken)
Success readen written val
| any (<oldctvid) readen || any (<oldctvid) written ->
let (threads', woken) = wake (OnCTVar written) threads
in return $ Right (knows (map Right written) tid $ goto (c val) tid threads', idSource { _nextCTVId = newctvid }, STM woken)
| otherwise ->
return $ Right (knows (map Right touched) tid $ goto (c val) tid threads, idSource { _nextCTVId = newctvid }, FreshSTM)
return $ Right (knows (map Right written) tid $ goto (c val) tid threads, idSource { _nextCTVId = newctvid }, FreshSTM)
Retry touched ->
let threads' = block (OnCTVar touched) tid threads
in return $ Right (threads', idSource { _nextCTVId = newctvid }, BlockedSTM)

View File

@ -120,7 +120,7 @@ runTransactionST ma ctvid = do
(res, undo, ctvid') <- doTransaction fixedST (unS ma) ctvid
case res of
Success _ _ -> return (res, ctvid')
Success _ _ _ -> return (res, ctvid')
_ -> undo >> return (res, ctvid)
where
@ -135,7 +135,7 @@ runTransactionIO ma ctvid = do
(res, undo, ctvid') <- doTransaction fixedIO (unS ma) ctvid
case res of
Success _ _ -> return (res, ctvid')
Success _ _ _ -> return (res, ctvid')
_ -> undo >> return (res, ctvid)
where

View File

@ -55,8 +55,9 @@ type CTVarId = Int
-- | The result of an STM transaction, along with which 'CTVar's it
-- touched whilst executing.
data Result a =
Success [CTVarId] a
-- ^ The transaction completed successfully, and mutated the returned 'CTVar's.
Success [CTVarId] [CTVarId] a
-- ^ The transaction completed successfully, reading the first list
-- 'CTVar's and writing to the second.
| Retry [CTVarId]
-- ^ The transaction aborted by calling 'retry', and read the
-- returned 'CTVar's. It should be retried when at least one of the
@ -80,7 +81,7 @@ doTransaction fixed ma newctvid = do
res <- readRef (wref fixed) ref
case res of
Just (Right val) -> return (Success (nub written) val, undo, newctvid')
Just (Right val) -> return (Success (nub readen) (nub written) val, undo, newctvid')
Just (Left exc) -> undo >> return (Exception exc, return (), newctvid)
Nothing -> undo >> return (Retry $ nub readen, return (), newctvid)
@ -117,13 +118,13 @@ stepTrans fixed act newctvid = case act of
stepCatch stm h c = do
(res, undo, newctvid') <- doTransaction fixed stm newctvid
case res of
Success written val -> return (c val, undo, newctvid', [], written)
Success readen written val -> return (c val, undo, newctvid', readen, written)
Retry readen -> return (ARetry, nothing, newctvid, readen, [])
Exception exc -> case fromException exc of
Just exc' -> do
(rese, undoe, newctvide') <- doTransaction fixed (h exc') newctvid
case rese of
Success written val -> return (c val, undoe, newctvide', [], written)
Success readen written val -> return (c val, undoe, newctvide', readen, written)
Exception exce -> return (AThrow exce, nothing, newctvid, [], [])
Retry readen -> return (ARetry, nothing, newctvid, readen, [])
Nothing -> return (AThrow exc, nothing, newctvid, [], [])
@ -149,12 +150,12 @@ stepTrans fixed act newctvid = case act of
stepOrElse a b c = do
(resa, undoa, newctvida') <- doTransaction fixed a newctvid
case resa of
Success written val -> return (c val, undoa, newctvida', [], written)
Success readen written val -> return (c val, undoa, newctvida', readen, written)
Exception exc -> return (AThrow exc, nothing, newctvid, [], [])
Retry _ -> do
(resb, undob, newctvidb') <- doTransaction fixed b newctvid
case resb of
Success written val -> return (c val, undob, newctvidb', [], written)
Success readen written val -> return (c val, undob, newctvidb', readen, written)
Exception exc -> return (AThrow exc, nothing, newctvid, [], [])
Retry readen -> return (ARetry, nothing, newctvid, readen, [])