linear-locks-0.1.0.0: src/LinearLocks.hs
{- ORMOLU_DISABLE -}
{- |
@linear-locks@ provides locking primitives that are statically guaranteed to not lead to deadlocks.
An in-depth description and tutorial can be found in the [README](https://github.com/dcastro/linear-locks#readme).
It is meant to be used with @QualifiedDo@ and these imports:
>>> :set -XQualifiedDo -XGHC2024 -XBlockArguments
>>> import LinearLocks
>>> import LinearLocks.Mutex qualified as Mutex
>>> import Prelude.Linear (Ur (..))
>>> import Control.Functor.Linear qualified as Linear
>>> import Control.Monad.IO.Class.Linear qualified as Linear
>>> :{
example :: IO ()
example = do
-- Create mutexes with a chosen level
configMutex <- Mutex.new 0 Config { verbose = True }
dbMutex <- Mutex.new 1 DbConn {}
--
-- Enter a lockscope
lockScope \key -> Linear.do
-- Acquire locks
(configGuard, key) <- acquire key configMutex
(dbGuard, key) <- acquire key dbMutex
--
-- Read/write
(Ur config, configGuard) <- Mutex.read configGuard
configGuard <- Mutex.write configGuard config { verbose = False }
--
-- IO actions
Linear.liftSystemIO do
putStrLn $ "Verbose mode was: " <> show (verbose config)
--
-- Release locks
Mutex.release configGuard
Mutex.release dbGuard
dropKeyAndReturn key ()
:}
-}
{- ORMOLU_ENABLE -}
module LinearLocks
( -- * Lock scope
LockKey,
lockScope,
dropKey,
dropKeyAndReturn,
NestedLocksScopeException (..),
-- * Lock sets
LockSet,
IsLockSet (), -- Note: do not export the typeclass members
newLockSet,
acquireMany,
)
where
import LinearLocks.Internal
import LinearLocks.Internal.LockSet
-- $setup
-- >>> data Config = Config { verbose :: Bool }
-- >>> data DbConn = DbConn