{-# 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 (
RegistryClosedException (..)
, ResourceRegistryThreadException
, bracketWithPrivateRegistry
, registryThread
, withRegistry
, ResourceKey
, allocate
, allocateEither
, release
, releaseAll
, unsafeRelease
, unsafeReleaseAll
, cancelThread
, forkLinkedThread
, forkThread
, linkToRegistry
, threadId
, waitAnyThread
, waitThread
, withThread
, Thread
, TempRegistryException (..)
, allocateTemp
, modifyWithTempRegistry
, runInnerWithTempRegistry
, runWithTempRegistry
, WithTempRegistry
, closeRegistry
, countResources
, unsafeNewRegistry
, ResourceRegistry
) 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.Bimap (Bimap)
import qualified Data.Bimap as Bimap
import Data.Either (partitionEithers)
import Data.Map.Strict (Map)
import qualified Data.Map.Strict as Map
import Data.Maybe (catMaybes, listToMaybe)
import Data.Set (Set)
import qualified Data.Set as Set
import Data.Word (Word64)
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)
newtype Age = Age Word64
deriving stock (Int -> Age -> ShowS
[Age] -> ShowS
Age -> String
(Int -> Age -> ShowS)
-> (Age -> String) -> ([Age] -> ShowS) -> Show Age
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Age] -> ShowS
$cshowList :: [Age] -> ShowS
show :: Age -> String
$cshow :: Age -> String
showsPrec :: Int -> Age -> ShowS
$cshowsPrec :: Int -> Age -> ShowS
Show)
deriving newtype (Age -> Age -> Bool
(Age -> Age -> Bool) -> (Age -> Age -> Bool) -> Eq Age
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Age -> Age -> Bool
$c/= :: Age -> Age -> Bool
== :: Age -> Age -> Bool
$c== :: Age -> Age -> Bool
Eq, Eq Age
Eq Age
-> (Age -> Age -> Ordering)
-> (Age -> Age -> Bool)
-> (Age -> Age -> Bool)
-> (Age -> Age -> Bool)
-> (Age -> Age -> Bool)
-> (Age -> Age -> Age)
-> (Age -> Age -> Age)
-> Ord Age
Age -> Age -> Bool
Age -> Age -> Ordering
Age -> Age -> Age
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 :: Age -> Age -> Age
$cmin :: Age -> Age -> Age
max :: Age -> Age -> Age
$cmax :: Age -> Age -> Age
>= :: Age -> Age -> Bool
$c>= :: Age -> Age -> Bool
> :: Age -> Age -> Bool
$c> :: Age -> Age -> Bool
<= :: Age -> Age -> Bool
$c<= :: Age -> Age -> Bool
< :: Age -> Age -> Bool
$c< :: Age -> Age -> Bool
compare :: Age -> Age -> Ordering
$ccompare :: Age -> Age -> Ordering
$cp1Ord :: Eq Age
Ord)
deriving Context -> Age -> IO (Maybe ThunkInfo)
Proxy Age -> String
(Context -> Age -> IO (Maybe ThunkInfo))
-> (Context -> Age -> IO (Maybe ThunkInfo))
-> (Proxy Age -> String)
-> NoThunks Age
forall a.
(Context -> a -> IO (Maybe ThunkInfo))
-> (Context -> a -> IO (Maybe ThunkInfo))
-> (Proxy a -> String)
-> NoThunks a
showTypeOf :: Proxy Age -> String
$cshowTypeOf :: Proxy Age -> String
wNoThunks :: Context -> Age -> IO (Maybe ThunkInfo)
$cwNoThunks :: Context -> Age -> IO (Maybe ThunkInfo)
noThunks :: Context -> Age -> IO (Maybe ThunkInfo)
$cnoThunks :: Context -> Age -> IO (Maybe ThunkInfo)
NoThunks via InspectHeapNamed "Age" Age
ageOfFirstResource :: Age
ageOfFirstResource :: Age
ageOfFirstResource = Word64 -> Age
Age Word64
forall a. Bounded a => a
maxBound
nextYoungerAge :: Age -> Age
nextYoungerAge :: Age -> Age
nextYoungerAge (Age Word64
n) = Word64 -> Age
Age (Word64
n Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
- Word64
1)
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 -> Bimap ResourceId Age
registryAges :: !(Bimap ResourceId Age)
, RegistryState m -> Age
registryNextAge :: !Age
, 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)
getYoungestToOldest :: RegistryState m -> [ResourceId]
getYoungestToOldest :: RegistryState m -> [ResourceId]
getYoungestToOldest = ((Age, ResourceId) -> ResourceId)
-> [(Age, ResourceId)] -> [ResourceId]
forall a b. (a -> b) -> [a] -> [b]
map (Age, ResourceId) -> ResourceId
forall a b. (a, b) -> b
snd ([(Age, ResourceId)] -> [ResourceId])
-> (RegistryState m -> [(Age, ResourceId)])
-> RegistryState m
-> [ResourceId]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Bimap ResourceId Age -> [(Age, ResourceId)]
forall a b. Bimap a b -> [(b, a)]
Bimap.toAscListR (Bimap ResourceId Age -> [(Age, ResourceId)])
-> (RegistryState m -> Bimap ResourceId Age)
-> RegistryState m
-> [(Age, ResourceId)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. RegistryState m -> Bimap ResourceId Age
forall (m :: * -> *). RegistryState m -> Bimap ResourceId Age
registryAges
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)
, registryAges :: Bimap ResourceId Age
registryAges = ResourceId -> Age -> Bimap ResourceId Age -> Bimap ResourceId Age
forall a b. (Ord a, Ord b) => a -> b -> Bimap a b -> Bimap a b
Bimap.insert
ResourceId
key
(RegistryState m -> Age
forall (m :: * -> *). RegistryState m -> Age
registryNextAge RegistryState m
st)
(RegistryState m -> Bimap ResourceId Age
forall (m :: * -> *). RegistryState m -> Bimap ResourceId Age
registryAges RegistryState m
st)
, registryNextAge :: Age
registryNextAge = Age -> Age
nextYoungerAge (RegistryState m -> Age
forall (m :: * -> *). RegistryState m -> Age
registryNextAge 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 ->
let (Maybe (Resource m)
mbResource, Map ResourceId (Resource m)
resources') = (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
(RegistryState m -> Map ResourceId (Resource m)
forall (m :: * -> *).
RegistryState m -> Map ResourceId (Resource m)
registryResources RegistryState m
st)
st' :: RegistryState m
st' = RegistryState m
st {
registryResources :: Map ResourceId (Resource m)
registryResources = Map ResourceId (Resource m)
resources'
, registryAges :: Bimap ResourceId Age
registryAges = ResourceId -> Bimap ResourceId Age -> Bimap ResourceId Age
forall a b. (Ord a, Ord b) => a -> Bimap a b -> Bimap a b
Bimap.delete ResourceId
key (RegistryState m -> Bimap ResourceId Age
forall (m :: * -> *). RegistryState m -> Bimap ResourceId Age
registryAges RegistryState m
st)
}
in (Maybe (Resource m)
mbResource, 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 [ResourceId])
close :: PrettyCallStack
-> State (RegistryState m) (Either PrettyCallStack [ResourceId])
close PrettyCallStack
closeCallStack = 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
(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 -> [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]
getYoungestToOldest
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 -> (a, RegistryState m)) -> STM m a
forall (m :: * -> *) s a.
MonadSTM m =>
StrictTVar m s -> (s -> (a, s)) -> STM m a
stateTVar (ResourceRegistry m -> StrictTVar m (RegistryState m)
forall (m :: * -> *).
ResourceRegistry m -> StrictTVar m (RegistryState m)
registryState ResourceRegistry m
rr) (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
-> Bimap ResourceId Age
-> Age
-> 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
, registryAges :: Bimap ResourceId Age
registryAges = Bimap ResourceId Age
forall a b. Bimap a b
Bimap.empty
, registryNextAge :: Age
registryNextAge = Age
ageOfFirstResource
, 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 [ResourceId]
alreadyClosed <- 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
$ PrettyCallStack
-> State (RegistryState m) (Either PrettyCallStack [ResourceId])
forall (m :: * -> *).
PrettyCallStack
-> State (RegistryState m) (Either PrettyCallStack [ResourceId])
close (Context m -> PrettyCallStack
forall (m :: * -> *). Context m -> PrettyCallStack
contextCallStack Context m
context)
case Either PrettyCallStack [ResourceId]
alreadyClosed of
Left PrettyCallStack
_ ->
() -> m ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
Right [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
-> [ResourceId]
-> (ResourceKey m -> m (Maybe (Context m)))
-> m [Context m]
forall (m :: * -> *).
IOLike m =>
ResourceRegistry m
-> [ResourceId]
-> (ResourceKey m -> m (Maybe (Context m)))
-> m [Context m]
releaseResources ResourceRegistry m
rr [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
-> [ResourceId]
-> (ResourceKey m -> m (Maybe (Context m)))
-> m [Context m]
releaseResources :: ResourceRegistry m
-> [ResourceId]
-> (ResourceKey m -> m (Maybe (Context m)))
-> m [Context m]
releaseResources ResourceRegistry m
rr [ResourceId]
sortedKeys 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 [ResourceId]
sortedKeys ((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
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
bracketWithPrivateRegistry :: (IOLike m, HasCallStack)
=> (ResourceRegistry m -> m a)
-> (a -> m ())
-> (a -> m r)
-> m r
bracketWithPrivateRegistry :: (ResourceRegistry m -> m a) -> (a -> m ()) -> (a -> m r) -> m r
bracketWithPrivateRegistry ResourceRegistry m -> m a
newA a -> m ()
closeA a -> m r
body =
(ResourceRegistry m -> m r) -> m r
forall (m :: * -> *) a.
(IOLike m, HasCallStack) =>
(ResourceRegistry m -> m a) -> m a
withRegistry ((ResourceRegistry m -> m r) -> m r)
-> (ResourceRegistry m -> m r) -> m r
forall a b. (a -> b) -> a -> b
$ \ResourceRegistry m
registry -> do
(ResourceKey m
_key, a
a) <- ResourceRegistry m
-> (ResourceId -> m a) -> (a -> m ()) -> m (ResourceKey m, a)
forall (m :: * -> *) a.
(IOLike m, HasCallStack) =>
ResourceRegistry m
-> (ResourceId -> m a) -> (a -> m ()) -> m (ResourceKey m, a)
allocate ResourceRegistry m
registry (\ResourceId
_key -> ResourceRegistry m -> m a
newA ResourceRegistry m
registry) a -> m ()
closeA
a -> m r
body a
a
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
runInnerWithTempRegistry
:: forall innerSt st m res a. IOLike m
=> WithTempRegistry innerSt m (a, innerSt, res)
-> (res -> m Bool)
-> (st -> res -> Bool)
-> WithTempRegistry st m a
runInnerWithTempRegistry :: WithTempRegistry innerSt m (a, innerSt, res)
-> (res -> m Bool)
-> (st -> res -> Bool)
-> WithTempRegistry st m a
runInnerWithTempRegistry WithTempRegistry innerSt m (a, innerSt, res)
inner res -> m Bool
free st -> res -> Bool
isTransferred = do
TempRegistry st m
outerTR <- ReaderT (TempRegistry st m) m (TempRegistry st m)
-> WithTempRegistry st m (TempRegistry st m)
forall st (m :: * -> *) a.
ReaderT (TempRegistry st m) m a -> WithTempRegistry st m a
WithTempRegistry ReaderT (TempRegistry st m) m (TempRegistry st m)
forall r (m :: * -> *). MonadReader r m => m r
ask
m a -> WithTempRegistry st m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m a -> WithTempRegistry st m a) -> m a -> WithTempRegistry st m a
forall a b. (a -> b) -> a -> b
$ WithTempRegistry innerSt m (a, innerSt) -> m a
forall (m :: * -> *) st a.
(IOLike m, HasCallStack) =>
WithTempRegistry st m (a, st) -> m a
runWithTempRegistry (WithTempRegistry innerSt m (a, innerSt) -> m a)
-> WithTempRegistry innerSt m (a, innerSt) -> m a
forall a b. (a -> b) -> a -> b
$ do
(a
a, innerSt
innerSt, res
res) <- WithTempRegistry innerSt m (a, innerSt, res)
inner
res
_ <- TempRegistry st m
-> WithTempRegistry st m res -> WithTempRegistry innerSt m res
withFixedTempRegistry TempRegistry st m
outerTR
(WithTempRegistry st m res -> WithTempRegistry innerSt m res)
-> WithTempRegistry st m res -> WithTempRegistry innerSt m res
forall a b. (a -> b) -> a -> b
$ m res
-> (res -> m Bool)
-> (st -> res -> Bool)
-> WithTempRegistry st m res
forall (m :: * -> *) a st.
(IOLike m, HasCallStack) =>
m a
-> (a -> m Bool) -> (st -> a -> Bool) -> WithTempRegistry st m a
allocateTemp (res -> m res
forall (m :: * -> *) a. Monad m => a -> m a
return res
res) res -> m Bool
free st -> res -> Bool
isTransferred
(a, innerSt) -> WithTempRegistry innerSt m (a, innerSt)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (a
a, innerSt
innerSt)
where
withFixedTempRegistry
:: TempRegistry st m
-> WithTempRegistry st m res
-> WithTempRegistry innerSt m res
withFixedTempRegistry :: TempRegistry st m
-> WithTempRegistry st m res -> WithTempRegistry innerSt m res
withFixedTempRegistry TempRegistry st m
env (WithTempRegistry (ReaderT TempRegistry st m -> m res
f)) =
ReaderT (TempRegistry innerSt m) m res
-> WithTempRegistry innerSt m res
forall st (m :: * -> *) a.
ReaderT (TempRegistry st m) m a -> WithTempRegistry st m a
WithTempRegistry (ReaderT (TempRegistry innerSt m) m res
-> WithTempRegistry innerSt m res)
-> ReaderT (TempRegistry innerSt m) m res
-> WithTempRegistry innerSt m res
forall a b. (a -> b) -> a -> b
$ (TempRegistry innerSt m -> m res)
-> ReaderT (TempRegistry innerSt m) m res
forall r (m :: * -> *) a. (r -> m a) -> ReaderT r m a
ReaderT ((TempRegistry innerSt m -> m res)
-> ReaderT (TempRegistry innerSt m) m res)
-> (TempRegistry innerSt m -> m res)
-> ReaderT (TempRegistry innerSt m) m res
forall a b. (a -> b) -> a -> b
$ \TempRegistry innerSt m
_ -> TempRegistry st m -> m res
f TempRegistry st m
env
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)
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
m () -> ReaderT (TempRegistry st m) m ()
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m () -> ReaderT (TempRegistry st m) m ())
-> m () -> ReaderT (TempRegistry st m) m ()
forall a b. (a -> b) -> a -> b
$ STM m () -> m ()
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
STM m a -> m a
atomically (STM m () -> m ()) -> STM 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 [ResourceId]
mKeys <- 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) [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
$ (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]
getYoungestToOldest
case Either PrettyCallStack [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 [ResourceId]
keys -> ResourceRegistry m
-> [ResourceId]
-> (ResourceKey m -> m (Maybe (Context m)))
-> m [Context m]
forall (m :: * -> *).
IOLike m =>
ResourceRegistry m
-> [ResourceId]
-> (ResourceKey m -> m (Maybe (Context m)))
-> m [Context m]
releaseResources ResourceRegistry m
rr [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 = Async m a -> ThreadId m
forall (m :: * -> *) a. MonadAsync m => Async m a -> ThreadId m
asyncThreadId 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