{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE DerivingVia #-}
{-# LANGUAGE ExistentialQuantification #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE TupleSections #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE UndecidableInstances #-}
module Ouroboros.Consensus.Util.ResourceRegistry (
ResourceRegistry
, RegistryClosedException(..)
, ResourceRegistryThreadException
, withRegistry
, registryThread
, ResourceKey
, allocate
, allocateEither
, release
, unsafeRelease
, releaseAll
, unsafeReleaseAll
, Thread
, threadId
, forkThread
, cancelThread
, withThread
, waitThread
, waitAnyThread
, linkToRegistry
, forkLinkedThread
, WithTempRegistry
, runWithTempRegistry
, TempRegistryException(..)
, allocateTemp
, modifyWithTempRegistry
, unsafeNewRegistry
, closeRegistry
, countResources
) where
import Control.Applicative ((<|>))
import Control.Exception (asyncExceptionFromException)
import Control.Monad
import Control.Monad.Reader
import Control.Monad.State.Strict
import Data.Bifunctor
import Data.Either (partitionEithers)
import Data.Map.Strict (Map)
import qualified Data.Map.Strict as Map
import Data.Maybe (catMaybes, listToMaybe)
import Data.Proxy
import Data.Set (Set)
import qualified Data.Set as Set
import Data.Tuple (swap)
import GHC.Generics (Generic)
import NoThunks.Class (InspectHeapNamed (..), OnlyCheckWhnfNamed (..),
allNoThunks)
import Ouroboros.Consensus.Util (mustBeRight, whenJust)
import Ouroboros.Consensus.Util.CallStack
import Ouroboros.Consensus.Util.IOLike
import Ouroboros.Consensus.Util.Orphans ()
data ResourceRegistry m = ResourceRegistry {
ResourceRegistry m -> Context m
registryContext :: !(Context m)
, ResourceRegistry m -> StrictTVar m (RegistryState m)
registryState :: !(StrictTVar m (RegistryState m))
}
deriving ((forall x. ResourceRegistry m -> Rep (ResourceRegistry m) x)
-> (forall x. Rep (ResourceRegistry m) x -> ResourceRegistry m)
-> Generic (ResourceRegistry m)
forall x. Rep (ResourceRegistry m) x -> ResourceRegistry m
forall x. ResourceRegistry m -> Rep (ResourceRegistry m) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall (m :: * -> *) x.
Rep (ResourceRegistry m) x -> ResourceRegistry m
forall (m :: * -> *) x.
ResourceRegistry m -> Rep (ResourceRegistry m) x
$cto :: forall (m :: * -> *) x.
Rep (ResourceRegistry m) x -> ResourceRegistry m
$cfrom :: forall (m :: * -> *) x.
ResourceRegistry m -> Rep (ResourceRegistry m) x
Generic)
deriving instance IOLike m => NoThunks (ResourceRegistry m)
data RegistryState m = RegistryState {
RegistryState m -> KnownThreads m
registryThreads :: !(KnownThreads m)
, RegistryState m -> Map ResourceId (Resource m)
registryResources :: !(Map ResourceId (Resource m))
, RegistryState m -> ResourceId
registryNextKey :: !ResourceId
, RegistryState m -> RegistryStatus
registryStatus :: !RegistryStatus
}
deriving ((forall x. RegistryState m -> Rep (RegistryState m) x)
-> (forall x. Rep (RegistryState m) x -> RegistryState m)
-> Generic (RegistryState m)
forall x. Rep (RegistryState m) x -> RegistryState m
forall x. RegistryState m -> Rep (RegistryState m) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall (m :: * -> *) x. Rep (RegistryState m) x -> RegistryState m
forall (m :: * -> *) x. RegistryState m -> Rep (RegistryState m) x
$cto :: forall (m :: * -> *) x. Rep (RegistryState m) x -> RegistryState m
$cfrom :: forall (m :: * -> *) x. RegistryState m -> Rep (RegistryState m) x
Generic, Context -> RegistryState m -> IO (Maybe ThunkInfo)
Proxy (RegistryState m) -> String
(Context -> RegistryState m -> IO (Maybe ThunkInfo))
-> (Context -> RegistryState m -> IO (Maybe ThunkInfo))
-> (Proxy (RegistryState m) -> String)
-> NoThunks (RegistryState m)
forall a.
(Context -> a -> IO (Maybe ThunkInfo))
-> (Context -> a -> IO (Maybe ThunkInfo))
-> (Proxy a -> String)
-> NoThunks a
forall (m :: * -> *).
Context -> RegistryState m -> IO (Maybe ThunkInfo)
forall (m :: * -> *). Proxy (RegistryState m) -> String
showTypeOf :: Proxy (RegistryState m) -> String
$cshowTypeOf :: forall (m :: * -> *). Proxy (RegistryState m) -> String
wNoThunks :: Context -> RegistryState m -> IO (Maybe ThunkInfo)
$cwNoThunks :: forall (m :: * -> *).
Context -> RegistryState m -> IO (Maybe ThunkInfo)
noThunks :: Context -> RegistryState m -> IO (Maybe ThunkInfo)
$cnoThunks :: forall (m :: * -> *).
Context -> RegistryState m -> IO (Maybe ThunkInfo)
NoThunks)
newtype KnownThreads m = KnownThreads (Set (ThreadId m))
deriving Context -> KnownThreads m -> IO (Maybe ThunkInfo)
Proxy (KnownThreads m) -> String
(Context -> KnownThreads m -> IO (Maybe ThunkInfo))
-> (Context -> KnownThreads m -> IO (Maybe ThunkInfo))
-> (Proxy (KnownThreads m) -> String)
-> NoThunks (KnownThreads m)
forall a.
(Context -> a -> IO (Maybe ThunkInfo))
-> (Context -> a -> IO (Maybe ThunkInfo))
-> (Proxy a -> String)
-> NoThunks a
forall (m :: * -> *).
Context -> KnownThreads m -> IO (Maybe ThunkInfo)
forall (m :: * -> *). Proxy (KnownThreads m) -> String
showTypeOf :: Proxy (KnownThreads m) -> String
$cshowTypeOf :: forall (m :: * -> *). Proxy (KnownThreads m) -> String
wNoThunks :: Context -> KnownThreads m -> IO (Maybe ThunkInfo)
$cwNoThunks :: forall (m :: * -> *).
Context -> KnownThreads m -> IO (Maybe ThunkInfo)
noThunks :: Context -> KnownThreads m -> IO (Maybe ThunkInfo)
$cnoThunks :: forall (m :: * -> *).
Context -> KnownThreads m -> IO (Maybe ThunkInfo)
NoThunks via InspectHeapNamed "KnownThreads" (KnownThreads m)
data RegistryStatus =
RegistryOpen
| RegistryClosed !PrettyCallStack
deriving ((forall x. RegistryStatus -> Rep RegistryStatus x)
-> (forall x. Rep RegistryStatus x -> RegistryStatus)
-> Generic RegistryStatus
forall x. Rep RegistryStatus x -> RegistryStatus
forall x. RegistryStatus -> Rep RegistryStatus x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep RegistryStatus x -> RegistryStatus
$cfrom :: forall x. RegistryStatus -> Rep RegistryStatus x
Generic, Context -> RegistryStatus -> IO (Maybe ThunkInfo)
Proxy RegistryStatus -> String
(Context -> RegistryStatus -> IO (Maybe ThunkInfo))
-> (Context -> RegistryStatus -> IO (Maybe ThunkInfo))
-> (Proxy RegistryStatus -> String)
-> NoThunks RegistryStatus
forall a.
(Context -> a -> IO (Maybe ThunkInfo))
-> (Context -> a -> IO (Maybe ThunkInfo))
-> (Proxy a -> String)
-> NoThunks a
showTypeOf :: Proxy RegistryStatus -> String
$cshowTypeOf :: Proxy RegistryStatus -> String
wNoThunks :: Context -> RegistryStatus -> IO (Maybe ThunkInfo)
$cwNoThunks :: Context -> RegistryStatus -> IO (Maybe ThunkInfo)
noThunks :: Context -> RegistryStatus -> IO (Maybe ThunkInfo)
$cnoThunks :: Context -> RegistryStatus -> IO (Maybe ThunkInfo)
NoThunks)
data ResourceKey m = ResourceKey !(ResourceRegistry m) !ResourceId
deriving ((forall x. ResourceKey m -> Rep (ResourceKey m) x)
-> (forall x. Rep (ResourceKey m) x -> ResourceKey m)
-> Generic (ResourceKey m)
forall x. Rep (ResourceKey m) x -> ResourceKey m
forall x. ResourceKey m -> Rep (ResourceKey m) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall (m :: * -> *) x. Rep (ResourceKey m) x -> ResourceKey m
forall (m :: * -> *) x. ResourceKey m -> Rep (ResourceKey m) x
$cto :: forall (m :: * -> *) x. Rep (ResourceKey m) x -> ResourceKey m
$cfrom :: forall (m :: * -> *) x. ResourceKey m -> Rep (ResourceKey m) x
Generic, Context -> ResourceKey m -> IO (Maybe ThunkInfo)
Proxy (ResourceKey m) -> String
(Context -> ResourceKey m -> IO (Maybe ThunkInfo))
-> (Context -> ResourceKey m -> IO (Maybe ThunkInfo))
-> (Proxy (ResourceKey m) -> String)
-> NoThunks (ResourceKey m)
forall a.
(Context -> a -> IO (Maybe ThunkInfo))
-> (Context -> a -> IO (Maybe ThunkInfo))
-> (Proxy a -> String)
-> NoThunks a
forall (m :: * -> *).
IOLike m =>
Context -> ResourceKey m -> IO (Maybe ThunkInfo)
forall (m :: * -> *). IOLike m => Proxy (ResourceKey m) -> String
showTypeOf :: Proxy (ResourceKey m) -> String
$cshowTypeOf :: forall (m :: * -> *). IOLike m => Proxy (ResourceKey m) -> String
wNoThunks :: Context -> ResourceKey m -> IO (Maybe ThunkInfo)
$cwNoThunks :: forall (m :: * -> *).
IOLike m =>
Context -> ResourceKey m -> IO (Maybe ThunkInfo)
noThunks :: Context -> ResourceKey m -> IO (Maybe ThunkInfo)
$cnoThunks :: forall (m :: * -> *).
IOLike m =>
Context -> ResourceKey m -> IO (Maybe ThunkInfo)
NoThunks)
resourceKeyId :: ResourceKey m -> ResourceId
resourceKeyId :: ResourceKey m -> ResourceId
resourceKeyId (ResourceKey ResourceRegistry m
_rr ResourceId
rid) = ResourceId
rid
newtype ResourceId = ResourceId Int
deriving stock (Int -> ResourceId -> ShowS
[ResourceId] -> ShowS
ResourceId -> String
(Int -> ResourceId -> ShowS)
-> (ResourceId -> String)
-> ([ResourceId] -> ShowS)
-> Show ResourceId
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [ResourceId] -> ShowS
$cshowList :: [ResourceId] -> ShowS
show :: ResourceId -> String
$cshow :: ResourceId -> String
showsPrec :: Int -> ResourceId -> ShowS
$cshowsPrec :: Int -> ResourceId -> ShowS
Show, ResourceId -> ResourceId -> Bool
(ResourceId -> ResourceId -> Bool)
-> (ResourceId -> ResourceId -> Bool) -> Eq ResourceId
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ResourceId -> ResourceId -> Bool
$c/= :: ResourceId -> ResourceId -> Bool
== :: ResourceId -> ResourceId -> Bool
$c== :: ResourceId -> ResourceId -> Bool
Eq, Eq ResourceId
Eq ResourceId
-> (ResourceId -> ResourceId -> Ordering)
-> (ResourceId -> ResourceId -> Bool)
-> (ResourceId -> ResourceId -> Bool)
-> (ResourceId -> ResourceId -> Bool)
-> (ResourceId -> ResourceId -> Bool)
-> (ResourceId -> ResourceId -> ResourceId)
-> (ResourceId -> ResourceId -> ResourceId)
-> Ord ResourceId
ResourceId -> ResourceId -> Bool
ResourceId -> ResourceId -> Ordering
ResourceId -> ResourceId -> ResourceId
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: ResourceId -> ResourceId -> ResourceId
$cmin :: ResourceId -> ResourceId -> ResourceId
max :: ResourceId -> ResourceId -> ResourceId
$cmax :: ResourceId -> ResourceId -> ResourceId
>= :: ResourceId -> ResourceId -> Bool
$c>= :: ResourceId -> ResourceId -> Bool
> :: ResourceId -> ResourceId -> Bool
$c> :: ResourceId -> ResourceId -> Bool
<= :: ResourceId -> ResourceId -> Bool
$c<= :: ResourceId -> ResourceId -> Bool
< :: ResourceId -> ResourceId -> Bool
$c< :: ResourceId -> ResourceId -> Bool
compare :: ResourceId -> ResourceId -> Ordering
$ccompare :: ResourceId -> ResourceId -> Ordering
$cp1Ord :: Eq ResourceId
Ord)
deriving newtype (Int -> ResourceId
ResourceId -> Int
ResourceId -> [ResourceId]
ResourceId -> ResourceId
ResourceId -> ResourceId -> [ResourceId]
ResourceId -> ResourceId -> ResourceId -> [ResourceId]
(ResourceId -> ResourceId)
-> (ResourceId -> ResourceId)
-> (Int -> ResourceId)
-> (ResourceId -> Int)
-> (ResourceId -> [ResourceId])
-> (ResourceId -> ResourceId -> [ResourceId])
-> (ResourceId -> ResourceId -> [ResourceId])
-> (ResourceId -> ResourceId -> ResourceId -> [ResourceId])
-> Enum ResourceId
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
enumFromThenTo :: ResourceId -> ResourceId -> ResourceId -> [ResourceId]
$cenumFromThenTo :: ResourceId -> ResourceId -> ResourceId -> [ResourceId]
enumFromTo :: ResourceId -> ResourceId -> [ResourceId]
$cenumFromTo :: ResourceId -> ResourceId -> [ResourceId]
enumFromThen :: ResourceId -> ResourceId -> [ResourceId]
$cenumFromThen :: ResourceId -> ResourceId -> [ResourceId]
enumFrom :: ResourceId -> [ResourceId]
$cenumFrom :: ResourceId -> [ResourceId]
fromEnum :: ResourceId -> Int
$cfromEnum :: ResourceId -> Int
toEnum :: Int -> ResourceId
$ctoEnum :: Int -> ResourceId
pred :: ResourceId -> ResourceId
$cpred :: ResourceId -> ResourceId
succ :: ResourceId -> ResourceId
$csucc :: ResourceId -> ResourceId
Enum, Context -> ResourceId -> IO (Maybe ThunkInfo)
Proxy ResourceId -> String
(Context -> ResourceId -> IO (Maybe ThunkInfo))
-> (Context -> ResourceId -> IO (Maybe ThunkInfo))
-> (Proxy ResourceId -> String)
-> NoThunks ResourceId
forall a.
(Context -> a -> IO (Maybe ThunkInfo))
-> (Context -> a -> IO (Maybe ThunkInfo))
-> (Proxy a -> String)
-> NoThunks a
showTypeOf :: Proxy ResourceId -> String
$cshowTypeOf :: Proxy ResourceId -> String
wNoThunks :: Context -> ResourceId -> IO (Maybe ThunkInfo)
$cwNoThunks :: Context -> ResourceId -> IO (Maybe ThunkInfo)
noThunks :: Context -> ResourceId -> IO (Maybe ThunkInfo)
$cnoThunks :: Context -> ResourceId -> IO (Maybe ThunkInfo)
NoThunks)
data Resource m = Resource {
Resource m -> Context m
resourceContext :: !(Context m)
, Resource m -> Release m
resourceRelease :: !(Release m)
}
deriving ((forall x. Resource m -> Rep (Resource m) x)
-> (forall x. Rep (Resource m) x -> Resource m)
-> Generic (Resource m)
forall x. Rep (Resource m) x -> Resource m
forall x. Resource m -> Rep (Resource m) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall (m :: * -> *) x. Rep (Resource m) x -> Resource m
forall (m :: * -> *) x. Resource m -> Rep (Resource m) x
$cto :: forall (m :: * -> *) x. Rep (Resource m) x -> Resource m
$cfrom :: forall (m :: * -> *) x. Resource m -> Rep (Resource m) x
Generic, Context -> Resource m -> IO (Maybe ThunkInfo)
Proxy (Resource m) -> String
(Context -> Resource m -> IO (Maybe ThunkInfo))
-> (Context -> Resource m -> IO (Maybe ThunkInfo))
-> (Proxy (Resource m) -> String)
-> NoThunks (Resource m)
forall a.
(Context -> a -> IO (Maybe ThunkInfo))
-> (Context -> a -> IO (Maybe ThunkInfo))
-> (Proxy a -> String)
-> NoThunks a
forall (m :: * -> *). Context -> Resource m -> IO (Maybe ThunkInfo)
forall (m :: * -> *). Proxy (Resource m) -> String
showTypeOf :: Proxy (Resource m) -> String
$cshowTypeOf :: forall (m :: * -> *). Proxy (Resource m) -> String
wNoThunks :: Context -> Resource m -> IO (Maybe ThunkInfo)
$cwNoThunks :: forall (m :: * -> *). Context -> Resource m -> IO (Maybe ThunkInfo)
noThunks :: Context -> Resource m -> IO (Maybe ThunkInfo)
$cnoThunks :: forall (m :: * -> *). Context -> Resource m -> IO (Maybe ThunkInfo)
NoThunks)
newtype Release m = Release (m Bool)
deriving Context -> Release m -> IO (Maybe ThunkInfo)
Proxy (Release m) -> String
(Context -> Release m -> IO (Maybe ThunkInfo))
-> (Context -> Release m -> IO (Maybe ThunkInfo))
-> (Proxy (Release m) -> String)
-> NoThunks (Release m)
forall a.
(Context -> a -> IO (Maybe ThunkInfo))
-> (Context -> a -> IO (Maybe ThunkInfo))
-> (Proxy a -> String)
-> NoThunks a
forall (m :: * -> *). Context -> Release m -> IO (Maybe ThunkInfo)
forall (m :: * -> *). Proxy (Release m) -> String
showTypeOf :: Proxy (Release m) -> String
$cshowTypeOf :: forall (m :: * -> *). Proxy (Release m) -> String
wNoThunks :: Context -> Release m -> IO (Maybe ThunkInfo)
$cwNoThunks :: forall (m :: * -> *). Context -> Release m -> IO (Maybe ThunkInfo)
noThunks :: Context -> Release m -> IO (Maybe ThunkInfo)
$cnoThunks :: forall (m :: * -> *). Context -> Release m -> IO (Maybe ThunkInfo)
NoThunks via OnlyCheckWhnfNamed "Release" (Release m)
releaseResource :: Resource m -> m Bool
releaseResource :: Resource m -> m Bool
releaseResource Resource{resourceRelease :: forall (m :: * -> *). Resource m -> Release m
resourceRelease = Release m Bool
f} = m Bool
f
instance Show (Release m) where
show :: Release m -> String
show Release m
_ = String
"<<release>>"
modifyKnownThreads :: (Set (ThreadId m) -> Set (ThreadId m))
-> KnownThreads m -> KnownThreads m
modifyKnownThreads :: (Set (ThreadId m) -> Set (ThreadId m))
-> KnownThreads m -> KnownThreads m
modifyKnownThreads Set (ThreadId m) -> Set (ThreadId m)
f (KnownThreads Set (ThreadId m)
ts) = Set (ThreadId m) -> KnownThreads m
forall (m :: * -> *). Set (ThreadId m) -> KnownThreads m
KnownThreads (Set (ThreadId m) -> Set (ThreadId m)
f Set (ThreadId m)
ts)
unlessClosed :: State (RegistryState m) a
-> State (RegistryState m) (Either PrettyCallStack a)
unlessClosed :: State (RegistryState m) a
-> State (RegistryState m) (Either PrettyCallStack a)
unlessClosed State (RegistryState m) a
f = do
RegistryStatus
status <- (RegistryState m -> RegistryStatus)
-> StateT (RegistryState m) Identity RegistryStatus
forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
gets RegistryState m -> RegistryStatus
forall (m :: * -> *). RegistryState m -> RegistryStatus
registryStatus
case RegistryStatus
status of
RegistryClosed PrettyCallStack
closed -> Either PrettyCallStack a
-> State (RegistryState m) (Either PrettyCallStack a)
forall (m :: * -> *) a. Monad m => a -> m a
return (Either PrettyCallStack a
-> State (RegistryState m) (Either PrettyCallStack a))
-> Either PrettyCallStack a
-> State (RegistryState m) (Either PrettyCallStack a)
forall a b. (a -> b) -> a -> b
$ PrettyCallStack -> Either PrettyCallStack a
forall a b. a -> Either a b
Left PrettyCallStack
closed
RegistryStatus
RegistryOpen -> a -> Either PrettyCallStack a
forall a b. b -> Either a b
Right (a -> Either PrettyCallStack a)
-> State (RegistryState m) a
-> State (RegistryState m) (Either PrettyCallStack a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> State (RegistryState m) a
f
allocKey :: State (RegistryState m) (Either PrettyCallStack ResourceId)
allocKey :: State (RegistryState m) (Either PrettyCallStack ResourceId)
allocKey = State (RegistryState m) ResourceId
-> State (RegistryState m) (Either PrettyCallStack ResourceId)
forall (m :: * -> *) a.
State (RegistryState m) a
-> State (RegistryState m) (Either PrettyCallStack a)
unlessClosed (State (RegistryState m) ResourceId
-> State (RegistryState m) (Either PrettyCallStack ResourceId))
-> State (RegistryState m) ResourceId
-> State (RegistryState m) (Either PrettyCallStack ResourceId)
forall a b. (a -> b) -> a -> b
$ do
ResourceId
nextKey <- (RegistryState m -> ResourceId)
-> State (RegistryState m) ResourceId
forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
gets RegistryState m -> ResourceId
forall (m :: * -> *). RegistryState m -> ResourceId
registryNextKey
(RegistryState m -> RegistryState m)
-> StateT (RegistryState m) Identity ()
forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modify ((RegistryState m -> RegistryState m)
-> StateT (RegistryState m) Identity ())
-> (RegistryState m -> RegistryState m)
-> StateT (RegistryState m) Identity ()
forall a b. (a -> b) -> a -> b
$ \RegistryState m
st -> RegistryState m
st {registryNextKey :: ResourceId
registryNextKey = ResourceId -> ResourceId
forall a. Enum a => a -> a
succ ResourceId
nextKey}
ResourceId -> State (RegistryState m) ResourceId
forall (m :: * -> *) a. Monad m => a -> m a
return ResourceId
nextKey
insertResource :: ResourceId
-> Resource m
-> State (RegistryState m) (Either PrettyCallStack ())
insertResource :: ResourceId
-> Resource m
-> State (RegistryState m) (Either PrettyCallStack ())
insertResource ResourceId
key Resource m
r = State (RegistryState m) ()
-> State (RegistryState m) (Either PrettyCallStack ())
forall (m :: * -> *) a.
State (RegistryState m) a
-> State (RegistryState m) (Either PrettyCallStack a)
unlessClosed (State (RegistryState m) ()
-> State (RegistryState m) (Either PrettyCallStack ()))
-> State (RegistryState m) ()
-> State (RegistryState m) (Either PrettyCallStack ())
forall a b. (a -> b) -> a -> b
$ do
(RegistryState m -> RegistryState m) -> State (RegistryState m) ()
forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modify ((RegistryState m -> RegistryState m)
-> State (RegistryState m) ())
-> (RegistryState m -> RegistryState m)
-> State (RegistryState m) ()
forall a b. (a -> b) -> a -> b
$ \RegistryState m
st -> RegistryState m
st {
registryResources :: Map ResourceId (Resource m)
registryResources = ResourceId
-> Resource m
-> Map ResourceId (Resource m)
-> Map ResourceId (Resource m)
forall k a. Ord k => k -> a -> Map k a -> Map k a
Map.insert ResourceId
key Resource m
r (RegistryState m -> Map ResourceId (Resource m)
forall (m :: * -> *).
RegistryState m -> Map ResourceId (Resource m)
registryResources RegistryState m
st)
}
removeResource :: ResourceId -> State (RegistryState m) (Maybe (Resource m))
removeResource :: ResourceId -> State (RegistryState m) (Maybe (Resource m))
removeResource ResourceId
key = (RegistryState m -> (Maybe (Resource m), RegistryState m))
-> State (RegistryState m) (Maybe (Resource m))
forall s (m :: * -> *) a. MonadState s m => (s -> (a, s)) -> m a
state ((RegistryState m -> (Maybe (Resource m), RegistryState m))
-> State (RegistryState m) (Maybe (Resource m)))
-> (RegistryState m -> (Maybe (Resource m), RegistryState m))
-> State (RegistryState m) (Maybe (Resource m))
forall a b. (a -> b) -> a -> b
$ \RegistryState m
st ->
(Map ResourceId (Resource m) -> RegistryState m)
-> (Maybe (Resource m), Map ResourceId (Resource m))
-> (Maybe (Resource m), RegistryState m)
forall (p :: * -> * -> *) b c a.
Bifunctor p =>
(b -> c) -> p a b -> p a c
second (\Map ResourceId (Resource m)
x -> RegistryState m
st {registryResources :: Map ResourceId (Resource m)
registryResources = Map ResourceId (Resource m)
x})
((Maybe (Resource m), Map ResourceId (Resource m))
-> (Maybe (Resource m), RegistryState m))
-> (Map ResourceId (Resource m)
-> (Maybe (Resource m), Map ResourceId (Resource m)))
-> Map ResourceId (Resource m)
-> (Maybe (Resource m), RegistryState m)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ResourceId -> Resource m -> Maybe (Resource m))
-> ResourceId
-> Map ResourceId (Resource m)
-> (Maybe (Resource m), Map ResourceId (Resource m))
forall k a.
Ord k =>
(k -> a -> Maybe a) -> k -> Map k a -> (Maybe a, Map k a)
Map.updateLookupWithKey (\ResourceId
_ Resource m
_ -> Maybe (Resource m)
forall a. Maybe a
Nothing) ResourceId
key
(Map ResourceId (Resource m)
-> (Maybe (Resource m), RegistryState m))
-> Map ResourceId (Resource m)
-> (Maybe (Resource m), RegistryState m)
forall a b. (a -> b) -> a -> b
$ RegistryState m -> Map ResourceId (Resource m)
forall (m :: * -> *).
RegistryState m -> Map ResourceId (Resource m)
registryResources RegistryState m
st
insertThread :: IOLike m => ThreadId m -> State (RegistryState m) ()
insertThread :: ThreadId m -> State (RegistryState m) ()
insertThread ThreadId m
tid =
(RegistryState m -> RegistryState m) -> State (RegistryState m) ()
forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modify ((RegistryState m -> RegistryState m)
-> State (RegistryState m) ())
-> (RegistryState m -> RegistryState m)
-> State (RegistryState m) ()
forall a b. (a -> b) -> a -> b
$ \RegistryState m
st -> RegistryState m
st {
registryThreads :: KnownThreads m
registryThreads = (Set (ThreadId m) -> Set (ThreadId m))
-> KnownThreads m -> KnownThreads m
forall (m :: * -> *).
(Set (ThreadId m) -> Set (ThreadId m))
-> KnownThreads m -> KnownThreads m
modifyKnownThreads (ThreadId m -> Set (ThreadId m) -> Set (ThreadId m)
forall a. Ord a => a -> Set a -> Set a
Set.insert ThreadId m
tid) (KnownThreads m -> KnownThreads m)
-> KnownThreads m -> KnownThreads m
forall a b. (a -> b) -> a -> b
$
RegistryState m -> KnownThreads m
forall (m :: * -> *). RegistryState m -> KnownThreads m
registryThreads RegistryState m
st
}
removeThread :: IOLike m => ThreadId m -> State (RegistryState m) ()
removeThread :: ThreadId m -> State (RegistryState m) ()
removeThread ThreadId m
tid =
(RegistryState m -> RegistryState m) -> State (RegistryState m) ()
forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modify ((RegistryState m -> RegistryState m)
-> State (RegistryState m) ())
-> (RegistryState m -> RegistryState m)
-> State (RegistryState m) ()
forall a b. (a -> b) -> a -> b
$ \RegistryState m
st -> RegistryState m
st {
registryThreads :: KnownThreads m
registryThreads = (Set (ThreadId m) -> Set (ThreadId m))
-> KnownThreads m -> KnownThreads m
forall (m :: * -> *).
(Set (ThreadId m) -> Set (ThreadId m))
-> KnownThreads m -> KnownThreads m
modifyKnownThreads (ThreadId m -> Set (ThreadId m) -> Set (ThreadId m)
forall a. Ord a => a -> Set a -> Set a
Set.delete ThreadId m
tid) (KnownThreads m -> KnownThreads m)
-> KnownThreads m -> KnownThreads m
forall a b. (a -> b) -> a -> b
$
RegistryState m -> KnownThreads m
forall (m :: * -> *). RegistryState m -> KnownThreads m
registryThreads RegistryState m
st
}
close :: PrettyCallStack
-> State (RegistryState m) (Either PrettyCallStack (Set ResourceId))
close :: PrettyCallStack
-> State
(RegistryState m) (Either PrettyCallStack (Set ResourceId))
close PrettyCallStack
closeCallStack = State (RegistryState m) (Set ResourceId)
-> State
(RegistryState m) (Either PrettyCallStack (Set ResourceId))
forall (m :: * -> *) a.
State (RegistryState m) a
-> State (RegistryState m) (Either PrettyCallStack a)
unlessClosed (State (RegistryState m) (Set ResourceId)
-> State
(RegistryState m) (Either PrettyCallStack (Set ResourceId)))
-> State (RegistryState m) (Set ResourceId)
-> State
(RegistryState m) (Either PrettyCallStack (Set ResourceId))
forall a b. (a -> b) -> a -> b
$ do
(RegistryState m -> RegistryState m)
-> StateT (RegistryState m) Identity ()
forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modify ((RegistryState m -> RegistryState m)
-> StateT (RegistryState m) Identity ())
-> (RegistryState m -> RegistryState m)
-> StateT (RegistryState m) Identity ()
forall a b. (a -> b) -> a -> b
$ \RegistryState m
st -> RegistryState m
st {registryStatus :: RegistryStatus
registryStatus = PrettyCallStack -> RegistryStatus
RegistryClosed PrettyCallStack
closeCallStack}
(RegistryState m -> Set ResourceId)
-> State (RegistryState m) (Set ResourceId)
forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
gets ((RegistryState m -> Set ResourceId)
-> State (RegistryState m) (Set ResourceId))
-> (RegistryState m -> Set ResourceId)
-> State (RegistryState m) (Set ResourceId)
forall a b. (a -> b) -> a -> b
$ Map ResourceId (Resource m) -> Set ResourceId
forall k a. Map k a -> Set k
Map.keysSet (Map ResourceId (Resource m) -> Set ResourceId)
-> (RegistryState m -> Map ResourceId (Resource m))
-> RegistryState m
-> Set ResourceId
forall b c a. (b -> c) -> (a -> b) -> a -> c
. RegistryState m -> Map ResourceId (Resource m)
forall (m :: * -> *).
RegistryState m -> Map ResourceId (Resource m)
registryResources
updateState :: forall m a. IOLike m
=> ResourceRegistry m
-> State (RegistryState m) a
-> m a
updateState :: ResourceRegistry m -> State (RegistryState m) a -> m a
updateState ResourceRegistry m
rr State (RegistryState m) a
f =
STM m a -> m a
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
STM m a -> m a
atomically (STM m a -> m a) -> STM m a -> m a
forall a b. (a -> b) -> a -> b
$ StrictTVar m (RegistryState m)
-> (RegistryState m -> (RegistryState m, a)) -> STM m a
forall (m :: * -> *) a b.
MonadSTM m =>
StrictTVar m a -> (a -> (a, b)) -> STM m b
stateTVar (ResourceRegistry m -> StrictTVar m (RegistryState m)
forall (m :: * -> *).
ResourceRegistry m -> StrictTVar m (RegistryState m)
registryState ResourceRegistry m
rr) ((a, RegistryState m) -> (RegistryState m, a)
forall a b. (a, b) -> (b, a)
swap ((a, RegistryState m) -> (RegistryState m, a))
-> (RegistryState m -> (a, RegistryState m))
-> RegistryState m
-> (RegistryState m, a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. State (RegistryState m) a
-> RegistryState m -> (a, RegistryState m)
forall s a. State s a -> s -> (a, s)
runState State (RegistryState m) a
f)
data RegistryClosedException =
forall m. IOLike m => RegistryClosedException {
()
registryClosedRegistryContext :: !(Context m)
, RegistryClosedException -> PrettyCallStack
registryClosedCloseCallStack :: !PrettyCallStack
, ()
registryClosedAllocContext :: !(Context m)
}
deriving instance Show RegistryClosedException
instance Exception RegistryClosedException
unsafeNewRegistry :: (IOLike m, HasCallStack) => m (ResourceRegistry m)
unsafeNewRegistry :: m (ResourceRegistry m)
unsafeNewRegistry = do
Context m
context <- m (Context m)
forall (m :: * -> *). (IOLike m, HasCallStack) => m (Context m)
captureContext
StrictTVar m (RegistryState m)
stateVar <- RegistryState m -> m (StrictTVar m (RegistryState m))
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack, NoThunks a) =>
a -> m (StrictTVar m a)
newTVarIO RegistryState m
forall (m :: * -> *). RegistryState m
initState
ResourceRegistry m -> m (ResourceRegistry m)
forall (m :: * -> *) a. Monad m => a -> m a
return ResourceRegistry :: forall (m :: * -> *).
Context m -> StrictTVar m (RegistryState m) -> ResourceRegistry m
ResourceRegistry {
registryContext :: Context m
registryContext = Context m
context
, registryState :: StrictTVar m (RegistryState m)
registryState = StrictTVar m (RegistryState m)
stateVar
}
where
initState :: RegistryState m
initState :: RegistryState m
initState = RegistryState :: forall (m :: * -> *).
KnownThreads m
-> Map ResourceId (Resource m)
-> ResourceId
-> RegistryStatus
-> RegistryState m
RegistryState {
registryThreads :: KnownThreads m
registryThreads = Set (ThreadId m) -> KnownThreads m
forall (m :: * -> *). Set (ThreadId m) -> KnownThreads m
KnownThreads Set (ThreadId m)
forall a. Set a
Set.empty
, registryResources :: Map ResourceId (Resource m)
registryResources = Map ResourceId (Resource m)
forall k a. Map k a
Map.empty
, registryNextKey :: ResourceId
registryNextKey = Int -> ResourceId
ResourceId Int
1
, registryStatus :: RegistryStatus
registryStatus = RegistryStatus
RegistryOpen
}
closeRegistry :: (IOLike m, HasCallStack) => ResourceRegistry m -> m ()
closeRegistry :: ResourceRegistry m -> m ()
closeRegistry ResourceRegistry m
rr = m () -> m ()
forall (m :: * -> *) a. MonadMask m => m a -> m a
mask_ (m () -> m ()) -> m () -> m ()
forall a b. (a -> b) -> a -> b
$ do
Context m
context <- m (Context m)
forall (m :: * -> *). (IOLike m, HasCallStack) => m (Context m)
captureContext
Bool -> m () -> m ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (Context m -> ThreadId m
forall (m :: * -> *). Context m -> ThreadId m
contextThreadId Context m
context ThreadId m -> ThreadId m -> Bool
forall a. Eq a => a -> a -> Bool
== Context m -> ThreadId m
forall (m :: * -> *). Context m -> ThreadId m
contextThreadId (ResourceRegistry m -> Context m
forall (m :: * -> *). ResourceRegistry m -> Context m
registryContext ResourceRegistry m
rr)) (m () -> m ()) -> m () -> m ()
forall a b. (a -> b) -> a -> b
$
ResourceRegistryThreadException -> m ()
forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwIO (ResourceRegistryThreadException -> m ())
-> ResourceRegistryThreadException -> m ()
forall a b. (a -> b) -> a -> b
$ ResourceRegistryClosedFromWrongThread :: forall (m :: * -> *).
IOLike m =>
Context m -> Context m -> ResourceRegistryThreadException
ResourceRegistryClosedFromWrongThread {
resourceRegistryCreatedIn :: Context m
resourceRegistryCreatedIn = ResourceRegistry m -> Context m
forall (m :: * -> *). ResourceRegistry m -> Context m
registryContext ResourceRegistry m
rr
, resourceRegistryUsedIn :: Context m
resourceRegistryUsedIn = Context m
context
}
Either PrettyCallStack (Set ResourceId)
alreadyClosed <- ResourceRegistry m
-> State
(RegistryState m) (Either PrettyCallStack (Set ResourceId))
-> m (Either PrettyCallStack (Set ResourceId))
forall (m :: * -> *) a.
IOLike m =>
ResourceRegistry m -> State (RegistryState m) a -> m a
updateState ResourceRegistry m
rr (State (RegistryState m) (Either PrettyCallStack (Set ResourceId))
-> m (Either PrettyCallStack (Set ResourceId)))
-> State
(RegistryState m) (Either PrettyCallStack (Set ResourceId))
-> m (Either PrettyCallStack (Set ResourceId))
forall a b. (a -> b) -> a -> b
$ PrettyCallStack
-> State
(RegistryState m) (Either PrettyCallStack (Set ResourceId))
forall (m :: * -> *).
PrettyCallStack
-> State
(RegistryState m) (Either PrettyCallStack (Set ResourceId))
close (Context m -> PrettyCallStack
forall (m :: * -> *). Context m -> PrettyCallStack
contextCallStack Context m
context)
case Either PrettyCallStack (Set ResourceId)
alreadyClosed of
Left PrettyCallStack
_ ->
() -> m ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
Right Set ResourceId
keys -> do
m [Context m] -> m ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (m [Context m] -> m ()) -> m [Context m] -> m ()
forall a b. (a -> b) -> a -> b
$ ResourceRegistry m
-> Set ResourceId
-> (ResourceKey m -> m (Maybe (Context m)))
-> m [Context m]
forall (m :: * -> *).
IOLike m =>
ResourceRegistry m
-> Set ResourceId
-> (ResourceKey m -> m (Maybe (Context m)))
-> m [Context m]
releaseResources ResourceRegistry m
rr Set ResourceId
keys ResourceKey m -> m (Maybe (Context m))
forall (m :: * -> *).
(IOLike m, HasCallStack) =>
ResourceKey m -> m (Maybe (Context m))
release
releaseResources :: IOLike m
=> ResourceRegistry m
-> Set ResourceId
-> (ResourceKey m -> m (Maybe (Context m)))
-> m [Context m]
releaseResources :: ResourceRegistry m
-> Set ResourceId
-> (ResourceKey m -> m (Maybe (Context m)))
-> m [Context m]
releaseResources ResourceRegistry m
rr Set ResourceId
keys ResourceKey m -> m (Maybe (Context m))
releaser = do
([SomeException]
exs, [Maybe (Context m)]
mbContexts) <- ([Either SomeException (Maybe (Context m))]
-> ([SomeException], [Maybe (Context m)]))
-> m [Either SomeException (Maybe (Context m))]
-> m ([SomeException], [Maybe (Context m)])
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap [Either SomeException (Maybe (Context m))]
-> ([SomeException], [Maybe (Context m)])
forall a b. [Either a b] -> ([a], [b])
partitionEithers (m [Either SomeException (Maybe (Context m))]
-> m ([SomeException], [Maybe (Context m)]))
-> m [Either SomeException (Maybe (Context m))]
-> m ([SomeException], [Maybe (Context m)])
forall a b. (a -> b) -> a -> b
$
[ResourceId]
-> (ResourceId -> m (Either SomeException (Maybe (Context m))))
-> m [Either SomeException (Maybe (Context m))]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
t a -> (a -> m b) -> m (t b)
forM (Set ResourceId -> [ResourceId]
newToOld Set ResourceId
keys) ((ResourceId -> m (Either SomeException (Maybe (Context m))))
-> m [Either SomeException (Maybe (Context m))])
-> (ResourceId -> m (Either SomeException (Maybe (Context m))))
-> m [Either SomeException (Maybe (Context m))]
forall a b. (a -> b) -> a -> b
$ m (Maybe (Context m))
-> m (Either SomeException (Maybe (Context m)))
forall (m :: * -> *) e a.
(MonadCatch m, Exception e) =>
m a -> m (Either e a)
try (m (Maybe (Context m))
-> m (Either SomeException (Maybe (Context m))))
-> (ResourceId -> m (Maybe (Context m)))
-> ResourceId
-> m (Either SomeException (Maybe (Context m)))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ResourceKey m -> m (Maybe (Context m))
releaser (ResourceKey m -> m (Maybe (Context m)))
-> (ResourceId -> ResourceKey m)
-> ResourceId
-> m (Maybe (Context m))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ResourceRegistry m -> ResourceId -> ResourceKey m
forall (m :: * -> *).
ResourceRegistry m -> ResourceId -> ResourceKey m
ResourceKey ResourceRegistry m
rr
case [SomeException] -> Maybe SomeException
prioritize [SomeException]
exs of
Maybe SomeException
Nothing -> [Context m] -> m [Context m]
forall (m :: * -> *) a. Monad m => a -> m a
return ([Maybe (Context m)] -> [Context m]
forall a. [Maybe a] -> [a]
catMaybes [Maybe (Context m)]
mbContexts)
Just SomeException
e -> SomeException -> m [Context m]
forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwIO SomeException
e
where
newToOld :: Set ResourceId -> [ResourceId]
newToOld :: Set ResourceId -> [ResourceId]
newToOld = Set ResourceId -> [ResourceId]
forall a. Set a -> [a]
Set.toDescList
prioritize :: [SomeException] -> Maybe SomeException
prioritize :: [SomeException] -> Maybe SomeException
prioritize =
(\([SomeException]
asyncEx, [SomeException]
otherEx) -> [SomeException] -> Maybe SomeException
forall a. [a] -> Maybe a
listToMaybe [SomeException]
asyncEx Maybe SomeException -> Maybe SomeException -> Maybe SomeException
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> [SomeException] -> Maybe SomeException
forall a. [a] -> Maybe a
listToMaybe [SomeException]
otherEx)
(([SomeException], [SomeException]) -> Maybe SomeException)
-> ([SomeException] -> ([SomeException], [SomeException]))
-> [SomeException]
-> Maybe SomeException
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([Maybe SomeException] -> [SomeException])
-> ([Maybe SomeException], [SomeException])
-> ([SomeException], [SomeException])
forall (p :: * -> * -> *) a b c.
Bifunctor p =>
(a -> b) -> p a c -> p b c
first [Maybe SomeException] -> [SomeException]
forall a. [Maybe a] -> [a]
catMaybes
(([Maybe SomeException], [SomeException])
-> ([SomeException], [SomeException]))
-> ([SomeException] -> ([Maybe SomeException], [SomeException]))
-> [SomeException]
-> ([SomeException], [SomeException])
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [(Maybe SomeException, SomeException)]
-> ([Maybe SomeException], [SomeException])
forall a b. [(a, b)] -> ([a], [b])
unzip
([(Maybe SomeException, SomeException)]
-> ([Maybe SomeException], [SomeException]))
-> ([SomeException] -> [(Maybe SomeException, SomeException)])
-> [SomeException]
-> ([Maybe SomeException], [SomeException])
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (SomeException -> (Maybe SomeException, SomeException))
-> [SomeException] -> [(Maybe SomeException, SomeException)]
forall a b. (a -> b) -> [a] -> [b]
map (\SomeException
e -> (SomeException -> Maybe SomeException
forall e. Exception e => SomeException -> Maybe e
asyncExceptionFromException SomeException
e, SomeException
e))
withRegistry :: (IOLike m, HasCallStack) => (ResourceRegistry m -> m a) -> m a
withRegistry :: (ResourceRegistry m -> m a) -> m a
withRegistry = m (ResourceRegistry m)
-> (ResourceRegistry m -> m ())
-> (ResourceRegistry m -> m a)
-> m a
forall (m :: * -> *) a b c.
MonadThrow m =>
m a -> (a -> m b) -> (a -> m c) -> m c
bracket m (ResourceRegistry m)
forall (m :: * -> *).
(IOLike m, HasCallStack) =>
m (ResourceRegistry m)
unsafeNewRegistry ResourceRegistry m -> m ()
forall (m :: * -> *).
(IOLike m, HasCallStack) =>
ResourceRegistry m -> m ()
closeRegistry
runWithTempRegistry
:: (IOLike m, HasCallStack)
=> WithTempRegistry st m (a, st)
-> m a
runWithTempRegistry :: WithTempRegistry st m (a, st) -> m a
runWithTempRegistry WithTempRegistry st m (a, st)
m = (ResourceRegistry m -> m a) -> m a
forall (m :: * -> *) a.
(IOLike m, HasCallStack) =>
(ResourceRegistry m -> m a) -> m a
withRegistry ((ResourceRegistry m -> m a) -> m a)
-> (ResourceRegistry m -> m a) -> m a
forall a b. (a -> b) -> a -> b
$ \ResourceRegistry m
rr -> do
StrictTVar m (TransferredTo st)
varTransferredTo <- TransferredTo st -> m (StrictTVar m (TransferredTo st))
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack, NoThunks a) =>
a -> m (StrictTVar m a)
newTVarIO TransferredTo st
forall a. Monoid a => a
mempty
let tempRegistry :: TempRegistry st m
tempRegistry = TempRegistry :: forall st (m :: * -> *).
ResourceRegistry m
-> StrictTVar m (TransferredTo st) -> TempRegistry st m
TempRegistry {
tempResourceRegistry :: ResourceRegistry m
tempResourceRegistry = ResourceRegistry m
rr
, tempTransferredTo :: StrictTVar m (TransferredTo st)
tempTransferredTo = StrictTVar m (TransferredTo st)
varTransferredTo
}
(a
a, st
st) <- ReaderT (TempRegistry st m) m (a, st)
-> TempRegistry st m -> m (a, st)
forall r (m :: * -> *) a. ReaderT r m a -> r -> m a
runReaderT (WithTempRegistry st m (a, st)
-> ReaderT (TempRegistry st m) m (a, st)
forall st (m :: * -> *) a.
WithTempRegistry st m a -> ReaderT (TempRegistry st m) m a
unWithTempRegistry WithTempRegistry st m (a, st)
m) TempRegistry st m
tempRegistry
TransferredTo st
transferredTo <- STM m (TransferredTo st) -> m (TransferredTo st)
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
STM m a -> m a
atomically (STM m (TransferredTo st) -> m (TransferredTo st))
-> STM m (TransferredTo st) -> m (TransferredTo st)
forall a b. (a -> b) -> a -> b
$ StrictTVar m (TransferredTo st) -> STM m (TransferredTo st)
forall (m :: * -> *) a. MonadSTM m => StrictTVar m a -> STM m a
readTVar StrictTVar m (TransferredTo st)
varTransferredTo
ResourceRegistry m -> TransferredTo st -> st -> m ()
forall (m :: * -> *) st.
IOLike m =>
ResourceRegistry m -> TransferredTo st -> st -> m ()
untrackTransferredTo ResourceRegistry m
rr TransferredTo st
transferredTo st
st
Context m
context <- m (Context m)
forall (m :: * -> *). (IOLike m, HasCallStack) => m (Context m)
captureContext
[Context m]
remainingResources <- ResourceRegistry m
-> Context m
-> (ResourceKey m -> m (Maybe (Context m)))
-> m [Context m]
forall (m :: * -> *).
IOLike m =>
ResourceRegistry m
-> Context m
-> (ResourceKey m -> m (Maybe (Context m)))
-> m [Context m]
releaseAllHelper ResourceRegistry m
rr Context m
context ResourceKey m -> m (Maybe (Context m))
forall (m :: * -> *).
(IOLike m, HasCallStack) =>
ResourceKey m -> m (Maybe (Context m))
release
Maybe (Context m) -> (Context m -> m ()) -> m ()
forall (f :: * -> *) a.
Applicative f =>
Maybe a -> (a -> f ()) -> f ()
whenJust ([Context m] -> Maybe (Context m)
forall a. [a] -> Maybe a
listToMaybe [Context m]
remainingResources) ((Context m -> m ()) -> m ()) -> (Context m -> m ()) -> m ()
forall a b. (a -> b) -> a -> b
$ \Context m
remainingResource ->
TempRegistryException -> m ()
forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwIO (TempRegistryException -> m ()) -> TempRegistryException -> m ()
forall a b. (a -> b) -> a -> b
$ TempRegistryRemainingResource :: forall (m :: * -> *).
IOLike m =>
Context m -> Context m -> TempRegistryException
TempRegistryRemainingResource {
tempRegistryContext :: Context m
tempRegistryContext = ResourceRegistry m -> Context m
forall (m :: * -> *). ResourceRegistry m -> Context m
registryContext ResourceRegistry m
rr
, tempRegistryResource :: Context m
tempRegistryResource = Context m
remainingResource
}
a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return a
a
data TempRegistryException =
forall m. IOLike m => TempRegistryRemainingResource {
()
tempRegistryContext :: !(Context m)
, ()
tempRegistryResource :: !(Context m)
}
deriving instance Show TempRegistryException
instance Exception TempRegistryException
newtype TransferredTo st = TransferredTo {
TransferredTo st -> st -> Set ResourceId
runTransferredTo :: st -> Set ResourceId
}
deriving newtype (b -> TransferredTo st -> TransferredTo st
NonEmpty (TransferredTo st) -> TransferredTo st
TransferredTo st -> TransferredTo st -> TransferredTo st
(TransferredTo st -> TransferredTo st -> TransferredTo st)
-> (NonEmpty (TransferredTo st) -> TransferredTo st)
-> (forall b.
Integral b =>
b -> TransferredTo st -> TransferredTo st)
-> Semigroup (TransferredTo st)
forall b. Integral b => b -> TransferredTo st -> TransferredTo st
forall st. NonEmpty (TransferredTo st) -> TransferredTo st
forall st. TransferredTo st -> TransferredTo st -> TransferredTo st
forall a.
(a -> a -> a)
-> (NonEmpty a -> a)
-> (forall b. Integral b => b -> a -> a)
-> Semigroup a
forall st b.
Integral b =>
b -> TransferredTo st -> TransferredTo st
stimes :: b -> TransferredTo st -> TransferredTo st
$cstimes :: forall st b.
Integral b =>
b -> TransferredTo st -> TransferredTo st
sconcat :: NonEmpty (TransferredTo st) -> TransferredTo st
$csconcat :: forall st. NonEmpty (TransferredTo st) -> TransferredTo st
<> :: TransferredTo st -> TransferredTo st -> TransferredTo st
$c<> :: forall st. TransferredTo st -> TransferredTo st -> TransferredTo st
Semigroup, Semigroup (TransferredTo st)
TransferredTo st
Semigroup (TransferredTo st)
-> TransferredTo st
-> (TransferredTo st -> TransferredTo st -> TransferredTo st)
-> ([TransferredTo st] -> TransferredTo st)
-> Monoid (TransferredTo st)
[TransferredTo st] -> TransferredTo st
TransferredTo st -> TransferredTo st -> TransferredTo st
forall st. Semigroup (TransferredTo st)
forall st. TransferredTo st
forall a.
Semigroup a -> a -> (a -> a -> a) -> ([a] -> a) -> Monoid a
forall st. [TransferredTo st] -> TransferredTo st
forall st. TransferredTo st -> TransferredTo st -> TransferredTo st
mconcat :: [TransferredTo st] -> TransferredTo st
$cmconcat :: forall st. [TransferredTo st] -> TransferredTo st
mappend :: TransferredTo st -> TransferredTo st -> TransferredTo st
$cmappend :: forall st. TransferredTo st -> TransferredTo st -> TransferredTo st
mempty :: TransferredTo st
$cmempty :: forall st. TransferredTo st
$cp1Monoid :: forall st. Semigroup (TransferredTo st)
Monoid)
deriving Context -> TransferredTo st -> IO (Maybe ThunkInfo)
Proxy (TransferredTo st) -> String
(Context -> TransferredTo st -> IO (Maybe ThunkInfo))
-> (Context -> TransferredTo st -> IO (Maybe ThunkInfo))
-> (Proxy (TransferredTo st) -> String)
-> NoThunks (TransferredTo st)
forall st. Context -> TransferredTo st -> IO (Maybe ThunkInfo)
forall st. Proxy (TransferredTo st) -> String
forall a.
(Context -> a -> IO (Maybe ThunkInfo))
-> (Context -> a -> IO (Maybe ThunkInfo))
-> (Proxy a -> String)
-> NoThunks a
showTypeOf :: Proxy (TransferredTo st) -> String
$cshowTypeOf :: forall st. Proxy (TransferredTo st) -> String
wNoThunks :: Context -> TransferredTo st -> IO (Maybe ThunkInfo)
$cwNoThunks :: forall st. Context -> TransferredTo st -> IO (Maybe ThunkInfo)
noThunks :: Context -> TransferredTo st -> IO (Maybe ThunkInfo)
$cnoThunks :: forall st. Context -> TransferredTo st -> IO (Maybe ThunkInfo)
NoThunks via OnlyCheckWhnfNamed "TransferredTo" (TransferredTo st)
data TempRegistry st m = TempRegistry {
TempRegistry st m -> ResourceRegistry m
tempResourceRegistry :: !(ResourceRegistry m)
, TempRegistry st m -> StrictTVar m (TransferredTo st)
tempTransferredTo :: !(StrictTVar m (TransferredTo st))
}
newtype WithTempRegistry st m a = WithTempRegistry {
WithTempRegistry st m a -> ReaderT (TempRegistry st m) m a
unWithTempRegistry :: ReaderT (TempRegistry st m) m a
}
deriving newtype (a -> WithTempRegistry st m b -> WithTempRegistry st m a
(a -> b) -> WithTempRegistry st m a -> WithTempRegistry st m b
(forall a b.
(a -> b) -> WithTempRegistry st m a -> WithTempRegistry st m b)
-> (forall a b.
a -> WithTempRegistry st m b -> WithTempRegistry st m a)
-> Functor (WithTempRegistry st m)
forall a b. a -> WithTempRegistry st m b -> WithTempRegistry st m a
forall a b.
(a -> b) -> WithTempRegistry st m a -> WithTempRegistry st m b
forall st (m :: * -> *) a b.
Functor m =>
a -> WithTempRegistry st m b -> WithTempRegistry st m a
forall st (m :: * -> *) a b.
Functor m =>
(a -> b) -> WithTempRegistry st m a -> WithTempRegistry st m b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: a -> WithTempRegistry st m b -> WithTempRegistry st m a
$c<$ :: forall st (m :: * -> *) a b.
Functor m =>
a -> WithTempRegistry st m b -> WithTempRegistry st m a
fmap :: (a -> b) -> WithTempRegistry st m a -> WithTempRegistry st m b
$cfmap :: forall st (m :: * -> *) a b.
Functor m =>
(a -> b) -> WithTempRegistry st m a -> WithTempRegistry st m b
Functor, Functor (WithTempRegistry st m)
a -> WithTempRegistry st m a
Functor (WithTempRegistry st m)
-> (forall a. a -> WithTempRegistry st m a)
-> (forall a b.
WithTempRegistry st m (a -> b)
-> WithTempRegistry st m a -> WithTempRegistry st m b)
-> (forall a b c.
(a -> b -> c)
-> WithTempRegistry st m a
-> WithTempRegistry st m b
-> WithTempRegistry st m c)
-> (forall a b.
WithTempRegistry st m a
-> WithTempRegistry st m b -> WithTempRegistry st m b)
-> (forall a b.
WithTempRegistry st m a
-> WithTempRegistry st m b -> WithTempRegistry st m a)
-> Applicative (WithTempRegistry st m)
WithTempRegistry st m a
-> WithTempRegistry st m b -> WithTempRegistry st m b
WithTempRegistry st m a
-> WithTempRegistry st m b -> WithTempRegistry st m a
WithTempRegistry st m (a -> b)
-> WithTempRegistry st m a -> WithTempRegistry st m b
(a -> b -> c)
-> WithTempRegistry st m a
-> WithTempRegistry st m b
-> WithTempRegistry st m c
forall a. a -> WithTempRegistry st m a
forall a b.
WithTempRegistry st m a
-> WithTempRegistry st m b -> WithTempRegistry st m a
forall a b.
WithTempRegistry st m a
-> WithTempRegistry st m b -> WithTempRegistry st m b
forall a b.
WithTempRegistry st m (a -> b)
-> WithTempRegistry st m a -> WithTempRegistry st m b
forall a b c.
(a -> b -> c)
-> WithTempRegistry st m a
-> WithTempRegistry st m b
-> WithTempRegistry st m c
forall st (m :: * -> *).
Applicative m =>
Functor (WithTempRegistry st m)
forall st (m :: * -> *) a.
Applicative m =>
a -> WithTempRegistry st m a
forall st (m :: * -> *) a b.
Applicative m =>
WithTempRegistry st m a
-> WithTempRegistry st m b -> WithTempRegistry st m a
forall st (m :: * -> *) a b.
Applicative m =>
WithTempRegistry st m a
-> WithTempRegistry st m b -> WithTempRegistry st m b
forall st (m :: * -> *) a b.
Applicative m =>
WithTempRegistry st m (a -> b)
-> WithTempRegistry st m a -> WithTempRegistry st m b
forall st (m :: * -> *) a b c.
Applicative m =>
(a -> b -> c)
-> WithTempRegistry st m a
-> WithTempRegistry st m b
-> WithTempRegistry st m c
forall (f :: * -> *).
Functor f
-> (forall a. a -> f a)
-> (forall a b. f (a -> b) -> f a -> f b)
-> (forall a b c. (a -> b -> c) -> f a -> f b -> f c)
-> (forall a b. f a -> f b -> f b)
-> (forall a b. f a -> f b -> f a)
-> Applicative f
<* :: WithTempRegistry st m a
-> WithTempRegistry st m b -> WithTempRegistry st m a
$c<* :: forall st (m :: * -> *) a b.
Applicative m =>
WithTempRegistry st m a
-> WithTempRegistry st m b -> WithTempRegistry st m a
*> :: WithTempRegistry st m a
-> WithTempRegistry st m b -> WithTempRegistry st m b
$c*> :: forall st (m :: * -> *) a b.
Applicative m =>
WithTempRegistry st m a
-> WithTempRegistry st m b -> WithTempRegistry st m b
liftA2 :: (a -> b -> c)
-> WithTempRegistry st m a
-> WithTempRegistry st m b
-> WithTempRegistry st m c
$cliftA2 :: forall st (m :: * -> *) a b c.
Applicative m =>
(a -> b -> c)
-> WithTempRegistry st m a
-> WithTempRegistry st m b
-> WithTempRegistry st m c
<*> :: WithTempRegistry st m (a -> b)
-> WithTempRegistry st m a -> WithTempRegistry st m b
$c<*> :: forall st (m :: * -> *) a b.
Applicative m =>
WithTempRegistry st m (a -> b)
-> WithTempRegistry st m a -> WithTempRegistry st m b
pure :: a -> WithTempRegistry st m a
$cpure :: forall st (m :: * -> *) a.
Applicative m =>
a -> WithTempRegistry st m a
$cp1Applicative :: forall st (m :: * -> *).
Applicative m =>
Functor (WithTempRegistry st m)
Applicative, Applicative (WithTempRegistry st m)
a -> WithTempRegistry st m a
Applicative (WithTempRegistry st m)
-> (forall a b.
WithTempRegistry st m a
-> (a -> WithTempRegistry st m b) -> WithTempRegistry st m b)
-> (forall a b.
WithTempRegistry st m a
-> WithTempRegistry st m b -> WithTempRegistry st m b)
-> (forall a. a -> WithTempRegistry st m a)
-> Monad (WithTempRegistry st m)
WithTempRegistry st m a
-> (a -> WithTempRegistry st m b) -> WithTempRegistry st m b
WithTempRegistry st m a
-> WithTempRegistry st m b -> WithTempRegistry st m b
forall a. a -> WithTempRegistry st m a
forall a b.
WithTempRegistry st m a
-> WithTempRegistry st m b -> WithTempRegistry st m b
forall a b.
WithTempRegistry st m a
-> (a -> WithTempRegistry st m b) -> WithTempRegistry st m b
forall st (m :: * -> *).
Monad m =>
Applicative (WithTempRegistry st m)
forall st (m :: * -> *) a. Monad m => a -> WithTempRegistry st m a
forall st (m :: * -> *) a b.
Monad m =>
WithTempRegistry st m a
-> WithTempRegistry st m b -> WithTempRegistry st m b
forall st (m :: * -> *) a b.
Monad m =>
WithTempRegistry st m a
-> (a -> WithTempRegistry st m b) -> WithTempRegistry st m b
forall (m :: * -> *).
Applicative m
-> (forall a b. m a -> (a -> m b) -> m b)
-> (forall a b. m a -> m b -> m b)
-> (forall a. a -> m a)
-> Monad m
return :: a -> WithTempRegistry st m a
$creturn :: forall st (m :: * -> *) a. Monad m => a -> WithTempRegistry st m a
>> :: WithTempRegistry st m a
-> WithTempRegistry st m b -> WithTempRegistry st m b
$c>> :: forall st (m :: * -> *) a b.
Monad m =>
WithTempRegistry st m a
-> WithTempRegistry st m b -> WithTempRegistry st m b
>>= :: WithTempRegistry st m a
-> (a -> WithTempRegistry st m b) -> WithTempRegistry st m b
$c>>= :: forall st (m :: * -> *) a b.
Monad m =>
WithTempRegistry st m a
-> (a -> WithTempRegistry st m b) -> WithTempRegistry st m b
$cp1Monad :: forall st (m :: * -> *).
Monad m =>
Applicative (WithTempRegistry st m)
Monad, Monad (WithTempRegistry st m)
e -> WithTempRegistry st m a
Monad (WithTempRegistry st m)
-> (forall e a. Exception e => e -> WithTempRegistry st m a)
-> (forall a b c.
WithTempRegistry st m a
-> (a -> WithTempRegistry st m b)
-> (a -> WithTempRegistry st m c)
-> WithTempRegistry st m c)
-> (forall a b c.
WithTempRegistry st m a
-> WithTempRegistry st m b
-> WithTempRegistry st m c
-> WithTempRegistry st m c)
-> (forall a b.
WithTempRegistry st m a
-> WithTempRegistry st m b -> WithTempRegistry st m a)
-> MonadThrow (WithTempRegistry st m)
WithTempRegistry st m a
-> (a -> WithTempRegistry st m b)
-> (a -> WithTempRegistry st m c)
-> WithTempRegistry st m c
WithTempRegistry st m a
-> WithTempRegistry st m b
-> WithTempRegistry st m c
-> WithTempRegistry st m c
WithTempRegistry st m a
-> WithTempRegistry st m b -> WithTempRegistry st m a
forall e a. Exception e => e -> WithTempRegistry st m a
forall a b.
WithTempRegistry st m a
-> WithTempRegistry st m b -> WithTempRegistry st m a
forall a b c.
WithTempRegistry st m a
-> WithTempRegistry st m b
-> WithTempRegistry st m c
-> WithTempRegistry st m c
forall a b c.
WithTempRegistry st m a
-> (a -> WithTempRegistry st m b)
-> (a -> WithTempRegistry st m c)
-> WithTempRegistry st m c
forall st (m :: * -> *).
MonadThrow m =>
Monad (WithTempRegistry st m)
forall st (m :: * -> *) e a.
(MonadThrow m, Exception e) =>
e -> WithTempRegistry st m a
forall st (m :: * -> *) a b.
MonadThrow m =>
WithTempRegistry st m a
-> WithTempRegistry st m b -> WithTempRegistry st m a
forall st (m :: * -> *) a b c.
MonadThrow m =>
WithTempRegistry st m a
-> WithTempRegistry st m b
-> WithTempRegistry st m c
-> WithTempRegistry st m c
forall st (m :: * -> *) a b c.
MonadThrow m =>
WithTempRegistry st m a
-> (a -> WithTempRegistry st m b)
-> (a -> WithTempRegistry st m c)
-> WithTempRegistry st m c
forall (m :: * -> *).
Monad m
-> (forall e a. Exception e => e -> m a)
-> (forall a b c. m a -> (a -> m b) -> (a -> m c) -> m c)
-> (forall a b c. m a -> m b -> m c -> m c)
-> (forall a b. m a -> m b -> m a)
-> MonadThrow m
finally :: WithTempRegistry st m a
-> WithTempRegistry st m b -> WithTempRegistry st m a
$cfinally :: forall st (m :: * -> *) a b.
MonadThrow m =>
WithTempRegistry st m a
-> WithTempRegistry st m b -> WithTempRegistry st m a
bracket_ :: WithTempRegistry st m a
-> WithTempRegistry st m b
-> WithTempRegistry st m c
-> WithTempRegistry st m c
$cbracket_ :: forall st (m :: * -> *) a b c.
MonadThrow m =>
WithTempRegistry st m a
-> WithTempRegistry st m b
-> WithTempRegistry st m c
-> WithTempRegistry st m c
bracket :: WithTempRegistry st m a
-> (a -> WithTempRegistry st m b)
-> (a -> WithTempRegistry st m c)
-> WithTempRegistry st m c
$cbracket :: forall st (m :: * -> *) a b c.
MonadThrow m =>
WithTempRegistry st m a
-> (a -> WithTempRegistry st m b)
-> (a -> WithTempRegistry st m c)
-> WithTempRegistry st m c
throwIO :: e -> WithTempRegistry st m a
$cthrowIO :: forall st (m :: * -> *) e a.
(MonadThrow m, Exception e) =>
e -> WithTempRegistry st m a
$cp1MonadThrow :: forall st (m :: * -> *).
MonadThrow m =>
Monad (WithTempRegistry st m)
MonadThrow, MonadThrow (WithTempRegistry st m)
MonadThrow (WithTempRegistry st m)
-> (forall e a.
Exception e =>
WithTempRegistry st m a
-> (e -> WithTempRegistry st m a) -> WithTempRegistry st m a)
-> (forall e b a.
Exception e =>
(e -> Maybe b)
-> WithTempRegistry st m a
-> (b -> WithTempRegistry st m a)
-> WithTempRegistry st m a)
-> (forall e a.
Exception e =>
WithTempRegistry st m a -> WithTempRegistry st m (Either e a))
-> (forall e b a.
Exception e =>
(e -> Maybe b)
-> WithTempRegistry st m a -> WithTempRegistry st m (Either b a))
-> (forall e a.
Exception e =>
(e -> WithTempRegistry st m a)
-> WithTempRegistry st m a -> WithTempRegistry st m a)
-> (forall e b a.
Exception e =>
(e -> Maybe b)
-> (b -> WithTempRegistry st m a)
-> WithTempRegistry st m a
-> WithTempRegistry st m a)
-> (forall a b.
WithTempRegistry st m a
-> WithTempRegistry st m b -> WithTempRegistry st m a)
-> (forall a b c.
WithTempRegistry st m a
-> (a -> WithTempRegistry st m b)
-> (a -> WithTempRegistry st m c)
-> WithTempRegistry st m c)
-> (forall a b c.
WithTempRegistry st m a
-> (a -> ExitCase b -> WithTempRegistry st m c)
-> (a -> WithTempRegistry st m b)
-> WithTempRegistry st m (b, c))
-> MonadCatch (WithTempRegistry st m)
WithTempRegistry st m a
-> (e -> WithTempRegistry st m a) -> WithTempRegistry st m a
WithTempRegistry st m a -> WithTempRegistry st m (Either e a)
WithTempRegistry st m a
-> WithTempRegistry st m b -> WithTempRegistry st m a
WithTempRegistry st m a
-> (a -> WithTempRegistry st m b)
-> (a -> WithTempRegistry st m c)
-> WithTempRegistry st m c
WithTempRegistry st m a
-> (a -> ExitCase b -> WithTempRegistry st m c)
-> (a -> WithTempRegistry st m b)
-> WithTempRegistry st m (b, c)
(e -> Maybe b)
-> WithTempRegistry st m a
-> (b -> WithTempRegistry st m a)
-> WithTempRegistry st m a
(e -> Maybe b)
-> WithTempRegistry st m a -> WithTempRegistry st m (Either b a)
(e -> WithTempRegistry st m a)
-> WithTempRegistry st m a -> WithTempRegistry st m a
(e -> Maybe b)
-> (b -> WithTempRegistry st m a)
-> WithTempRegistry st m a
-> WithTempRegistry st m a
forall e a.
Exception e =>
WithTempRegistry st m a -> WithTempRegistry st m (Either e a)
forall e a.
Exception e =>
WithTempRegistry st m a
-> (e -> WithTempRegistry st m a) -> WithTempRegistry st m a
forall e a.
Exception e =>
(e -> WithTempRegistry st m a)
-> WithTempRegistry st m a -> WithTempRegistry st m a
forall a b.
WithTempRegistry st m a
-> WithTempRegistry st m b -> WithTempRegistry st m a
forall e b a.
Exception e =>
(e -> Maybe b)
-> WithTempRegistry st m a -> WithTempRegistry st m (Either b a)
forall e b a.
Exception e =>
(e -> Maybe b)
-> WithTempRegistry st m a
-> (b -> WithTempRegistry st m a)
-> WithTempRegistry st m a
forall e b a.
Exception e =>
(e -> Maybe b)
-> (b -> WithTempRegistry st m a)
-> WithTempRegistry st m a
-> WithTempRegistry st m a
forall a b c.
WithTempRegistry st m a
-> (a -> WithTempRegistry st m b)
-> (a -> WithTempRegistry st m c)
-> WithTempRegistry st m c
forall a b c.
WithTempRegistry st m a
-> (a -> ExitCase b -> WithTempRegistry st m c)
-> (a -> WithTempRegistry st m b)
-> WithTempRegistry st m (b, c)
forall st (m :: * -> *).
MonadCatch m =>
MonadThrow (WithTempRegistry st m)
forall st (m :: * -> *) e a.
(MonadCatch m, Exception e) =>
WithTempRegistry st m a -> WithTempRegistry st m (Either e a)
forall st (m :: * -> *) e a.
(MonadCatch m, Exception e) =>
WithTempRegistry st m a
-> (e -> WithTempRegistry st m a) -> WithTempRegistry st m a
forall st (m :: * -> *) e a.
(MonadCatch m, Exception e) =>
(e -> WithTempRegistry st m a)
-> WithTempRegistry st m a -> WithTempRegistry st m a
forall st (m :: * -> *) a b.
MonadCatch m =>
WithTempRegistry st m a
-> WithTempRegistry st m b -> WithTempRegistry st m a
forall st (m :: * -> *) e b a.
(MonadCatch m, Exception e) =>
(e -> Maybe b)
-> WithTempRegistry st m a -> WithTempRegistry st m (Either b a)
forall st (m :: * -> *) e b a.
(MonadCatch m, Exception e) =>
(e -> Maybe b)
-> WithTempRegistry st m a
-> (b -> WithTempRegistry st m a)
-> WithTempRegistry st m a
forall st (m :: * -> *) e b a.
(MonadCatch m, Exception e) =>
(e -> Maybe b)
-> (b -> WithTempRegistry st m a)
-> WithTempRegistry st m a
-> WithTempRegistry st m a
forall st (m :: * -> *) a b c.
MonadCatch m =>
WithTempRegistry st m a
-> (a -> WithTempRegistry st m b)
-> (a -> WithTempRegistry st m c)
-> WithTempRegistry st m c
forall st (m :: * -> *) a b c.
MonadCatch m =>
WithTempRegistry st m a
-> (a -> ExitCase b -> WithTempRegistry st m c)
-> (a -> WithTempRegistry st m b)
-> WithTempRegistry st m (b, c)
forall (m :: * -> *).
MonadThrow m
-> (forall e a. Exception e => m a -> (e -> m a) -> m a)
-> (forall e b a.
Exception e =>
(e -> Maybe b) -> m a -> (b -> m a) -> m a)
-> (forall e a. Exception e => m a -> m (Either e a))
-> (forall e b a.
Exception e =>
(e -> Maybe b) -> m a -> m (Either b a))
-> (forall e a. Exception e => (e -> m a) -> m a -> m a)
-> (forall e b a.
Exception e =>
(e -> Maybe b) -> (b -> m a) -> m a -> m a)
-> (forall a b. m a -> m b -> m a)
-> (forall a b c. m a -> (a -> m b) -> (a -> m c) -> m c)
-> (forall a b c.
m a -> (a -> ExitCase b -> m c) -> (a -> m b) -> m (b, c))
-> MonadCatch m
generalBracket :: WithTempRegistry st m a
-> (a -> ExitCase b -> WithTempRegistry st m c)
-> (a -> WithTempRegistry st m b)
-> WithTempRegistry st m (b, c)
$cgeneralBracket :: forall st (m :: * -> *) a b c.
MonadCatch m =>
WithTempRegistry st m a
-> (a -> ExitCase b -> WithTempRegistry st m c)
-> (a -> WithTempRegistry st m b)
-> WithTempRegistry st m (b, c)
bracketOnError :: WithTempRegistry st m a
-> (a -> WithTempRegistry st m b)
-> (a -> WithTempRegistry st m c)
-> WithTempRegistry st m c
$cbracketOnError :: forall st (m :: * -> *) a b c.
MonadCatch m =>
WithTempRegistry st m a
-> (a -> WithTempRegistry st m b)
-> (a -> WithTempRegistry st m c)
-> WithTempRegistry st m c
onException :: WithTempRegistry st m a
-> WithTempRegistry st m b -> WithTempRegistry st m a
$conException :: forall st (m :: * -> *) a b.
MonadCatch m =>
WithTempRegistry st m a
-> WithTempRegistry st m b -> WithTempRegistry st m a
handleJust :: (e -> Maybe b)
-> (b -> WithTempRegistry st m a)
-> WithTempRegistry st m a
-> WithTempRegistry st m a
$chandleJust :: forall st (m :: * -> *) e b a.
(MonadCatch m, Exception e) =>
(e -> Maybe b)
-> (b -> WithTempRegistry st m a)
-> WithTempRegistry st m a
-> WithTempRegistry st m a
handle :: (e -> WithTempRegistry st m a)
-> WithTempRegistry st m a -> WithTempRegistry st m a
$chandle :: forall st (m :: * -> *) e a.
(MonadCatch m, Exception e) =>
(e -> WithTempRegistry st m a)
-> WithTempRegistry st m a -> WithTempRegistry st m a
tryJust :: (e -> Maybe b)
-> WithTempRegistry st m a -> WithTempRegistry st m (Either b a)
$ctryJust :: forall st (m :: * -> *) e b a.
(MonadCatch m, Exception e) =>
(e -> Maybe b)
-> WithTempRegistry st m a -> WithTempRegistry st m (Either b a)
try :: WithTempRegistry st m a -> WithTempRegistry st m (Either e a)
$ctry :: forall st (m :: * -> *) e a.
(MonadCatch m, Exception e) =>
WithTempRegistry st m a -> WithTempRegistry st m (Either e a)
catchJust :: (e -> Maybe b)
-> WithTempRegistry st m a
-> (b -> WithTempRegistry st m a)
-> WithTempRegistry st m a
$ccatchJust :: forall st (m :: * -> *) e b a.
(MonadCatch m, Exception e) =>
(e -> Maybe b)
-> WithTempRegistry st m a
-> (b -> WithTempRegistry st m a)
-> WithTempRegistry st m a
catch :: WithTempRegistry st m a
-> (e -> WithTempRegistry st m a) -> WithTempRegistry st m a
$ccatch :: forall st (m :: * -> *) e a.
(MonadCatch m, Exception e) =>
WithTempRegistry st m a
-> (e -> WithTempRegistry st m a) -> WithTempRegistry st m a
$cp1MonadCatch :: forall st (m :: * -> *).
MonadCatch m =>
MonadThrow (WithTempRegistry st m)
MonadCatch, MonadCatch (WithTempRegistry st m)
MonadCatch (WithTempRegistry st m)
-> (forall b.
((forall a. WithTempRegistry st m a -> WithTempRegistry st m a)
-> WithTempRegistry st m b)
-> WithTempRegistry st m b)
-> (forall b.
((forall a. WithTempRegistry st m a -> WithTempRegistry st m a)
-> WithTempRegistry st m b)
-> WithTempRegistry st m b)
-> (forall a. WithTempRegistry st m a -> WithTempRegistry st m a)
-> (forall a. WithTempRegistry st m a -> WithTempRegistry st m a)
-> MonadMask (WithTempRegistry st m)
WithTempRegistry st m a -> WithTempRegistry st m a
WithTempRegistry st m a -> WithTempRegistry st m a
((forall a. WithTempRegistry st m a -> WithTempRegistry st m a)
-> WithTempRegistry st m b)
-> WithTempRegistry st m b
((forall a. WithTempRegistry st m a -> WithTempRegistry st m a)
-> WithTempRegistry st m b)
-> WithTempRegistry st m b
forall a. WithTempRegistry st m a -> WithTempRegistry st m a
forall b.
((forall a. WithTempRegistry st m a -> WithTempRegistry st m a)
-> WithTempRegistry st m b)
-> WithTempRegistry st m b
forall st (m :: * -> *).
MonadMask m =>
MonadCatch (WithTempRegistry st m)
forall st (m :: * -> *) a.
MonadMask m =>
WithTempRegistry st m a -> WithTempRegistry st m a
forall st (m :: * -> *) b.
MonadMask m =>
((forall a. WithTempRegistry st m a -> WithTempRegistry st m a)
-> WithTempRegistry st m b)
-> WithTempRegistry st m b
forall (m :: * -> *).
MonadCatch m
-> (forall b. ((forall a. m a -> m a) -> m b) -> m b)
-> (forall b. ((forall a. m a -> m a) -> m b) -> m b)
-> (forall a. m a -> m a)
-> (forall a. m a -> m a)
-> MonadMask m
uninterruptibleMask_ :: WithTempRegistry st m a -> WithTempRegistry st m a
$cuninterruptibleMask_ :: forall st (m :: * -> *) a.
MonadMask m =>
WithTempRegistry st m a -> WithTempRegistry st m a
mask_ :: WithTempRegistry st m a -> WithTempRegistry st m a
$cmask_ :: forall st (m :: * -> *) a.
MonadMask m =>
WithTempRegistry st m a -> WithTempRegistry st m a
uninterruptibleMask :: ((forall a. WithTempRegistry st m a -> WithTempRegistry st m a)
-> WithTempRegistry st m b)
-> WithTempRegistry st m b
$cuninterruptibleMask :: forall st (m :: * -> *) b.
MonadMask m =>
((forall a. WithTempRegistry st m a -> WithTempRegistry st m a)
-> WithTempRegistry st m b)
-> WithTempRegistry st m b
mask :: ((forall a. WithTempRegistry st m a -> WithTempRegistry st m a)
-> WithTempRegistry st m b)
-> WithTempRegistry st m b
$cmask :: forall st (m :: * -> *) b.
MonadMask m =>
((forall a. WithTempRegistry st m a -> WithTempRegistry st m a)
-> WithTempRegistry st m b)
-> WithTempRegistry st m b
$cp1MonadMask :: forall st (m :: * -> *).
MonadMask m =>
MonadCatch (WithTempRegistry st m)
MonadMask, Monad (WithTempRegistry st m)
MonadSTMTx (STM (WithTempRegistry st m))
WithTempRegistry st m (TMVar (WithTempRegistry st m) a)
a -> WithTempRegistry st m (TVar (WithTempRegistry st m) a)
a -> WithTempRegistry st m (TMVar (WithTempRegistry st m) a)
Monad (WithTempRegistry st m)
-> MonadSTMTx (STM (WithTempRegistry st m))
-> (forall a.
HasCallStack =>
STM (WithTempRegistry st m) a -> WithTempRegistry st m a)
-> (forall a.
a -> WithTempRegistry st m (TVar (WithTempRegistry st m) a))
-> (forall a.
a -> WithTempRegistry st m (TMVar (WithTempRegistry st m) a))
-> (forall a.
WithTempRegistry st m (TMVar (WithTempRegistry st m) a))
-> (forall a.
Natural
-> WithTempRegistry st m (TBQueue (WithTempRegistry st m) a))
-> MonadSTM (WithTempRegistry st m)
Natural
-> WithTempRegistry st m (TBQueue (WithTempRegistry st m) a)
STM (WithTempRegistry st m) a -> WithTempRegistry st m a
forall a. WithTempRegistry st m (TMVar (WithTempRegistry st m) a)
forall a.
a -> WithTempRegistry st m (TMVar (WithTempRegistry st m) a)
forall a.
a -> WithTempRegistry st m (TVar (WithTempRegistry st m) a)
forall a.
HasCallStack =>
STM (WithTempRegistry st m) a -> WithTempRegistry st m a
forall a.
Natural
-> WithTempRegistry st m (TBQueue (WithTempRegistry st m) a)
forall st (m :: * -> *).
MonadSTM m =>
Monad (WithTempRegistry st m)
forall st (m :: * -> *).
MonadSTM m =>
MonadSTMTx (STM (WithTempRegistry st m))
forall st (m :: * -> *) a.
MonadSTM m =>
WithTempRegistry st m (TMVar (WithTempRegistry st m) a)
forall st (m :: * -> *) a.
MonadSTM m =>
a -> WithTempRegistry st m (TMVar (WithTempRegistry st m) a)
forall st (m :: * -> *) a.
MonadSTM m =>
a -> WithTempRegistry st m (TVar (WithTempRegistry st m) a)
forall st (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
STM (WithTempRegistry st m) a -> WithTempRegistry st m a
forall st (m :: * -> *) a.
MonadSTM m =>
Natural
-> WithTempRegistry st m (TBQueue (WithTempRegistry st m) a)
forall (m :: * -> *).
Monad m
-> MonadSTMTx (STM m)
-> (forall a. HasCallStack => STM m a -> m a)
-> (forall a. a -> m (TVar m a))
-> (forall a. a -> m (TMVar m a))
-> (forall a. m (TMVar m a))
-> (forall a. Natural -> m (TBQueue m a))
-> MonadSTM m
newTBQueueIO :: Natural
-> WithTempRegistry st m (TBQueue (WithTempRegistry st m) a)
$cnewTBQueueIO :: forall st (m :: * -> *) a.
MonadSTM m =>
Natural
-> WithTempRegistry st m (TBQueue (WithTempRegistry st m) a)
newEmptyTMVarIO :: WithTempRegistry st m (TMVar (WithTempRegistry st m) a)
$cnewEmptyTMVarIO :: forall st (m :: * -> *) a.
MonadSTM m =>
WithTempRegistry st m (TMVar (WithTempRegistry st m) a)
newTMVarIO :: a -> WithTempRegistry st m (TMVar (WithTempRegistry st m) a)
$cnewTMVarIO :: forall st (m :: * -> *) a.
MonadSTM m =>
a -> WithTempRegistry st m (TMVar (WithTempRegistry st m) a)
newTVarIO :: a -> WithTempRegistry st m (TVar (WithTempRegistry st m) a)
$cnewTVarIO :: forall st (m :: * -> *) a.
MonadSTM m =>
a -> WithTempRegistry st m (TVar (WithTempRegistry st m) a)
atomically :: STM (WithTempRegistry st m) a -> WithTempRegistry st m a
$catomically :: forall st (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
STM (WithTempRegistry st m) a -> WithTempRegistry st m a
$cp2MonadSTM :: forall st (m :: * -> *).
MonadSTM m =>
MonadSTMTx (STM (WithTempRegistry st m))
$cp1MonadSTM :: forall st (m :: * -> *).
MonadSTM m =>
Monad (WithTempRegistry st m)
MonadSTM)
instance MonadTrans (WithTempRegistry st) where
lift :: m a -> WithTempRegistry st m a
lift = ReaderT (TempRegistry st m) m a -> WithTempRegistry st m a
forall st (m :: * -> *) a.
ReaderT (TempRegistry st m) m a -> WithTempRegistry st m a
WithTempRegistry (ReaderT (TempRegistry st m) m a -> WithTempRegistry st m a)
-> (m a -> ReaderT (TempRegistry st m) m a)
-> m a
-> WithTempRegistry st m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. m a -> ReaderT (TempRegistry st m) m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift
instance MonadState s m => MonadState s (WithTempRegistry st m) where
state :: (s -> (a, s)) -> WithTempRegistry st m a
state = ReaderT (TempRegistry st m) m a -> WithTempRegistry st m a
forall st (m :: * -> *) a.
ReaderT (TempRegistry st m) m a -> WithTempRegistry st m a
WithTempRegistry (ReaderT (TempRegistry st m) m a -> WithTempRegistry st m a)
-> ((s -> (a, s)) -> ReaderT (TempRegistry st m) m a)
-> (s -> (a, s))
-> WithTempRegistry st m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (s -> (a, s)) -> ReaderT (TempRegistry st m) m a
forall s (m :: * -> *) a. MonadState s m => (s -> (a, s)) -> m a
state
untrackTransferredTo
:: IOLike m
=> ResourceRegistry m
-> TransferredTo st
-> st
-> m ()
untrackTransferredTo :: ResourceRegistry m -> TransferredTo st -> st -> m ()
untrackTransferredTo ResourceRegistry m
rr TransferredTo st
transferredTo st
st =
ResourceRegistry m -> State (RegistryState m) () -> m ()
forall (m :: * -> *) a.
IOLike m =>
ResourceRegistry m -> State (RegistryState m) a -> m a
updateState ResourceRegistry m
rr (State (RegistryState m) () -> m ())
-> State (RegistryState m) () -> m ()
forall a b. (a -> b) -> a -> b
$ (ResourceId
-> StateT (RegistryState m) Identity (Maybe (Resource m)))
-> Set ResourceId -> State (RegistryState m) ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ ResourceId
-> StateT (RegistryState m) Identity (Maybe (Resource m))
forall (m :: * -> *).
ResourceId -> State (RegistryState m) (Maybe (Resource m))
removeResource Set ResourceId
rids
where
rids :: Set ResourceId
rids = TransferredTo st -> st -> Set ResourceId
forall st. TransferredTo st -> st -> Set ResourceId
runTransferredTo TransferredTo st
transferredTo st
st
allocateTemp
:: (IOLike m, HasCallStack)
=> m a
-> (a -> m Bool)
-> (st -> a -> Bool)
-> WithTempRegistry st m a
allocateTemp :: m a
-> (a -> m Bool) -> (st -> a -> Bool) -> WithTempRegistry st m a
allocateTemp m a
alloc a -> m Bool
free st -> a -> Bool
isTransferred = ReaderT (TempRegistry st m) m a -> WithTempRegistry st m a
forall st (m :: * -> *) a.
ReaderT (TempRegistry st m) m a -> WithTempRegistry st m a
WithTempRegistry (ReaderT (TempRegistry st m) m a -> WithTempRegistry st m a)
-> ReaderT (TempRegistry st m) m a -> WithTempRegistry st m a
forall a b. (a -> b) -> a -> b
$ do
TempRegistry ResourceRegistry m
rr StrictTVar m (TransferredTo st)
varTransferredTo <- ReaderT (TempRegistry st m) m (TempRegistry st m)
forall r (m :: * -> *). MonadReader r m => m r
ask
(ResourceKey m
key, a
a) <- m (ResourceKey m, a)
-> ReaderT (TempRegistry st m) m (ResourceKey m, a)
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m (ResourceKey m, a)
-> ReaderT (TempRegistry st m) m (ResourceKey m, a))
-> m (ResourceKey m, a)
-> ReaderT (TempRegistry st m) m (ResourceKey m, a)
forall a b. (a -> b) -> a -> b
$ (Either Void (ResourceKey m, a) -> (ResourceKey m, a))
-> m (Either Void (ResourceKey m, a)) -> m (ResourceKey m, a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Either Void (ResourceKey m, a) -> (ResourceKey m, a)
forall a. Either Void a -> a
mustBeRight (m (Either Void (ResourceKey m, a)) -> m (ResourceKey m, a))
-> m (Either Void (ResourceKey m, a)) -> m (ResourceKey m, a)
forall a b. (a -> b) -> a -> b
$
ResourceRegistry m
-> (ResourceId -> m (Either Void a))
-> (a -> m Bool)
-> m (Either Void (ResourceKey m, a))
forall (m :: * -> *) e a.
(IOLike m, HasCallStack) =>
ResourceRegistry m
-> (ResourceId -> m (Either e a))
-> (a -> m Bool)
-> m (Either e (ResourceKey m, a))
allocateEither ResourceRegistry m
rr ((a -> Either Void a) -> m a -> m (Either Void a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> Either Void a
forall a b. b -> Either a b
Right (m a -> m (Either Void a))
-> (ResourceId -> m a) -> ResourceId -> m (Either Void a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. m a -> ResourceId -> m a
forall a b. a -> b -> a
const m a
alloc) a -> m Bool
free
STM (ReaderT (TempRegistry st m) m) ()
-> ReaderT (TempRegistry st m) m ()
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
STM m a -> m a
atomically (STM (ReaderT (TempRegistry st m) m) ()
-> ReaderT (TempRegistry st m) m ())
-> STM (ReaderT (TempRegistry st m) m) ()
-> ReaderT (TempRegistry st m) m ()
forall a b. (a -> b) -> a -> b
$ StrictTVar m (TransferredTo st)
-> (TransferredTo st -> TransferredTo st) -> STM m ()
forall (m :: * -> *) a.
MonadSTM m =>
StrictTVar m a -> (a -> a) -> STM m ()
modifyTVar StrictTVar m (TransferredTo st)
varTransferredTo ((TransferredTo st -> TransferredTo st) -> STM m ())
-> (TransferredTo st -> TransferredTo st) -> STM m ()
forall a b. (a -> b) -> a -> b
$ TransferredTo st -> TransferredTo st -> TransferredTo st
forall a. Monoid a => a -> a -> a
mappend (TransferredTo st -> TransferredTo st -> TransferredTo st)
-> TransferredTo st -> TransferredTo st -> TransferredTo st
forall a b. (a -> b) -> a -> b
$
(st -> Set ResourceId) -> TransferredTo st
forall st. (st -> Set ResourceId) -> TransferredTo st
TransferredTo ((st -> Set ResourceId) -> TransferredTo st)
-> (st -> Set ResourceId) -> TransferredTo st
forall a b. (a -> b) -> a -> b
$ \st
st ->
if st -> a -> Bool
isTransferred st
st a
a
then ResourceId -> Set ResourceId
forall a. a -> Set a
Set.singleton (ResourceKey m -> ResourceId
forall (m :: * -> *). ResourceKey m -> ResourceId
resourceKeyId ResourceKey m
key)
else Set ResourceId
forall a. Set a
Set.empty
a -> ReaderT (TempRegistry st m) m a
forall (m :: * -> *) a. Monad m => a -> m a
return a
a
modifyWithTempRegistry
:: forall m st a. IOLike m
=> m st
-> (st -> ExitCase st -> m ())
-> StateT st (WithTempRegistry st m) a
-> m a
modifyWithTempRegistry :: m st
-> (st -> ExitCase st -> m ())
-> StateT st (WithTempRegistry st m) a
-> m a
modifyWithTempRegistry m st
getSt st -> ExitCase st -> m ()
putSt StateT st (WithTempRegistry st m) a
modSt = WithTempRegistry st m (a, st) -> m a
forall (m :: * -> *) st a.
(IOLike m, HasCallStack) =>
WithTempRegistry st m (a, st) -> m a
runWithTempRegistry (WithTempRegistry st m (a, st) -> m a)
-> WithTempRegistry st m (a, st) -> m a
forall a b. (a -> b) -> a -> b
$
((a, st), ()) -> (a, st)
forall a b. (a, b) -> a
fst (((a, st), ()) -> (a, st))
-> WithTempRegistry st m ((a, st), ())
-> WithTempRegistry st m (a, st)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> WithTempRegistry st m st
-> (st -> ExitCase (a, st) -> WithTempRegistry st m ())
-> (st -> WithTempRegistry st m (a, st))
-> WithTempRegistry st m ((a, st), ())
forall (m :: * -> *) a b c.
MonadCatch m =>
m a -> (a -> ExitCase b -> m c) -> (a -> m b) -> m (b, c)
generalBracket (m st -> WithTempRegistry st m st
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift m st
getSt) st -> ExitCase (a, st) -> WithTempRegistry st m ()
transfer st -> WithTempRegistry st m (a, st)
mutate
where
transfer :: st -> ExitCase (a, st) -> WithTempRegistry st m ()
transfer :: st -> ExitCase (a, st) -> WithTempRegistry st m ()
transfer st
initSt ExitCase (a, st)
ec = m () -> WithTempRegistry st m ()
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m () -> WithTempRegistry st m ())
-> m () -> WithTempRegistry st m ()
forall a b. (a -> b) -> a -> b
$ st -> ExitCase st -> m ()
putSt st
initSt ((a, st) -> st
forall a b. (a, b) -> b
snd ((a, st) -> st) -> ExitCase (a, st) -> ExitCase st
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ExitCase (a, st)
ec)
mutate :: st -> WithTempRegistry st m (a, st)
mutate :: st -> WithTempRegistry st m (a, st)
mutate = StateT st (WithTempRegistry st m) a
-> st -> WithTempRegistry st m (a, st)
forall s (m :: * -> *) a. StateT s m a -> s -> m (a, s)
runStateT StateT st (WithTempRegistry st m) a
modSt
registryThread :: ResourceRegistry m -> ThreadId m
registryThread :: ResourceRegistry m -> ThreadId m
registryThread = Context m -> ThreadId m
forall (m :: * -> *). Context m -> ThreadId m
contextThreadId (Context m -> ThreadId m)
-> (ResourceRegistry m -> Context m)
-> ResourceRegistry m
-> ThreadId m
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ResourceRegistry m -> Context m
forall (m :: * -> *). ResourceRegistry m -> Context m
registryContext
countResources :: IOLike m => ResourceRegistry m -> m Int
countResources :: ResourceRegistry m -> m Int
countResources ResourceRegistry m
rr = STM m Int -> m Int
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
STM m a -> m a
atomically (STM m Int -> m Int) -> STM m Int -> m Int
forall a b. (a -> b) -> a -> b
$ RegistryState m -> Int
forall (m :: * -> *). RegistryState m -> Int
aux (RegistryState m -> Int) -> STM m (RegistryState m) -> STM m Int
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> StrictTVar m (RegistryState m) -> STM m (RegistryState m)
forall (m :: * -> *) a. MonadSTM m => StrictTVar m a -> STM m a
readTVar (ResourceRegistry m -> StrictTVar m (RegistryState m)
forall (m :: * -> *).
ResourceRegistry m -> StrictTVar m (RegistryState m)
registryState ResourceRegistry m
rr)
where
aux :: RegistryState m -> Int
aux :: RegistryState m -> Int
aux = Map ResourceId (Resource m) -> Int
forall k a. Map k a -> Int
Map.size (Map ResourceId (Resource m) -> Int)
-> (RegistryState m -> Map ResourceId (Resource m))
-> RegistryState m
-> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. RegistryState m -> Map ResourceId (Resource m)
forall (m :: * -> *).
RegistryState m -> Map ResourceId (Resource m)
registryResources
allocate :: forall m a. (IOLike m, HasCallStack)
=> ResourceRegistry m
-> (ResourceId -> m a)
-> (a -> m ())
-> m (ResourceKey m, a)
allocate :: ResourceRegistry m
-> (ResourceId -> m a) -> (a -> m ()) -> m (ResourceKey m, a)
allocate ResourceRegistry m
rr ResourceId -> m a
alloc a -> m ()
free = Either Void (ResourceKey m, a) -> (ResourceKey m, a)
forall a. Either Void a -> a
mustBeRight (Either Void (ResourceKey m, a) -> (ResourceKey m, a))
-> m (Either Void (ResourceKey m, a)) -> m (ResourceKey m, a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
ResourceRegistry m
-> (ResourceId -> m (Either Void a))
-> (a -> m Bool)
-> m (Either Void (ResourceKey m, a))
forall (m :: * -> *) e a.
(IOLike m, HasCallStack) =>
ResourceRegistry m
-> (ResourceId -> m (Either e a))
-> (a -> m Bool)
-> m (Either e (ResourceKey m, a))
allocateEither ResourceRegistry m
rr ((a -> Either Void a) -> m a -> m (Either Void a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> Either Void a
forall a b. b -> Either a b
Right (m a -> m (Either Void a))
-> (ResourceId -> m a) -> ResourceId -> m (Either Void a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ResourceId -> m a
alloc) (\a
a -> a -> m ()
free a
a m () -> m Bool -> m Bool
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Bool -> m Bool
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
True)
allocateEither :: forall m e a. (IOLike m, HasCallStack)
=> ResourceRegistry m
-> (ResourceId -> m (Either e a))
-> (a -> m Bool)
-> m (Either e (ResourceKey m, a))
allocateEither :: ResourceRegistry m
-> (ResourceId -> m (Either e a))
-> (a -> m Bool)
-> m (Either e (ResourceKey m, a))
allocateEither ResourceRegistry m
rr ResourceId -> m (Either e a)
alloc a -> m Bool
free = do
Context m
context <- m (Context m)
forall (m :: * -> *). (IOLike m, HasCallStack) => m (Context m)
captureContext
ResourceRegistry m -> Context m -> m ()
forall (m :: * -> *).
IOLike m =>
ResourceRegistry m -> Context m -> m ()
ensureKnownThread ResourceRegistry m
rr Context m
context
Either PrettyCallStack ResourceId
mKey <- ResourceRegistry m
-> State (RegistryState m) (Either PrettyCallStack ResourceId)
-> m (Either PrettyCallStack ResourceId)
forall (m :: * -> *) a.
IOLike m =>
ResourceRegistry m -> State (RegistryState m) a -> m a
updateState ResourceRegistry m
rr (State (RegistryState m) (Either PrettyCallStack ResourceId)
-> m (Either PrettyCallStack ResourceId))
-> State (RegistryState m) (Either PrettyCallStack ResourceId)
-> m (Either PrettyCallStack ResourceId)
forall a b. (a -> b) -> a -> b
$ State (RegistryState m) (Either PrettyCallStack ResourceId)
forall (m :: * -> *).
State (RegistryState m) (Either PrettyCallStack ResourceId)
allocKey
case Either PrettyCallStack ResourceId
mKey of
Left PrettyCallStack
closed ->
ResourceRegistry m
-> Context m -> PrettyCallStack -> m (Either e (ResourceKey m, a))
forall (m :: * -> *) x.
IOLike m =>
ResourceRegistry m -> Context m -> PrettyCallStack -> m x
throwRegistryClosed ResourceRegistry m
rr Context m
context PrettyCallStack
closed
Right ResourceId
key -> m (Either e (ResourceKey m, a)) -> m (Either e (ResourceKey m, a))
forall (m :: * -> *) a. MonadMask m => m a -> m a
mask_ (m (Either e (ResourceKey m, a))
-> m (Either e (ResourceKey m, a)))
-> m (Either e (ResourceKey m, a))
-> m (Either e (ResourceKey m, a))
forall a b. (a -> b) -> a -> b
$ do
Either e a
ma <- ResourceId -> m (Either e a)
alloc ResourceId
key
case Either e a
ma of
Left e
e -> Either e (ResourceKey m, a) -> m (Either e (ResourceKey m, a))
forall (m :: * -> *) a. Monad m => a -> m a
return (Either e (ResourceKey m, a) -> m (Either e (ResourceKey m, a)))
-> Either e (ResourceKey m, a) -> m (Either e (ResourceKey m, a))
forall a b. (a -> b) -> a -> b
$ e -> Either e (ResourceKey m, a)
forall a b. a -> Either a b
Left e
e
Right a
a -> do
Either PrettyCallStack ()
inserted <- ResourceRegistry m
-> State (RegistryState m) (Either PrettyCallStack ())
-> m (Either PrettyCallStack ())
forall (m :: * -> *) a.
IOLike m =>
ResourceRegistry m -> State (RegistryState m) a -> m a
updateState ResourceRegistry m
rr (State (RegistryState m) (Either PrettyCallStack ())
-> m (Either PrettyCallStack ()))
-> State (RegistryState m) (Either PrettyCallStack ())
-> m (Either PrettyCallStack ())
forall a b. (a -> b) -> a -> b
$ ResourceId
-> Resource m
-> State (RegistryState m) (Either PrettyCallStack ())
forall (m :: * -> *).
ResourceId
-> Resource m
-> State (RegistryState m) (Either PrettyCallStack ())
insertResource ResourceId
key (Context m -> a -> Resource m
mkResource Context m
context a
a)
case Either PrettyCallStack ()
inserted of
Left PrettyCallStack
closed -> do
m Bool -> m ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (m Bool -> m ()) -> m Bool -> m ()
forall a b. (a -> b) -> a -> b
$ a -> m Bool
free a
a
ResourceRegistry m
-> Context m -> PrettyCallStack -> m (Either e (ResourceKey m, a))
forall (m :: * -> *) x.
IOLike m =>
ResourceRegistry m -> Context m -> PrettyCallStack -> m x
throwRegistryClosed ResourceRegistry m
rr Context m
context PrettyCallStack
closed
Right () ->
Either e (ResourceKey m, a) -> m (Either e (ResourceKey m, a))
forall (m :: * -> *) a. Monad m => a -> m a
return (Either e (ResourceKey m, a) -> m (Either e (ResourceKey m, a)))
-> Either e (ResourceKey m, a) -> m (Either e (ResourceKey m, a))
forall a b. (a -> b) -> a -> b
$ (ResourceKey m, a) -> Either e (ResourceKey m, a)
forall a b. b -> Either a b
Right (ResourceRegistry m -> ResourceId -> ResourceKey m
forall (m :: * -> *).
ResourceRegistry m -> ResourceId -> ResourceKey m
ResourceKey ResourceRegistry m
rr ResourceId
key, a
a)
where
mkResource :: Context m -> a -> Resource m
mkResource :: Context m -> a -> Resource m
mkResource Context m
context a
a = Resource :: forall (m :: * -> *). Context m -> Release m -> Resource m
Resource {
resourceContext :: Context m
resourceContext = Context m
context
, resourceRelease :: Release m
resourceRelease = m Bool -> Release m
forall (m :: * -> *). m Bool -> Release m
Release (m Bool -> Release m) -> m Bool -> Release m
forall a b. (a -> b) -> a -> b
$ a -> m Bool
free a
a
}
throwRegistryClosed :: IOLike m
=> ResourceRegistry m
-> Context m
-> PrettyCallStack
-> m x
throwRegistryClosed :: ResourceRegistry m -> Context m -> PrettyCallStack -> m x
throwRegistryClosed ResourceRegistry m
rr Context m
context PrettyCallStack
closed = RegistryClosedException -> m x
forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwIO RegistryClosedException :: forall (m :: * -> *).
IOLike m =>
Context m
-> PrettyCallStack -> Context m -> RegistryClosedException
RegistryClosedException {
registryClosedRegistryContext :: Context m
registryClosedRegistryContext = ResourceRegistry m -> Context m
forall (m :: * -> *). ResourceRegistry m -> Context m
registryContext ResourceRegistry m
rr
, registryClosedCloseCallStack :: PrettyCallStack
registryClosedCloseCallStack = PrettyCallStack
closed
, registryClosedAllocContext :: Context m
registryClosedAllocContext = Context m
context
}
release :: (IOLike m, HasCallStack) => ResourceKey m -> m (Maybe (Context m))
release :: ResourceKey m -> m (Maybe (Context m))
release key :: ResourceKey m
key@(ResourceKey ResourceRegistry m
rr ResourceId
_) = do
Context m
context <- m (Context m)
forall (m :: * -> *). (IOLike m, HasCallStack) => m (Context m)
captureContext
ResourceRegistry m -> Context m -> m ()
forall (m :: * -> *).
IOLike m =>
ResourceRegistry m -> Context m -> m ()
ensureKnownThread ResourceRegistry m
rr Context m
context
ResourceKey m -> m (Maybe (Context m))
forall (m :: * -> *).
IOLike m =>
ResourceKey m -> m (Maybe (Context m))
unsafeRelease ResourceKey m
key
unsafeRelease :: IOLike m => ResourceKey m -> m (Maybe (Context m))
unsafeRelease :: ResourceKey m -> m (Maybe (Context m))
unsafeRelease (ResourceKey ResourceRegistry m
rr ResourceId
rid) = do
m (Maybe (Context m)) -> m (Maybe (Context m))
forall (m :: * -> *) a. MonadMask m => m a -> m a
mask_ (m (Maybe (Context m)) -> m (Maybe (Context m)))
-> m (Maybe (Context m)) -> m (Maybe (Context m))
forall a b. (a -> b) -> a -> b
$ do
Maybe (Resource m)
mResource <- ResourceRegistry m
-> State (RegistryState m) (Maybe (Resource m))
-> m (Maybe (Resource m))
forall (m :: * -> *) a.
IOLike m =>
ResourceRegistry m -> State (RegistryState m) a -> m a
updateState ResourceRegistry m
rr (State (RegistryState m) (Maybe (Resource m))
-> m (Maybe (Resource m)))
-> State (RegistryState m) (Maybe (Resource m))
-> m (Maybe (Resource m))
forall a b. (a -> b) -> a -> b
$ ResourceId -> State (RegistryState m) (Maybe (Resource m))
forall (m :: * -> *).
ResourceId -> State (RegistryState m) (Maybe (Resource m))
removeResource ResourceId
rid
case Maybe (Resource m)
mResource of
Maybe (Resource m)
Nothing -> Maybe (Context m) -> m (Maybe (Context m))
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe (Context m)
forall a. Maybe a
Nothing
Just Resource m
resource -> do
Bool
actuallyReleased <- Resource m -> m Bool
forall (m :: * -> *). Resource m -> m Bool
releaseResource Resource m
resource
Maybe (Context m) -> m (Maybe (Context m))
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe (Context m) -> m (Maybe (Context m)))
-> Maybe (Context m) -> m (Maybe (Context m))
forall a b. (a -> b) -> a -> b
$
if Bool
actuallyReleased
then Context m -> Maybe (Context m)
forall a. a -> Maybe a
Just (Resource m -> Context m
forall (m :: * -> *). Resource m -> Context m
resourceContext Resource m
resource)
else Maybe (Context m)
forall a. Maybe a
Nothing
releaseAll :: (IOLike m, HasCallStack) => ResourceRegistry m -> m ()
releaseAll :: ResourceRegistry m -> m ()
releaseAll ResourceRegistry m
rr = do
Context m
context <- m (Context m)
forall (m :: * -> *). (IOLike m, HasCallStack) => m (Context m)
captureContext
Bool -> m () -> m ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (Context m -> ThreadId m
forall (m :: * -> *). Context m -> ThreadId m
contextThreadId Context m
context ThreadId m -> ThreadId m -> Bool
forall a. Eq a => a -> a -> Bool
== Context m -> ThreadId m
forall (m :: * -> *). Context m -> ThreadId m
contextThreadId (ResourceRegistry m -> Context m
forall (m :: * -> *). ResourceRegistry m -> Context m
registryContext ResourceRegistry m
rr)) (m () -> m ()) -> m () -> m ()
forall a b. (a -> b) -> a -> b
$
ResourceRegistryThreadException -> m ()
forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwIO (ResourceRegistryThreadException -> m ())
-> ResourceRegistryThreadException -> m ()
forall a b. (a -> b) -> a -> b
$ ResourceRegistryClosedFromWrongThread :: forall (m :: * -> *).
IOLike m =>
Context m -> Context m -> ResourceRegistryThreadException
ResourceRegistryClosedFromWrongThread {
resourceRegistryCreatedIn :: Context m
resourceRegistryCreatedIn = ResourceRegistry m -> Context m
forall (m :: * -> *). ResourceRegistry m -> Context m
registryContext ResourceRegistry m
rr
, resourceRegistryUsedIn :: Context m
resourceRegistryUsedIn = Context m
context
}
m [Context m] -> m ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (m [Context m] -> m ()) -> m [Context m] -> m ()
forall a b. (a -> b) -> a -> b
$ ResourceRegistry m
-> Context m
-> (ResourceKey m -> m (Maybe (Context m)))
-> m [Context m]
forall (m :: * -> *).
IOLike m =>
ResourceRegistry m
-> Context m
-> (ResourceKey m -> m (Maybe (Context m)))
-> m [Context m]
releaseAllHelper ResourceRegistry m
rr Context m
context ResourceKey m -> m (Maybe (Context m))
forall (m :: * -> *).
(IOLike m, HasCallStack) =>
ResourceKey m -> m (Maybe (Context m))
release
unsafeReleaseAll :: (IOLike m, HasCallStack) => ResourceRegistry m -> m ()
unsafeReleaseAll :: ResourceRegistry m -> m ()
unsafeReleaseAll ResourceRegistry m
rr = do
Context m
context <- m (Context m)
forall (m :: * -> *). (IOLike m, HasCallStack) => m (Context m)
captureContext
m [Context m] -> m ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (m [Context m] -> m ()) -> m [Context m] -> m ()
forall a b. (a -> b) -> a -> b
$ ResourceRegistry m
-> Context m
-> (ResourceKey m -> m (Maybe (Context m)))
-> m [Context m]
forall (m :: * -> *).
IOLike m =>
ResourceRegistry m
-> Context m
-> (ResourceKey m -> m (Maybe (Context m)))
-> m [Context m]
releaseAllHelper ResourceRegistry m
rr Context m
context ResourceKey m -> m (Maybe (Context m))
forall (m :: * -> *).
IOLike m =>
ResourceKey m -> m (Maybe (Context m))
unsafeRelease
releaseAllHelper :: IOLike m
=> ResourceRegistry m
-> Context m
-> (ResourceKey m -> m (Maybe (Context m)))
-> m [Context m]
releaseAllHelper :: ResourceRegistry m
-> Context m
-> (ResourceKey m -> m (Maybe (Context m)))
-> m [Context m]
releaseAllHelper ResourceRegistry m
rr Context m
context ResourceKey m -> m (Maybe (Context m))
releaser = m [Context m] -> m [Context m]
forall (m :: * -> *) a. MonadMask m => m a -> m a
mask_ (m [Context m] -> m [Context m]) -> m [Context m] -> m [Context m]
forall a b. (a -> b) -> a -> b
$ do
Either PrettyCallStack (Set ResourceId)
mKeys <- ResourceRegistry m
-> State
(RegistryState m) (Either PrettyCallStack (Set ResourceId))
-> m (Either PrettyCallStack (Set ResourceId))
forall (m :: * -> *) a.
IOLike m =>
ResourceRegistry m -> State (RegistryState m) a -> m a
updateState ResourceRegistry m
rr (State (RegistryState m) (Either PrettyCallStack (Set ResourceId))
-> m (Either PrettyCallStack (Set ResourceId)))
-> State
(RegistryState m) (Either PrettyCallStack (Set ResourceId))
-> m (Either PrettyCallStack (Set ResourceId))
forall a b. (a -> b) -> a -> b
$ State (RegistryState m) (Set ResourceId)
-> State
(RegistryState m) (Either PrettyCallStack (Set ResourceId))
forall (m :: * -> *) a.
State (RegistryState m) a
-> State (RegistryState m) (Either PrettyCallStack a)
unlessClosed (State (RegistryState m) (Set ResourceId)
-> State
(RegistryState m) (Either PrettyCallStack (Set ResourceId)))
-> State (RegistryState m) (Set ResourceId)
-> State
(RegistryState m) (Either PrettyCallStack (Set ResourceId))
forall a b. (a -> b) -> a -> b
$
(RegistryState m -> Set ResourceId)
-> State (RegistryState m) (Set ResourceId)
forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
gets ((RegistryState m -> Set ResourceId)
-> State (RegistryState m) (Set ResourceId))
-> (RegistryState m -> Set ResourceId)
-> State (RegistryState m) (Set ResourceId)
forall a b. (a -> b) -> a -> b
$ Map ResourceId (Resource m) -> Set ResourceId
forall k a. Map k a -> Set k
Map.keysSet (Map ResourceId (Resource m) -> Set ResourceId)
-> (RegistryState m -> Map ResourceId (Resource m))
-> RegistryState m
-> Set ResourceId
forall b c a. (b -> c) -> (a -> b) -> a -> c
. RegistryState m -> Map ResourceId (Resource m)
forall (m :: * -> *).
RegistryState m -> Map ResourceId (Resource m)
registryResources
case Either PrettyCallStack (Set ResourceId)
mKeys of
Left PrettyCallStack
closed -> ResourceRegistry m -> Context m -> PrettyCallStack -> m [Context m]
forall (m :: * -> *) x.
IOLike m =>
ResourceRegistry m -> Context m -> PrettyCallStack -> m x
throwRegistryClosed ResourceRegistry m
rr Context m
context PrettyCallStack
closed
Right Set ResourceId
keys -> ResourceRegistry m
-> Set ResourceId
-> (ResourceKey m -> m (Maybe (Context m)))
-> m [Context m]
forall (m :: * -> *).
IOLike m =>
ResourceRegistry m
-> Set ResourceId
-> (ResourceKey m -> m (Maybe (Context m)))
-> m [Context m]
releaseResources ResourceRegistry m
rr Set ResourceId
keys ResourceKey m -> m (Maybe (Context m))
releaser
data Thread m a = IOLike m => Thread {
Thread m a -> ThreadId m
threadId :: !(ThreadId m)
, Thread m a -> ResourceId
threadResourceId :: !ResourceId
, Thread m a -> Async m a
threadAsync :: !(Async m a)
, Thread m a -> ResourceRegistry m
threadRegistry :: !(ResourceRegistry m)
}
deriving Context -> Thread m a -> IO (Maybe ThunkInfo)
Proxy (Thread m a) -> String
(Context -> Thread m a -> IO (Maybe ThunkInfo))
-> (Context -> Thread m a -> IO (Maybe ThunkInfo))
-> (Proxy (Thread m a) -> String)
-> NoThunks (Thread m a)
forall a.
(Context -> a -> IO (Maybe ThunkInfo))
-> (Context -> a -> IO (Maybe ThunkInfo))
-> (Proxy a -> String)
-> NoThunks a
forall (m :: * -> *) a.
Context -> Thread m a -> IO (Maybe ThunkInfo)
forall (m :: * -> *) a. Proxy (Thread m a) -> String
showTypeOf :: Proxy (Thread m a) -> String
$cshowTypeOf :: forall (m :: * -> *) a. Proxy (Thread m a) -> String
wNoThunks :: Context -> Thread m a -> IO (Maybe ThunkInfo)
$cwNoThunks :: forall (m :: * -> *) a.
Context -> Thread m a -> IO (Maybe ThunkInfo)
noThunks :: Context -> Thread m a -> IO (Maybe ThunkInfo)
$cnoThunks :: forall (m :: * -> *) a.
Context -> Thread m a -> IO (Maybe ThunkInfo)
NoThunks via OnlyCheckWhnfNamed "Thread" (Thread m a)
instance Eq (Thread m a) where
Thread{threadId :: forall (m :: * -> *) a. Thread m a -> ThreadId m
threadId = ThreadId m
a} == :: Thread m a -> Thread m a -> Bool
== Thread{threadId :: forall (m :: * -> *) a. Thread m a -> ThreadId m
threadId = ThreadId m
b} = ThreadId m
a ThreadId m -> ThreadId m -> Bool
forall a. Eq a => a -> a -> Bool
== ThreadId m
b
cancelThread :: IOLike m => Thread m a -> m ()
cancelThread :: Thread m a -> m ()
cancelThread = Async m a -> m ()
forall (m :: * -> *) a. MonadAsync m => Async m a -> m ()
uninterruptibleCancel (Async m a -> m ())
-> (Thread m a -> Async m a) -> Thread m a -> m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Thread m a -> Async m a
forall (m :: * -> *) a. Thread m a -> Async m a
threadAsync
waitThread :: IOLike m => Thread m a -> m a
waitThread :: Thread m a -> m a
waitThread = Async m a -> m a
forall (m :: * -> *) a. MonadAsync m => Async m a -> m a
wait (Async m a -> m a)
-> (Thread m a -> Async m a) -> Thread m a -> m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Thread m a -> Async m a
forall (m :: * -> *) a. Thread m a -> Async m a
threadAsync
waitAnyThread :: forall m a. IOLike m => [Thread m a] -> m a
waitAnyThread :: [Thread m a] -> m a
waitAnyThread [Thread m a]
ts = (Async m a, a) -> a
forall a b. (a, b) -> b
snd ((Async m a, a) -> a) -> m (Async m a, a) -> m a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Async m a] -> m (Async m a, a)
forall (m :: * -> *) a.
MonadAsync m =>
[Async m a] -> m (Async m a, a)
waitAny ((Thread m a -> Async m a) -> [Thread m a] -> [Async m a]
forall a b. (a -> b) -> [a] -> [b]
map Thread m a -> Async m a
forall (m :: * -> *) a. Thread m a -> Async m a
threadAsync [Thread m a]
ts)
forkThread :: forall m a. (IOLike m, HasCallStack)
=> ResourceRegistry m
-> String
-> m a
-> m (Thread m a)
forkThread :: ResourceRegistry m -> String -> m a -> m (Thread m a)
forkThread ResourceRegistry m
rr String
label m a
body = (ResourceKey m, Thread m a) -> Thread m a
forall a b. (a, b) -> b
snd ((ResourceKey m, Thread m a) -> Thread m a)
-> m (ResourceKey m, Thread m a) -> m (Thread m a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
ResourceRegistry m
-> (ResourceId -> m (Thread m a))
-> (Thread m a -> m ())
-> m (ResourceKey m, Thread m a)
forall (m :: * -> *) a.
(IOLike m, HasCallStack) =>
ResourceRegistry m
-> (ResourceId -> m a) -> (a -> m ()) -> m (ResourceKey m, a)
allocate ResourceRegistry m
rr (\ResourceId
key -> ResourceId -> Async m a -> Thread m a
mkThread ResourceId
key (Async m a -> Thread m a) -> m (Async m a) -> m (Thread m a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> m a -> m (Async m a)
forall (m :: * -> *) a. MonadAsync m => m a -> m (Async m a)
async (ResourceId -> m a
body' ResourceId
key)) Thread m a -> m ()
forall (m :: * -> *) a. IOLike m => Thread m a -> m ()
cancelThread
where
mkThread :: ResourceId -> Async m a -> Thread m a
mkThread :: ResourceId -> Async m a -> Thread m a
mkThread ResourceId
rid Async m a
child = Thread :: forall (m :: * -> *) a.
IOLike m =>
ThreadId m
-> ResourceId -> Async m a -> ResourceRegistry m -> Thread m a
Thread {
threadId :: ThreadId m
threadId = Proxy m -> Async m a -> ThreadId m
forall (m :: * -> *) a.
MonadAsync m =>
Proxy m -> Async m a -> ThreadId m
asyncThreadId (Proxy m
forall k (t :: k). Proxy t
Proxy @m) Async m a
child
, threadResourceId :: ResourceId
threadResourceId = ResourceId
rid
, threadAsync :: Async m a
threadAsync = Async m a
child
, threadRegistry :: ResourceRegistry m
threadRegistry = ResourceRegistry m
rr
}
body' :: ResourceId -> m a
body' :: ResourceId -> m a
body' ResourceId
rid = do
ThreadId m
me <- m (ThreadId m)
forall (m :: * -> *). MonadThread m => m (ThreadId m)
myThreadId
ThreadId m -> String -> m ()
forall (m :: * -> *). MonadThread m => ThreadId m -> String -> m ()
labelThread ThreadId m
me String
label
(ThreadId m -> m ()
registerThread ThreadId m
me m () -> m a -> m a
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> m a
body) m a -> m () -> m a
forall (m :: * -> *) a b. MonadThrow m => m a -> m b -> m a
`finally` ThreadId m -> ResourceId -> m ()
unregisterThread ThreadId m
me ResourceId
rid
registerThread :: ThreadId m -> m ()
registerThread :: ThreadId m -> m ()
registerThread ThreadId m
tid = ResourceRegistry m -> State (RegistryState m) () -> m ()
forall (m :: * -> *) a.
IOLike m =>
ResourceRegistry m -> State (RegistryState m) a -> m a
updateState ResourceRegistry m
rr (State (RegistryState m) () -> m ())
-> State (RegistryState m) () -> m ()
forall a b. (a -> b) -> a -> b
$ ThreadId m -> State (RegistryState m) ()
forall (m :: * -> *).
IOLike m =>
ThreadId m -> State (RegistryState m) ()
insertThread ThreadId m
tid
unregisterThread :: ThreadId m -> ResourceId -> m ()
unregisterThread :: ThreadId m -> ResourceId -> m ()
unregisterThread ThreadId m
tid ResourceId
rid =
ResourceRegistry m -> State (RegistryState m) () -> m ()
forall (m :: * -> *) a.
IOLike m =>
ResourceRegistry m -> State (RegistryState m) a -> m a
updateState ResourceRegistry m
rr (State (RegistryState m) () -> m ())
-> State (RegistryState m) () -> m ()
forall a b. (a -> b) -> a -> b
$ do
ThreadId m -> State (RegistryState m) ()
forall (m :: * -> *).
IOLike m =>
ThreadId m -> State (RegistryState m) ()
removeThread ThreadId m
tid
StateT (RegistryState m) Identity (Maybe (Resource m))
-> State (RegistryState m) ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (StateT (RegistryState m) Identity (Maybe (Resource m))
-> State (RegistryState m) ())
-> StateT (RegistryState m) Identity (Maybe (Resource m))
-> State (RegistryState m) ()
forall a b. (a -> b) -> a -> b
$ ResourceId
-> StateT (RegistryState m) Identity (Maybe (Resource m))
forall (m :: * -> *).
ResourceId -> State (RegistryState m) (Maybe (Resource m))
removeResource ResourceId
rid
withThread :: IOLike m
=> ResourceRegistry m
-> String
-> m a
-> (Thread m a -> m b)
-> m b
withThread :: ResourceRegistry m -> String -> m a -> (Thread m a -> m b) -> m b
withThread ResourceRegistry m
rr String
label m a
body = m (Thread m a)
-> (Thread m a -> m ()) -> (Thread m a -> m b) -> m b
forall (m :: * -> *) a b c.
MonadThrow m =>
m a -> (a -> m b) -> (a -> m c) -> m c
bracket (ResourceRegistry m -> String -> m a -> m (Thread m a)
forall (m :: * -> *) a.
(IOLike m, HasCallStack) =>
ResourceRegistry m -> String -> m a -> m (Thread m a)
forkThread ResourceRegistry m
rr String
label m a
body) Thread m a -> m ()
forall (m :: * -> *) a. IOLike m => Thread m a -> m ()
cancelThread
linkToRegistry :: IOLike m => Thread m a -> m ()
linkToRegistry :: Thread m a -> m ()
linkToRegistry Thread m a
t = ThreadId m -> Async m a -> m ()
forall (m :: * -> *) a.
(MonadAsync m, MonadFork m, MonadMask m) =>
ThreadId m -> Async m a -> m ()
linkTo (ResourceRegistry m -> ThreadId m
forall (m :: * -> *). ResourceRegistry m -> ThreadId m
registryThread (ResourceRegistry m -> ThreadId m)
-> ResourceRegistry m -> ThreadId m
forall a b. (a -> b) -> a -> b
$ Thread m a -> ResourceRegistry m
forall (m :: * -> *) a. Thread m a -> ResourceRegistry m
threadRegistry Thread m a
t) (Thread m a -> Async m a
forall (m :: * -> *) a. Thread m a -> Async m a
threadAsync Thread m a
t)
forkLinkedThread :: (IOLike m, HasCallStack)
=> ResourceRegistry m
-> String
-> m a
-> m (Thread m a)
forkLinkedThread :: ResourceRegistry m -> String -> m a -> m (Thread m a)
forkLinkedThread ResourceRegistry m
rr String
label m a
body = do
Thread m a
t <- ResourceRegistry m -> String -> m a -> m (Thread m a)
forall (m :: * -> *) a.
(IOLike m, HasCallStack) =>
ResourceRegistry m -> String -> m a -> m (Thread m a)
forkThread ResourceRegistry m
rr String
label m a
body
Thread m a -> m ()
forall (m :: * -> *) a. IOLike m => Thread m a -> m ()
linkToRegistry Thread m a
t
Thread m a -> m (Thread m a)
forall (m :: * -> *) a. Monad m => a -> m a
return Thread m a
t
ensureKnownThread :: forall m. IOLike m
=> ResourceRegistry m -> Context m -> m ()
ensureKnownThread :: ResourceRegistry m -> Context m -> m ()
ensureKnownThread ResourceRegistry m
rr Context m
context = do
Bool
isKnown <- m Bool
checkIsKnown
Bool -> m () -> m ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless Bool
isKnown (m () -> m ()) -> m () -> m ()
forall a b. (a -> b) -> a -> b
$
ResourceRegistryThreadException -> m ()
forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwIO (ResourceRegistryThreadException -> m ())
-> ResourceRegistryThreadException -> m ()
forall a b. (a -> b) -> a -> b
$ ResourceRegistryUsedFromUntrackedThread :: forall (m :: * -> *).
IOLike m =>
Context m -> Context m -> ResourceRegistryThreadException
ResourceRegistryUsedFromUntrackedThread {
resourceRegistryCreatedIn :: Context m
resourceRegistryCreatedIn = ResourceRegistry m -> Context m
forall (m :: * -> *). ResourceRegistry m -> Context m
registryContext ResourceRegistry m
rr
, resourceRegistryUsedIn :: Context m
resourceRegistryUsedIn = Context m
context
}
where
checkIsKnown :: m Bool
checkIsKnown :: m Bool
checkIsKnown
| Context m -> ThreadId m
forall (m :: * -> *). Context m -> ThreadId m
contextThreadId Context m
context ThreadId m -> ThreadId m -> Bool
forall a. Eq a => a -> a -> Bool
== Context m -> ThreadId m
forall (m :: * -> *). Context m -> ThreadId m
contextThreadId (ResourceRegistry m -> Context m
forall (m :: * -> *). ResourceRegistry m -> Context m
registryContext ResourceRegistry m
rr) =
Bool -> m Bool
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
True
| Bool
otherwise = STM m Bool -> m Bool
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
STM m a -> m a
atomically (STM m Bool -> m Bool) -> STM m Bool -> m Bool
forall a b. (a -> b) -> a -> b
$ do
KnownThreads Set (ThreadId m)
ts <- RegistryState m -> KnownThreads m
forall (m :: * -> *). RegistryState m -> KnownThreads m
registryThreads (RegistryState m -> KnownThreads m)
-> STM m (RegistryState m) -> STM m (KnownThreads m)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> StrictTVar m (RegistryState m) -> STM m (RegistryState m)
forall (m :: * -> *) a. MonadSTM m => StrictTVar m a -> STM m a
readTVar (ResourceRegistry m -> StrictTVar m (RegistryState m)
forall (m :: * -> *).
ResourceRegistry m -> StrictTVar m (RegistryState m)
registryState ResourceRegistry m
rr)
Bool -> STM m Bool
forall (m :: * -> *) a. Monad m => a -> m a
return (Bool -> STM m Bool) -> Bool -> STM m Bool
forall a b. (a -> b) -> a -> b
$ Context m -> ThreadId m
forall (m :: * -> *). Context m -> ThreadId m
contextThreadId Context m
context ThreadId m -> Set (ThreadId m) -> Bool
forall a. Ord a => a -> Set a -> Bool
`Set.member` Set (ThreadId m)
ts
data ResourceRegistryThreadException =
forall m. IOLike m => ResourceRegistryUsedFromUntrackedThread {
()
resourceRegistryCreatedIn :: !(Context m)
, ()
resourceRegistryUsedIn :: !(Context m)
}
| forall m. IOLike m => ResourceRegistryClosedFromWrongThread {
resourceRegistryCreatedIn :: !(Context m)
, resourceRegistryUsedIn :: !(Context m)
}
deriving instance Show ResourceRegistryThreadException
instance Exception ResourceRegistryThreadException
data Context m = IOLike m => Context {
Context m -> PrettyCallStack
contextCallStack :: !PrettyCallStack
, Context m -> ThreadId m
contextThreadId :: !(ThreadId m)
}
instance NoThunks (Context m) where
showTypeOf :: Proxy (Context m) -> String
showTypeOf Proxy (Context m)
_ = String
"Context"
wNoThunks :: Context -> Context m -> IO (Maybe ThunkInfo)
wNoThunks Context
ctxt (Context PrettyCallStack
cs ThreadId m
tid) = [IO (Maybe ThunkInfo)] -> IO (Maybe ThunkInfo)
allNoThunks
[ Context -> PrettyCallStack -> IO (Maybe ThunkInfo)
forall a. NoThunks a => Context -> a -> IO (Maybe ThunkInfo)
noThunks Context
ctxt PrettyCallStack
cs
, Context
-> InspectHeapNamed "ThreadId" (ThreadId m) -> IO (Maybe ThunkInfo)
forall a. NoThunks a => Context -> a -> IO (Maybe ThunkInfo)
noThunks Context
ctxt (ThreadId m -> InspectHeapNamed "ThreadId" (ThreadId m)
forall (name :: Symbol) a. a -> InspectHeapNamed name a
InspectHeapNamed @"ThreadId" ThreadId m
tid)
]
deriving instance Show (Context m)
captureContext :: IOLike m => HasCallStack => m (Context m)
captureContext :: m (Context m)
captureContext = PrettyCallStack -> ThreadId m -> Context m
forall (m :: * -> *).
IOLike m =>
PrettyCallStack -> ThreadId m -> Context m
Context PrettyCallStack
HasCallStack => PrettyCallStack
prettyCallStack (ThreadId m -> Context m) -> m (ThreadId m) -> m (Context m)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> m (ThreadId m)
forall (m :: * -> *). MonadThread m => m (ThreadId m)
myThreadId