{-# options_haddock prune #-}
module Polysemy.Conc.Interpreter.Lock where
import Control.Concurrent (ThreadId, myThreadId)
import Polysemy.Conc.Effect.Lock (Lock (Lock, LockOr))
import Polysemy.Conc.Effect.Mask (Mask, mask, restore)
import Polysemy.Conc.Effect.Race (Race)
import qualified Polysemy.Conc.Effect.Sync as Sync (putTry, takeBlock, takeTry)
import Polysemy.Conc.Effect.Sync (Sync)
import Polysemy.Conc.Interpreter.Sync (interpretSyncAs)
currentThread ::
Member (Embed IO) r =>
Sem r ThreadId
currentThread :: forall (r :: EffectRow). Member (Embed IO) r => Sem r ThreadId
currentThread =
IO ThreadId -> Sem r ThreadId
forall (m :: * -> *) (r :: EffectRow) a.
Member (Embed m) r =>
m a -> Sem r a
embed IO ThreadId
myThreadId
interpretLockPermissive ::
InterpreterFor Lock r
interpretLockPermissive :: forall (r :: EffectRow). InterpreterFor Lock r
interpretLockPermissive =
(forall (rInitial :: EffectRow) x.
Lock (Sem rInitial) x -> Tactical Lock (Sem rInitial) r x)
-> Sem (Lock : r) a -> Sem r a
forall (e :: Effect) (r :: EffectRow) a.
(forall (rInitial :: EffectRow) x.
e (Sem rInitial) x -> Tactical e (Sem rInitial) r x)
-> Sem (e : r) a -> Sem r a
interpretH \case
Lock Sem rInitial x
ma ->
Sem rInitial x -> Tactical Lock (Sem rInitial) r x
forall (m :: * -> *) a (e :: Effect) (r :: EffectRow).
m a -> Tactical e m r a
runTSimple Sem rInitial x
ma
LockOr Sem rInitial x
_ Sem rInitial x
ma ->
Sem rInitial x -> Tactical Lock (Sem rInitial) r x
forall (m :: * -> *) a (e :: Effect) (r :: EffectRow).
m a -> Tactical e m r a
runTSimple Sem rInitial x
ma
{-# inline interpretLockPermissive #-}
lockOnDifferentThread ::
∀ f m r a .
Members [Sync (), Resource, Race, Mask, Embed IO] r =>
ThreadId ->
m a ->
(Sem (Lock : r) (f a) -> Sem (Lock : r) (f a)) ->
Sem (WithTactics Lock f m r) (f a)
lockOnDifferentThread :: forall (f :: * -> *) (m :: * -> *) (r :: EffectRow) a.
Members '[Sync (), Resource, Race, Mask, Embed IO] r =>
ThreadId
-> m a
-> (Sem (Lock : r) (f a) -> Sem (Lock : r) (f a))
-> Sem (WithTactics Lock f m r) (f a)
lockOnDifferentThread ThreadId
lockThread m a
maI Sem (Lock : r) (f a) -> Sem (Lock : r) (f a)
f = do
ThreadId
thread <- Sem (WithTactics Lock f m r) ThreadId
forall (r :: EffectRow). Member (Embed IO) r => Sem r ThreadId
currentThread
Sem (Lock : r) (f a)
ma <- m a -> Sem (WithTactics Lock f m r) (Sem (Lock : r) (f a))
forall (m :: * -> *) a (e :: Effect) (f :: * -> *)
(r :: EffectRow).
m a -> Sem (WithTactics e f m r) (Sem (e : r) (f a))
runT m a
maI
Sem r (f a) -> Sem (WithTactics Lock f m r) (f a)
forall (e :: Effect) (r :: EffectRow) a. Sem r a -> Sem (e : r) a
raise (Sem r (f a) -> Sem (WithTactics Lock f m r) (f a))
-> Sem r (f a) -> Sem (WithTactics Lock f m r) (f a)
forall a b. (a -> b) -> a -> b
$ ThreadId -> InterpreterFor Lock r
forall (r :: EffectRow).
Members '[Sync (), Resource, Race, Mask, Embed IO] r =>
ThreadId -> InterpreterFor Lock r
interpretLockReentrantEntered ThreadId
thread do
if ThreadId
thread ThreadId -> ThreadId -> Bool
forall a. Eq a => a -> a -> Bool
== ThreadId
lockThread
then Sem (Lock : r) (f a)
ma
else Sem (Lock : r) (f a) -> Sem (Lock : r) (f a)
f Sem (Lock : r) (f a)
ma
{-# inline lockOnDifferentThread #-}
enter ::
∀ f m r a .
Members [Sync (), Resource, Race, Mask, Embed IO] r =>
m a ->
(Sem (Lock : r) (f a) -> Sem (Lock : r) (f a)) ->
Sem (WithTactics Lock f m r) (f a)
enter :: forall (f :: * -> *) (m :: * -> *) (r :: EffectRow) a.
Members '[Sync (), Resource, Race, Mask, Embed IO] r =>
m a
-> (Sem (Lock : r) (f a) -> Sem (Lock : r) (f a))
-> Sem (WithTactics Lock f m r) (f a)
enter m a
maI Sem (Lock : r) (f a) -> Sem (Lock : r) (f a)
f = do
ThreadId
thread <- Sem (WithTactics Lock f m r) ThreadId
forall (r :: EffectRow). Member (Embed IO) r => Sem r ThreadId
currentThread
Sem (Lock : r) (f a)
ma <- m a -> Sem (WithTactics Lock f m r) (Sem (Lock : r) (f a))
forall (m :: * -> *) a (e :: Effect) (f :: * -> *)
(r :: EffectRow).
m a -> Sem (WithTactics e f m r) (Sem (e : r) (f a))
runT m a
maI
Sem r (f a) -> Sem (WithTactics Lock f m r) (f a)
forall (e :: Effect) (r :: EffectRow) a. Sem r a -> Sem (e : r) a
raise (Sem r (f a) -> Sem (WithTactics Lock f m r) (f a))
-> Sem r (f a) -> Sem (WithTactics Lock f m r) (f a)
forall a b. (a -> b) -> a -> b
$ ThreadId -> InterpreterFor Lock r
forall (r :: EffectRow).
Members '[Sync (), Resource, Race, Mask, Embed IO] r =>
ThreadId -> InterpreterFor Lock r
interpretLockReentrantEntered ThreadId
thread do
Sem (Lock : r) (f a) -> Sem (Lock : r) (f a)
f Sem (Lock : r) (f a)
ma
{-# inline enter #-}
lockWait ::
∀ r a .
Members [Sync (), Resource, Mask] r =>
Sem r a ->
Sem r a
lockWait :: forall (r :: EffectRow) a.
Members '[Sync (), Resource, Mask] r =>
Sem r a -> Sem r a
lockWait Sem r a
ma =
Sem (RestoreMask : r) a -> Sem r a
forall (r :: EffectRow).
Member Mask r =>
InterpreterFor RestoreMask r
mask do
forall d (r :: EffectRow). Member (Sync d) r => Sem r d
Sync.takeBlock @()
Sem (RestoreMask : r) a
-> Sem (RestoreMask : r) Bool -> Sem (RestoreMask : r) a
forall (r :: EffectRow) a b.
Member Resource r =>
Sem r a -> Sem r b -> Sem r a
finally (Sem (RestoreMask : r) a -> Sem (RestoreMask : r) a
forall (r :: EffectRow) a.
Member RestoreMask r =>
Sem r a -> Sem r a
restore (Sem r a -> Sem (RestoreMask : r) a
forall (e :: Effect) (r :: EffectRow) a. Sem r a -> Sem (e : r) a
raise Sem r a
ma)) (() -> Sem (RestoreMask : r) Bool
forall d (r :: EffectRow). Member (Sync d) r => d -> Sem r Bool
Sync.putTry ())
{-# inline lockWait #-}
lockAlt ::
∀ r a .
Members [Sync (), Resource, Mask] r =>
Sem r a ->
Sem r a ->
Sem r a
lockAlt :: forall (r :: EffectRow) a.
Members '[Sync (), Resource, Mask] r =>
Sem r a -> Sem r a -> Sem r a
lockAlt Sem r a
alt Sem r a
ma =
Sem (RestoreMask : r) a -> Sem r a
forall (r :: EffectRow).
Member Mask r =>
InterpreterFor RestoreMask r
mask do
Sem (RestoreMask : r) (Maybe ())
forall d (r :: EffectRow). Member (Sync d) r => Sem r (Maybe d)
Sync.takeTry Sem (RestoreMask : r) (Maybe ())
-> (Maybe () -> Sem (RestoreMask : r) a) -> Sem (RestoreMask : r) a
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
Just () ->
Sem (RestoreMask : r) a
-> Sem (RestoreMask : r) Bool -> Sem (RestoreMask : r) a
forall (r :: EffectRow) a b.
Member Resource r =>
Sem r a -> Sem r b -> Sem r a
finally (Sem (RestoreMask : r) a -> Sem (RestoreMask : r) a
forall (r :: EffectRow) a.
Member RestoreMask r =>
Sem r a -> Sem r a
restore (Sem r a -> Sem (RestoreMask : r) a
forall (e :: Effect) (r :: EffectRow) a. Sem r a -> Sem (e : r) a
raise Sem r a
ma)) (() -> Sem (RestoreMask : r) Bool
forall d (r :: EffectRow). Member (Sync d) r => d -> Sem r Bool
Sync.putTry ())
Maybe ()
Nothing ->
Sem (RestoreMask : r) a -> Sem (RestoreMask : r) a
forall (r :: EffectRow) a.
Member RestoreMask r =>
Sem r a -> Sem r a
restore (Sem r a -> Sem (RestoreMask : r) a
forall (e :: Effect) (r :: EffectRow) a. Sem r a -> Sem (e : r) a
raise Sem r a
alt)
{-# inline lockAlt #-}
interpretLockReentrantEntered ::
Members [Sync (), Resource, Race, Mask, Embed IO] r =>
ThreadId ->
InterpreterFor Lock r
interpretLockReentrantEntered :: forall (r :: EffectRow).
Members '[Sync (), Resource, Race, Mask, Embed IO] r =>
ThreadId -> InterpreterFor Lock r
interpretLockReentrantEntered ThreadId
lockThread =
(forall (rInitial :: EffectRow) x.
Lock (Sem rInitial) x -> Tactical Lock (Sem rInitial) r x)
-> Sem (Lock : r) a -> Sem r a
forall (e :: Effect) (r :: EffectRow) a.
(forall (rInitial :: EffectRow) x.
e (Sem rInitial) x -> Tactical e (Sem rInitial) r x)
-> Sem (e : r) a -> Sem r a
interpretH \case
Lock Sem rInitial x
maI ->
ThreadId
-> Sem rInitial x
-> (Sem (Lock : r) (f x) -> Sem (Lock : r) (f x))
-> Sem (WithTactics Lock f (Sem rInitial) r) (f x)
forall (f :: * -> *) (m :: * -> *) (r :: EffectRow) a.
Members '[Sync (), Resource, Race, Mask, Embed IO] r =>
ThreadId
-> m a
-> (Sem (Lock : r) (f a) -> Sem (Lock : r) (f a))
-> Sem (WithTactics Lock f m r) (f a)
lockOnDifferentThread ThreadId
lockThread Sem rInitial x
maI (Sem (Lock : r) (f x) -> Sem (Lock : r) (f x)
forall (r :: EffectRow) a.
Members '[Sync (), Resource, Mask] r =>
Sem r a -> Sem r a
lockWait)
LockOr Sem rInitial x
altI Sem rInitial x
maI -> do
Sem (Lock : r) (f x)
alt <- Sem rInitial x
-> Sem (WithTactics Lock f (Sem rInitial) r) (Sem (Lock : r) (f x))
forall (m :: * -> *) a (e :: Effect) (f :: * -> *)
(r :: EffectRow).
m a -> Sem (WithTactics e f m r) (Sem (e : r) (f a))
runT Sem rInitial x
altI
ThreadId
-> Sem rInitial x
-> (Sem (Lock : r) (f x) -> Sem (Lock : r) (f x))
-> Sem (WithTactics Lock f (Sem rInitial) r) (f x)
forall (f :: * -> *) (m :: * -> *) (r :: EffectRow) a.
Members '[Sync (), Resource, Race, Mask, Embed IO] r =>
ThreadId
-> m a
-> (Sem (Lock : r) (f a) -> Sem (Lock : r) (f a))
-> Sem (WithTactics Lock f m r) (f a)
lockOnDifferentThread ThreadId
lockThread Sem rInitial x
maI (Sem (Lock : r) (f x)
-> Sem (Lock : r) (f x) -> Sem (Lock : r) (f x)
forall (r :: EffectRow) a.
Members '[Sync (), Resource, Mask] r =>
Sem r a -> Sem r a -> Sem r a
lockAlt Sem (Lock : r) (f x)
alt)
{-# inline interpretLockReentrantEntered #-}
interpretLockReentrant ::
Members [Resource, Race, Mask, Embed IO] r =>
InterpreterFor Lock r
interpretLockReentrant :: forall (r :: EffectRow).
Members '[Resource, Race, Mask, Embed IO] r =>
InterpreterFor Lock r
interpretLockReentrant =
() -> InterpreterFor (Sync ()) r
forall d (r :: EffectRow).
Members '[Race, Embed IO] r =>
d -> InterpreterFor (Sync d) r
interpretSyncAs () (Sem (Sync () : r) a -> Sem r a)
-> (Sem (Lock : r) a -> Sem (Sync () : r) a)
-> Sem (Lock : r) a
-> Sem r a
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
(forall (rInitial :: EffectRow) x.
Lock (Sem rInitial) x
-> Tactical Lock (Sem rInitial) (Sync () : r) x)
-> Sem (Lock : r) a -> Sem (Sync () : r) a
forall (e1 :: Effect) (e2 :: Effect) (r :: EffectRow) a.
(forall (rInitial :: EffectRow) x.
e1 (Sem rInitial) x -> Tactical e1 (Sem rInitial) (e2 : r) x)
-> Sem (e1 : r) a -> Sem (e2 : r) a
reinterpretH \case
Lock Sem rInitial x
maI ->
Sem rInitial x
-> (Sem (Lock : Sync () : r) (f x)
-> Sem (Lock : Sync () : r) (f x))
-> Sem (WithTactics Lock f (Sem rInitial) (Sync () : r)) (f x)
forall (f :: * -> *) (m :: * -> *) (r :: EffectRow) a.
Members '[Sync (), Resource, Race, Mask, Embed IO] r =>
m a
-> (Sem (Lock : r) (f a) -> Sem (Lock : r) (f a))
-> Sem (WithTactics Lock f m r) (f a)
enter Sem rInitial x
maI (Sem (Lock : Sync () : r) (f x) -> Sem (Lock : Sync () : r) (f x)
forall (r :: EffectRow) a.
Members '[Sync (), Resource, Mask] r =>
Sem r a -> Sem r a
lockWait)
LockOr Sem rInitial x
altI Sem rInitial x
maI -> do
Sem (Lock : Sync () : r) (f x)
alt <- Sem rInitial x
-> Sem
(WithTactics Lock f (Sem rInitial) (Sync () : r))
(Sem (Lock : Sync () : r) (f x))
forall (m :: * -> *) a (e :: Effect) (f :: * -> *)
(r :: EffectRow).
m a -> Sem (WithTactics e f m r) (Sem (e : r) (f a))
runT Sem rInitial x
altI
Sem rInitial x
-> (Sem (Lock : Sync () : r) (f x)
-> Sem (Lock : Sync () : r) (f x))
-> Sem (WithTactics Lock f (Sem rInitial) (Sync () : r)) (f x)
forall (f :: * -> *) (m :: * -> *) (r :: EffectRow) a.
Members '[Sync (), Resource, Race, Mask, Embed IO] r =>
m a
-> (Sem (Lock : r) (f a) -> Sem (Lock : r) (f a))
-> Sem (WithTactics Lock f m r) (f a)
enter Sem rInitial x
maI (Sem (Lock : Sync () : r) (f x)
-> Sem (Lock : Sync () : r) (f x) -> Sem (Lock : Sync () : r) (f x)
forall (r :: EffectRow) a.
Members '[Sync (), Resource, Mask] r =>
Sem r a -> Sem r a -> Sem r a
lockAlt Sem (Lock : Sync () : r) (f x)
alt)
{-# inline interpretLockReentrant #-}