Portability | non-portable (requires STM) |
---|---|
Stability | experimental |
Maintainer | Peter Robinson <robinson@ecs.tuwien.ac.at> |
Extends Control.Concurrent.STM with IO hooks
- class Monad m => MonadAdvSTM m where
- onCommit :: IO () -> m ()
- unsafeRetryWith :: IO () -> m b
- orElse :: m a -> m a -> m a
- retry :: m a
- check :: Bool -> m ()
- alwaysSucceeds :: m a -> m ()
- always :: m Bool -> m ()
- catchSTM :: Exception e => m a -> (e -> m a) -> m a
- liftAdv :: STM a -> m a
- readTVar :: TVar a -> m a
- writeTVar :: TVar a -> a -> m ()
- readTVarAsync :: TVar a -> m a
- writeTVarAsync :: TVar a -> a -> m ()
- newTVar :: a -> m (TVar a)
- data AdvSTM a
- atomically :: AdvSTM a -> IO a
- unsafeIOToAdvSTM :: IO a -> AdvSTM a
- handleSTM :: (MonadAdvSTM m, Exception e) => (e -> m a) -> m a -> m a
- debugAdvSTM :: String -> Int -> AdvSTM ()
- debugMode :: Bool -> AdvSTM ()
Class MonadAdvSTM
class Monad m => MonadAdvSTM m whereSource
A type class for extended-STM monads. For a concrete instantiation see
AdvSTM
onCommit :: IO () -> m ()Source
Takes an IO action that will be executed iff the transaction commits.
- When a TVar was modified in a transaction and the transaction tries to commit, this update remains invisible to other threads until the corresponding onCommit action is dispatched.
- If the onCommit action throws an exception, the original value of the TVars will be restored.
- Accessing a modified TVar within the onCommit action will cause a Deadlock exception to be thrown.
As a general rule, onCommit
should
only be used for "real" (i.e. without atomic blocks) IO actions and is certainly
not the right place to fiddle with TVars. For example, if you wanted to
write a TVar value to a file on commit, you could write:
tvar <- newTVarIO "bla" atomically $ do x <- readTVar tvar onCommit (writeFile "myfile" x)
Note: If you really need to access the TVar
within an onCommit action
(e.g. to recover from an IO exception), you can use writeTVarAsync
.
unsafeRetryWith :: IO () -> m bSource
Retries the transaction and uses unsafeIOToSTM
to fork off a
thread that runs the given IO action. Since a transaction might be rerun
several times by the runtime system, it is your responsibility to
ensure that the IO-action is idempotent and releases all acquired locks.
orElse :: m a -> m a -> m aSource
See orElse
See retry
See check
alwaysSucceeds :: m a -> m ()Source
See alwaysSucceeds
always :: m Bool -> m ()Source
See always
catchSTM :: Exception e => m a -> (e -> m a) -> m aSource
See catchSTM
Lifts STM actions to MonadAdvSTM
.
readTVar :: TVar a -> m aSource
Reads a value from a TVar. Blocks until the IO onCommit action(s) of
the corresponding transaction are complete.
See onCommit
for a more detailed description of this behaviour.
writeTVar :: TVar a -> a -> m ()Source
Writes a value to a TVar. Blocks until the onCommit IO-action(s) are
complete. See onCommit
for details.
readTVarAsync :: TVar a -> m aSource
Reads a value directly from the TVar. Does not block when the onCommit actions aren't done yet. NOTE: Only use this function when you know what you're doing.
writeTVarAsync :: TVar a -> a -> m ()Source
Writes a value directly to the TVar. Does not block when onCommit actions aren't done yet. This function comes in handy for error recovery of exceptions that occur in onCommit.
newTVar :: a -> m (TVar a)Source
See newTVar
MonadAdvSTM AdvSTM | |
(MonadAdvSTM m, Monoid w) => MonadAdvSTM (WriterT w m) | |
MonadAdvSTM m => MonadAdvSTM (StateT s m) | |
MonadAdvSTM m => MonadAdvSTM (ReaderT r m) |
Monad AdvSTM
Drop-in replacement for the STM monad
atomically :: AdvSTM a -> IO aSource
See atomically
unsafeIOToAdvSTM :: IO a -> AdvSTM aSource
See unsafeIOToSTM
handleSTM :: (MonadAdvSTM m, Exception e) => (e -> m a) -> m a -> m aSource
A version of catchSTM
with the arguments swapped around.