{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE DerivingVia #-}
{-# LANGUAGE ExistentialQuantification #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE QuantifiedConstraints #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE UndecidableInstances #-}
{-# OPTIONS_GHC -Wno-orphans #-}
module Control.ResourceRegistry
(
Context
, ResourceId
, ResourceRegistry
, RegistryClosedException (..)
, ResourceRegistryThreadException
, bracketWithPrivateRegistry
, registryThread
, withRegistry
, ResourceKey
, allocate
, allocateEither
, release
, releaseAll
, unsafeRelease
, unsafeReleaseAll
, Thread
, cancelThread
, forkLinkedThread
, forkThread
, linkToRegistry
, threadId
, waitAnyThread
, waitThread
, withThread
, TempRegistryException (..)
, WithTempRegistry
, allocateTemp
, modifyWithTempRegistry
, runInnerWithTempRegistry
, runWithTempRegistry
, closeRegistry
, countResources
, unsafeNewRegistry
) where
import Control.Applicative ((<|>))
import Control.Concurrent.Class.MonadSTM.Strict
import Control.Exception (asyncExceptionFromException)
import Control.Monad
import Control.Monad.Class.MonadAsync
import Control.Monad.Class.MonadFork
import Control.Monad.Class.MonadThrow
import Control.Monad.Reader
import Control.Monad.State.Strict
import Data.Bifunctor
import Data.Bimap (Bimap)
import Data.Bimap qualified as Bimap
import Data.Either (partitionEithers)
import Data.Map.Strict (Map)
import Data.Map.Strict qualified as Map
import Data.Maybe (catMaybes, listToMaybe)
import Data.Set (Set)
import Data.Set qualified as Set
import Data.Void
import Data.Word (Word64)
import GHC.Generics (Generic)
import GHC.Stack (CallStack, HasCallStack)
import GHC.Stack qualified as GHC
import NoThunks.Class hiding (Context)
data ResourceRegistry m = ResourceRegistry
{ forall (m :: * -> *). ResourceRegistry m -> Context m
registryContext :: !(Context m)
, forall (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
$cfrom :: forall (m :: * -> *) x.
ResourceRegistry m -> Rep (ResourceRegistry m) x
from :: forall x. ResourceRegistry m -> Rep (ResourceRegistry m) x
$cto :: forall (m :: * -> *) x.
Rep (ResourceRegistry m) x -> ResourceRegistry m
to :: forall x. Rep (ResourceRegistry m) x -> ResourceRegistry m
Generic
deriving instance
(forall a. NoThunks a => NoThunks (StrictTVar m a)) =>
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
$cshowsPrec :: Int -> Age -> ShowS
showsPrec :: Int -> Age -> ShowS
$cshow :: Age -> String
show :: Age -> String
$cshowList :: [Age] -> ShowS
showList :: [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
$c== :: Age -> Age -> Bool
== :: Age -> Age -> Bool
$c/= :: Age -> Age -> Bool
/= :: 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
$ccompare :: Age -> Age -> Ordering
compare :: Age -> Age -> Ordering
$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
>= :: Age -> Age -> Bool
$cmax :: Age -> Age -> Age
max :: Age -> Age -> Age
$cmin :: Age -> Age -> Age
min :: Age -> Age -> 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
$cnoThunks :: Context -> Age -> IO (Maybe ThunkInfo)
noThunks :: Context -> Age -> IO (Maybe ThunkInfo)
$cwNoThunks :: Context -> Age -> IO (Maybe ThunkInfo)
wNoThunks :: Context -> Age -> IO (Maybe ThunkInfo)
$cshowTypeOf :: Proxy Age -> String
showTypeOf :: Proxy Age -> String
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
{ forall (m :: * -> *). RegistryState m -> KnownThreads m
registryThreads :: !(KnownThreads m)
, forall (m :: * -> *).
RegistryState m -> Map ResourceId (Resource m)
registryResources :: !(Map ResourceId (Resource m))
, forall (m :: * -> *). RegistryState m -> ResourceId
registryNextKey :: !ResourceId
, forall (m :: * -> *). RegistryState m -> Bimap ResourceId Age
registryAges :: !(Bimap ResourceId Age)
, forall (m :: * -> *). RegistryState m -> Age
registryNextAge :: !Age
, forall (m :: * -> *). 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
$cfrom :: forall (m :: * -> *) x. RegistryState m -> Rep (RegistryState m) x
from :: forall x. RegistryState m -> Rep (RegistryState m) x
$cto :: forall (m :: * -> *) x. Rep (RegistryState m) x -> RegistryState m
to :: forall x. Rep (RegistryState m) x -> RegistryState m
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
$cnoThunks :: forall (m :: * -> *).
Context -> RegistryState m -> IO (Maybe ThunkInfo)
noThunks :: Context -> RegistryState m -> IO (Maybe ThunkInfo)
$cwNoThunks :: forall (m :: * -> *).
Context -> RegistryState m -> IO (Maybe ThunkInfo)
wNoThunks :: Context -> RegistryState m -> IO (Maybe ThunkInfo)
$cshowTypeOf :: forall (m :: * -> *). Proxy (RegistryState m) -> String
showTypeOf :: Proxy (RegistryState m) -> String
NoThunks)
getYoungestToOldest :: RegistryState m -> [ResourceId]
getYoungestToOldest :: forall (m :: * -> *). 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
$cnoThunks :: forall (m :: * -> *).
Context -> KnownThreads m -> IO (Maybe ThunkInfo)
noThunks :: Context -> KnownThreads m -> IO (Maybe ThunkInfo)
$cwNoThunks :: forall (m :: * -> *).
Context -> KnownThreads m -> IO (Maybe ThunkInfo)
wNoThunks :: Context -> KnownThreads m -> IO (Maybe ThunkInfo)
$cshowTypeOf :: forall (m :: * -> *). Proxy (KnownThreads m) -> String
showTypeOf :: Proxy (KnownThreads m) -> String
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
$cfrom :: forall x. RegistryStatus -> Rep RegistryStatus x
from :: forall x. RegistryStatus -> Rep RegistryStatus x
$cto :: forall x. Rep RegistryStatus x -> RegistryStatus
to :: forall x. Rep RegistryStatus x -> RegistryStatus
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
$cnoThunks :: Context -> RegistryStatus -> IO (Maybe ThunkInfo)
noThunks :: Context -> RegistryStatus -> IO (Maybe ThunkInfo)
$cwNoThunks :: Context -> RegistryStatus -> IO (Maybe ThunkInfo)
wNoThunks :: Context -> RegistryStatus -> IO (Maybe ThunkInfo)
$cshowTypeOf :: Proxy RegistryStatus -> String
showTypeOf :: Proxy RegistryStatus -> String
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
$cfrom :: forall (m :: * -> *) x. ResourceKey m -> Rep (ResourceKey m) x
from :: forall x. ResourceKey m -> Rep (ResourceKey m) x
$cto :: forall (m :: * -> *) x. Rep (ResourceKey m) x -> ResourceKey m
to :: forall x. Rep (ResourceKey m) x -> ResourceKey m
Generic
deriving instance
NoThunks (ResourceRegistry m) =>
NoThunks (ResourceKey m)
resourceKeyId :: ResourceKey m -> ResourceId
resourceKeyId :: forall (m :: * -> *). 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
$cshowsPrec :: Int -> ResourceId -> ShowS
showsPrec :: Int -> ResourceId -> ShowS
$cshow :: ResourceId -> String
show :: ResourceId -> String
$cshowList :: [ResourceId] -> ShowS
showList :: [ResourceId] -> ShowS
Show, ResourceId -> ResourceId -> Bool
(ResourceId -> ResourceId -> Bool)
-> (ResourceId -> ResourceId -> Bool) -> Eq ResourceId
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: ResourceId -> ResourceId -> Bool
== :: ResourceId -> ResourceId -> Bool
$c/= :: ResourceId -> ResourceId -> Bool
/= :: 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
$ccompare :: ResourceId -> ResourceId -> Ordering
compare :: ResourceId -> ResourceId -> Ordering
$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
>= :: ResourceId -> ResourceId -> Bool
$cmax :: ResourceId -> ResourceId -> ResourceId
max :: ResourceId -> ResourceId -> ResourceId
$cmin :: ResourceId -> ResourceId -> ResourceId
min :: ResourceId -> ResourceId -> 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
$csucc :: ResourceId -> ResourceId
succ :: ResourceId -> ResourceId
$cpred :: ResourceId -> ResourceId
pred :: ResourceId -> ResourceId
$ctoEnum :: Int -> ResourceId
toEnum :: Int -> ResourceId
$cfromEnum :: ResourceId -> Int
fromEnum :: ResourceId -> Int
$cenumFrom :: ResourceId -> [ResourceId]
enumFrom :: ResourceId -> [ResourceId]
$cenumFromThen :: ResourceId -> ResourceId -> [ResourceId]
enumFromThen :: ResourceId -> ResourceId -> [ResourceId]
$cenumFromTo :: ResourceId -> ResourceId -> [ResourceId]
enumFromTo :: ResourceId -> ResourceId -> [ResourceId]
$cenumFromThenTo :: ResourceId -> ResourceId -> ResourceId -> [ResourceId]
enumFromThenTo :: ResourceId -> ResourceId -> 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
$cnoThunks :: Context -> ResourceId -> IO (Maybe ThunkInfo)
noThunks :: Context -> ResourceId -> IO (Maybe ThunkInfo)
$cwNoThunks :: Context -> ResourceId -> IO (Maybe ThunkInfo)
wNoThunks :: Context -> ResourceId -> IO (Maybe ThunkInfo)
$cshowTypeOf :: Proxy ResourceId -> String
showTypeOf :: Proxy ResourceId -> String
NoThunks)
data Resource m = Resource
{ forall (m :: * -> *). Resource m -> Context m
resourceContext :: !(Context m)
, forall (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
$cfrom :: forall (m :: * -> *) x. Resource m -> Rep (Resource m) x
from :: forall x. Resource m -> Rep (Resource m) x
$cto :: forall (m :: * -> *) x. Rep (Resource m) x -> Resource m
to :: forall x. Rep (Resource m) x -> Resource m
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
$cnoThunks :: forall (m :: * -> *). Context -> Resource m -> IO (Maybe ThunkInfo)
noThunks :: Context -> Resource m -> IO (Maybe ThunkInfo)
$cwNoThunks :: forall (m :: * -> *). Context -> Resource m -> IO (Maybe ThunkInfo)
wNoThunks :: Context -> Resource m -> IO (Maybe ThunkInfo)
$cshowTypeOf :: forall (m :: * -> *). Proxy (Resource m) -> String
showTypeOf :: Proxy (Resource m) -> String
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
$cnoThunks :: forall (m :: * -> *). Context -> Release m -> IO (Maybe ThunkInfo)
noThunks :: Context -> Release m -> IO (Maybe ThunkInfo)
$cwNoThunks :: forall (m :: * -> *). Context -> Release m -> IO (Maybe ThunkInfo)
wNoThunks :: Context -> Release m -> IO (Maybe ThunkInfo)
$cshowTypeOf :: forall (m :: * -> *). Proxy (Release m) -> String
showTypeOf :: Proxy (Release m) -> String
NoThunks via OnlyCheckWhnfNamed "Release" (Release m)
releaseResource :: Resource m -> m Bool
releaseResource :: forall (m :: * -> *). 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 :: forall (m :: * -> *).
(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 :: forall (m :: * -> *) a.
State (RegistryState m) a
-> State (RegistryState m) (Either PrettyCallStack a)
unlessClosed State (RegistryState m) a
f = do
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 status of
RegistryClosed PrettyCallStack
closed -> Either PrettyCallStack a
-> StateT (RegistryState m) Identity (Either PrettyCallStack a)
forall a. a -> StateT (RegistryState m) Identity a
forall (m :: * -> *) a. Monad m => a -> m a
return (Either PrettyCallStack a
-> StateT (RegistryState m) Identity (Either PrettyCallStack a))
-> Either PrettyCallStack a
-> StateT (RegistryState m) Identity (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
-> StateT (RegistryState m) Identity (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 :: forall (m :: * -> *).
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
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
modify $ \RegistryState m
st -> RegistryState m
st{registryNextKey = succ nextKey}
return nextKey
insertResource ::
ResourceId ->
Resource m ->
State (RegistryState m) (Either PrettyCallStack ())
insertResource :: forall (m :: * -> *).
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.insert key r (registryResources st)
, registryAges =
Bimap.insert
key
(registryNextAge st)
(registryAges st)
, registryNextAge = nextYoungerAge (registryNextAge st)
}
removeResource :: ResourceId -> State (RegistryState m) (Maybe (Resource m))
removeResource :: forall (m :: * -> *).
ResourceId -> State (RegistryState m) (Maybe (Resource m))
removeResource ResourceId
key = (RegistryState m -> (Maybe (Resource m), RegistryState m))
-> StateT (RegistryState m) Identity (Maybe (Resource m))
forall a.
(RegistryState m -> (a, RegistryState m))
-> StateT (RegistryState m) Identity a
forall s (m :: * -> *) a. MonadState s m => (s -> (a, s)) -> m a
state ((RegistryState m -> (Maybe (Resource m), RegistryState m))
-> StateT (RegistryState m) Identity (Maybe (Resource m)))
-> (RegistryState m -> (Maybe (Resource m), RegistryState m))
-> StateT (RegistryState m) Identity (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 = resources'
, registryAges = Bimap.delete key (registryAges st)
}
in (Maybe (Resource m)
mbResource, RegistryState m
st')
insertThread :: MonadThread m => ThreadId m -> State (RegistryState m) ()
insertThread :: forall (m :: * -> *).
MonadThread m =>
ThreadId m -> State (RegistryState m) ()
insertThread ThreadId m
tid =
(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
{ registryThreads =
modifyKnownThreads (Set.insert tid) $
registryThreads st
}
removeThread :: MonadThread m => ThreadId m -> State (RegistryState m) ()
removeThread :: forall (m :: * -> *).
MonadThread m =>
ThreadId m -> State (RegistryState m) ()
removeThread ThreadId m
tid =
(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
{ registryThreads =
modifyKnownThreads (Set.delete tid) $
registryThreads st
}
close ::
PrettyCallStack ->
State (RegistryState m) (Either PrettyCallStack [ResourceId])
close :: forall (m :: * -> *).
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 = RegistryClosed 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.
MonadSTM m =>
ResourceRegistry m ->
State (RegistryState m) a ->
m a
updateState :: forall (m :: * -> *) a.
MonadSTM m =>
ResourceRegistry m -> State (RegistryState m) a -> m a
updateState ResourceRegistry m
rr State (RegistryState m) a
f =
STM m a -> m a
forall a. HasCallStack => 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. MonadThread m => RegistryClosedException
{ ()
registryClosedRegistryContext :: !(Context m)
, RegistryClosedException -> PrettyCallStack
registryClosedCloseCallStack :: !PrettyCallStack
, ()
registryClosedAllocContext :: !(Context m)
}
deriving instance Show RegistryClosedException
instance Exception RegistryClosedException
unsafeNewRegistry ::
(MonadSTM m, MonadThread m, HasCallStack) =>
m (ResourceRegistry m)
unsafeNewRegistry :: forall (m :: * -> *).
(MonadSTM m, MonadThread m, HasCallStack) =>
m (ResourceRegistry m)
unsafeNewRegistry = do
context <- m (Context m)
forall (m :: * -> *).
(MonadThread m, HasCallStack) =>
m (Context m)
captureContext
stateVar <- newTVarIO initState
return
ResourceRegistry
{ registryContext = context
, registryState = stateVar
}
where
initState :: RegistryState m
initState :: forall (m :: * -> *). RegistryState m
initState =
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 ::
(MonadMask m, MonadThread m, MonadSTM m, HasCallStack) =>
ResourceRegistry m ->
m ()
closeRegistry :: forall (m :: * -> *).
(MonadMask m, MonadThread m, MonadSTM m, HasCallStack) =>
ResourceRegistry m -> m ()
closeRegistry ResourceRegistry m
rr = m () -> m ()
forall a. m a -> m a
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)
forall (m :: * -> *).
(MonadThread m, HasCallStack) =>
m (Context m)
captureContext
unless (contextThreadId context == contextThreadId (registryContext rr)) $
throwIO $
ResourceRegistryClosedFromWrongThread
{ resourceRegistryCreatedIn = registryContext rr
, resourceRegistryUsedIn = context
}
alreadyClosed <- updateState rr $ close (contextCallStack context)
case alreadyClosed of
Left PrettyCallStack
_ ->
() -> m ()
forall a. a -> m a
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 :: * -> *).
MonadCatch 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 :: * -> *).
(MonadMask m, MonadSTM m, MonadThread m, HasCallStack) =>
ResourceKey m -> m (Maybe (Context m))
release
releaseResources ::
MonadCatch m =>
ResourceRegistry m ->
[ResourceId] ->
(ResourceKey m -> m (Maybe (Context m))) ->
m [Context m]
releaseResources :: forall (m :: * -> *).
MonadCatch m =>
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
(exs, mbContexts) <-
([Either SomeException (Maybe (Context m))]
-> ([SomeException], [Maybe (Context m)]))
-> m [Either SomeException (Maybe (Context m))]
-> m ([SomeException], [Maybe (Context m)])
forall a b. (a -> b) -> m a -> m b
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 e a. Exception e => m a -> m (Either e a)
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 prioritize exs of
Maybe SomeException
Nothing -> [Context m] -> m [Context m]
forall a. a -> m a
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 e a. Exception e => e -> m a
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 a. Maybe a -> Maybe a -> Maybe a
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 a b c. (a -> b) -> (a, c) -> (b, c)
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 ::
(MonadSTM m, MonadMask m, MonadThread m, HasCallStack) =>
(ResourceRegistry m -> m a) ->
m a
withRegistry :: forall (m :: * -> *) a.
(MonadSTM m, MonadMask m, MonadThread m, HasCallStack) =>
(ResourceRegistry m -> m a) -> m a
withRegistry = m (ResourceRegistry m)
-> (ResourceRegistry m -> m ())
-> (ResourceRegistry m -> m a)
-> m a
forall a b c. m a -> (a -> m b) -> (a -> m c) -> m c
forall (m :: * -> *) a b c.
MonadThrow m =>
m a -> (a -> m b) -> (a -> m c) -> m c
bracket m (ResourceRegistry m)
forall (m :: * -> *).
(MonadSTM m, MonadThread m, HasCallStack) =>
m (ResourceRegistry m)
unsafeNewRegistry ResourceRegistry m -> m ()
forall (m :: * -> *).
(MonadMask m, MonadThread m, MonadSTM m, HasCallStack) =>
ResourceRegistry m -> m ()
closeRegistry
bracketWithPrivateRegistry ::
(MonadSTM m, MonadMask m, MonadThread m, HasCallStack) =>
(ResourceRegistry m -> m a) ->
(a -> m ()) ->
(a -> m r) ->
m r
bracketWithPrivateRegistry :: forall (m :: * -> *) a r.
(MonadSTM m, MonadMask m, MonadThread m, HasCallStack) =>
(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.
(MonadSTM m, MonadMask m, MonadThread 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
(_key, a) <- ResourceRegistry m
-> (ResourceId -> m a) -> (a -> m ()) -> m (ResourceKey m, a)
forall (m :: * -> *) a.
(MonadSTM m, MonadMask m, MonadThread 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
body a
runWithTempRegistry ::
(MonadSTM m, MonadMask m, MonadThread m, HasCallStack) =>
WithTempRegistry st m (a, st) ->
m a
runWithTempRegistry :: forall (m :: * -> *) st a.
(MonadSTM m, MonadMask m, MonadThread m, HasCallStack) =>
WithTempRegistry st m (a, st) -> m a
runWithTempRegistry WithTempRegistry st m (a, st)
m = (ResourceRegistry m -> m a) -> m a
forall (m :: * -> *) a.
(MonadSTM m, MonadMask m, MonadThread 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
varTransferredTo <- TransferredTo st -> m (StrictTVar m (TransferredTo st))
forall (m :: * -> *) a. MonadSTM m => a -> m (StrictTVar m a)
newTVarIO TransferredTo st
forall a. Monoid a => a
mempty
let tempRegistry =
TempRegistry
{ tempResourceRegistry :: ResourceRegistry m
tempResourceRegistry = ResourceRegistry m
rr
, tempTransferredTo :: StrictTVar m (TransferredTo st)
tempTransferredTo = StrictTVar m (TransferredTo st)
varTransferredTo
}
(a, st) <- runReaderT (unWithTempRegistry m) tempRegistry
transferredTo <- readTVarIO varTransferredTo
untrackTransferredTo rr transferredTo st
context <- captureContext
remainingResources <- releaseAllHelper rr context release
whenJust (listToMaybe remainingResources) $ \Context m
remainingResource ->
TempRegistryException -> m ()
forall e a. Exception e => e -> m a
forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwIO (TempRegistryException -> m ()) -> TempRegistryException -> m ()
forall a b. (a -> b) -> a -> b
$
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
}
return a
where
whenJust :: Maybe t -> (t -> f ()) -> f ()
whenJust (Just t
x) t -> f ()
f = t -> f ()
f t
x
whenJust Maybe t
Nothing t -> f ()
_ = () -> f ()
forall a. a -> f a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
runInnerWithTempRegistry ::
forall innerSt st m res a.
(MonadSTM m, MonadMask m, MonadThread m) =>
WithTempRegistry innerSt m (a, innerSt, res) ->
(res -> m Bool) ->
(st -> res -> Bool) ->
WithTempRegistry st m a
runInnerWithTempRegistry :: forall innerSt st (m :: * -> *) res a.
(MonadSTM m, MonadMask m, MonadThread m) =>
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
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
lift $ runWithTempRegistry $ do
(a, innerSt, res) <- inner
_ <-
withFixedTempRegistry outerTR $
allocateTemp (return res) free isTransferred
pure (a, 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. MonadThread m => TempRegistryRemainingResource
{ ()
tempRegistryContext :: !(Context m)
, ()
tempRegistryResource :: !(Context m)
}
deriving instance Show TempRegistryException
instance Exception TempRegistryException
newtype TransferredTo st = TransferredTo
{ forall st. TransferredTo st -> st -> Set ResourceId
runTransferredTo :: st -> Set ResourceId
}
deriving newtype (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
$c<> :: forall st. TransferredTo st -> TransferredTo st -> TransferredTo st
<> :: TransferredTo st -> TransferredTo st -> TransferredTo st
$csconcat :: forall st. NonEmpty (TransferredTo st) -> TransferredTo st
sconcat :: NonEmpty (TransferredTo st) -> TransferredTo st
$cstimes :: forall st b.
Integral b =>
b -> TransferredTo st -> TransferredTo st
stimes :: forall b. Integral b => b -> 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
$cmempty :: forall st. TransferredTo st
mempty :: TransferredTo st
$cmappend :: forall st. TransferredTo st -> TransferredTo st -> TransferredTo st
mappend :: TransferredTo st -> TransferredTo st -> TransferredTo st
$cmconcat :: forall st. [TransferredTo st] -> TransferredTo st
mconcat :: [TransferredTo st] -> 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
$cnoThunks :: forall st. Context -> TransferredTo st -> IO (Maybe ThunkInfo)
noThunks :: Context -> TransferredTo st -> IO (Maybe ThunkInfo)
$cwNoThunks :: forall st. Context -> TransferredTo st -> IO (Maybe ThunkInfo)
wNoThunks :: Context -> TransferredTo st -> IO (Maybe ThunkInfo)
$cshowTypeOf :: forall st. Proxy (TransferredTo st) -> String
showTypeOf :: Proxy (TransferredTo st) -> String
NoThunks via OnlyCheckWhnfNamed "TransferredTo" (TransferredTo st)
data TempRegistry st m = TempRegistry
{ forall st (m :: * -> *). TempRegistry st m -> ResourceRegistry m
tempResourceRegistry :: !(ResourceRegistry m)
, forall st (m :: * -> *).
TempRegistry st m -> StrictTVar m (TransferredTo st)
tempTransferredTo :: !(StrictTVar m (TransferredTo st))
}
newtype WithTempRegistry st m a = WithTempRegistry
{ forall st (m :: * -> *) a.
WithTempRegistry st m a -> ReaderT (TempRegistry st m) m a
unWithTempRegistry :: ReaderT (TempRegistry st m) m a
}
deriving newtype
( (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
$cfmap :: forall st (m :: * -> *) a b.
Functor m =>
(a -> b) -> WithTempRegistry st m a -> WithTempRegistry st m b
fmap :: forall a b.
(a -> b) -> WithTempRegistry st m a -> WithTempRegistry st m b
$c<$ :: forall st (m :: * -> *) a b.
Functor m =>
a -> WithTempRegistry st m b -> WithTempRegistry st m a
<$ :: forall a b. a -> WithTempRegistry st m b -> WithTempRegistry st m a
Functor
, Functor (WithTempRegistry st m)
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)
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
$cpure :: forall st (m :: * -> *) a.
Applicative m =>
a -> WithTempRegistry st m a
pure :: forall a. a -> WithTempRegistry st m a
$c<*> :: forall st (m :: * -> *) a b.
Applicative m =>
WithTempRegistry st m (a -> b)
-> WithTempRegistry st m a -> WithTempRegistry st m b
<*> :: forall a b.
WithTempRegistry st m (a -> b)
-> WithTempRegistry st m a -> WithTempRegistry st m b
$cliftA2 :: forall st (m :: * -> *) a b c.
Applicative m =>
(a -> b -> c)
-> WithTempRegistry st m a
-> WithTempRegistry st m b
-> WithTempRegistry st m c
liftA2 :: forall a b c.
(a -> b -> c)
-> WithTempRegistry st m a
-> WithTempRegistry st m b
-> WithTempRegistry st m c
$c*> :: forall st (m :: * -> *) a b.
Applicative m =>
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 b
$c<* :: forall st (m :: * -> *) a b.
Applicative m =>
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 a
Applicative
, Applicative (WithTempRegistry st m)
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)
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
$c>>= :: forall st (m :: * -> *) a b.
Monad m =>
WithTempRegistry st m a
-> (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
$c>> :: forall st (m :: * -> *) a b.
Monad m =>
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 b
$creturn :: forall st (m :: * -> *) a. Monad m => a -> WithTempRegistry st m a
return :: forall a. a -> WithTempRegistry st m a
Monad
, Monad (WithTempRegistry st m)
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)
-> (forall e a.
ExceptionAnnotation e =>
e -> WithTempRegistry st m a -> WithTempRegistry st m a)
-> MonadThrow (WithTempRegistry st m)
forall e a.
ExceptionAnnotation e =>
e -> WithTempRegistry st m a -> 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, ExceptionAnnotation e) =>
e -> WithTempRegistry st m a -> WithTempRegistry st m a
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)
-> (forall e a. ExceptionAnnotation e => e -> m a -> m a)
-> MonadThrow m
$cthrowIO :: forall st (m :: * -> *) e a.
(MonadThrow m, Exception e) =>
e -> WithTempRegistry st m a
throwIO :: forall e a. Exception e => e -> WithTempRegistry st m a
$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
bracket :: forall a b c.
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
-> WithTempRegistry st m b
-> WithTempRegistry st m c
-> WithTempRegistry st m c
bracket_ :: forall a b c.
WithTempRegistry st m a
-> WithTempRegistry st m b
-> WithTempRegistry st m c
-> WithTempRegistry st m c
$cfinally :: forall st (m :: * -> *) a b.
MonadThrow m =>
WithTempRegistry st m a
-> WithTempRegistry st m b -> WithTempRegistry st m a
finally :: forall a b.
WithTempRegistry st m a
-> WithTempRegistry st m b -> WithTempRegistry st m a
$cannotateIO :: forall st (m :: * -> *) e a.
(MonadThrow m, ExceptionAnnotation e) =>
e -> WithTempRegistry st m a -> WithTempRegistry st m a
annotateIO :: forall e a.
ExceptionAnnotation e =>
e -> WithTempRegistry st m a -> WithTempRegistry st m a
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)
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
$ccatch :: forall st (m :: * -> *) e a.
(MonadCatch m, Exception e) =>
WithTempRegistry st m a
-> (e -> WithTempRegistry st m a) -> WithTempRegistry st m a
catch :: forall e a.
Exception e =>
WithTempRegistry st m a
-> (e -> 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
catchJust :: forall e b a.
Exception e =>
(e -> Maybe b)
-> WithTempRegistry st m a
-> (b -> WithTempRegistry st m a)
-> WithTempRegistry st m a
$ctry :: forall st (m :: * -> *) e a.
(MonadCatch m, Exception e) =>
WithTempRegistry st m a -> WithTempRegistry st m (Either e a)
try :: forall e a.
Exception e =>
WithTempRegistry st m a -> WithTempRegistry st m (Either e 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)
tryJust :: forall e b a.
Exception e =>
(e -> Maybe b)
-> WithTempRegistry st m a -> WithTempRegistry st m (Either b a)
$chandle :: forall st (m :: * -> *) e a.
(MonadCatch m, Exception e) =>
(e -> WithTempRegistry st m a)
-> WithTempRegistry st m a -> WithTempRegistry st m a
handle :: forall e a.
Exception e =>
(e -> 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
handleJust :: forall e b a.
Exception e =>
(e -> Maybe b)
-> (b -> WithTempRegistry st m a)
-> WithTempRegistry st m a
-> WithTempRegistry st m a
$conException :: forall st (m :: * -> *) a b.
MonadCatch m =>
WithTempRegistry st m a
-> WithTempRegistry st m b -> WithTempRegistry st m a
onException :: forall a b.
WithTempRegistry st m a
-> WithTempRegistry st m b -> WithTempRegistry st m a
$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
bracketOnError :: forall a b c.
WithTempRegistry st m a
-> (a -> WithTempRegistry st m b)
-> (a -> WithTempRegistry st m c)
-> WithTempRegistry st m 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)
generalBracket :: 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
, MonadCatch (WithTempRegistry st m)
WithTempRegistry st m ()
WithTempRegistry st m MaskingState
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)
-> WithTempRegistry st m MaskingState
-> (forall a. WithTempRegistry st m a -> WithTempRegistry st m a)
-> WithTempRegistry st m ()
-> MonadMask (WithTempRegistry st m)
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 :: * -> *). MonadMask m => WithTempRegistry st m ()
forall st (m :: * -> *).
MonadMask m =>
WithTempRegistry st m MaskingState
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)
-> m MaskingState
-> (forall a. m a -> m a)
-> m ()
-> MonadMask m
$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
mask :: forall b.
((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
uninterruptibleMask :: forall b.
((forall a. WithTempRegistry st m a -> WithTempRegistry st m a)
-> WithTempRegistry st m b)
-> WithTempRegistry st m b
$cmask_ :: forall st (m :: * -> *) a.
MonadMask m =>
WithTempRegistry st m a -> WithTempRegistry st m a
mask_ :: forall a. WithTempRegistry st m a -> WithTempRegistry st m a
$cuninterruptibleMask_ :: 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
$cgetMaskingState :: forall st (m :: * -> *).
MonadMask m =>
WithTempRegistry st m MaskingState
getMaskingState :: WithTempRegistry st m MaskingState
$cinterruptible :: forall st (m :: * -> *) a.
MonadMask m =>
WithTempRegistry st m a -> WithTempRegistry st m a
interruptible :: forall a. WithTempRegistry st m a -> WithTempRegistry st m a
$callowInterrupt :: forall st (m :: * -> *). MonadMask m => WithTempRegistry st m ()
allowInterrupt :: WithTempRegistry st m ()
MonadMask
)
instance MonadTrans (WithTempRegistry st) where
lift :: forall (m :: * -> *) a. Monad m => 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 (m :: * -> *) a.
Monad m =>
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 :: forall a. (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 a. (s -> (a, s)) -> ReaderT (TempRegistry st m) m a
forall s (m :: * -> *) a. MonadState s m => (s -> (a, s)) -> m a
state
untrackTransferredTo ::
MonadSTM m =>
ResourceRegistry m ->
TransferredTo st ->
st ->
m ()
untrackTransferredTo :: forall (m :: * -> *) st.
MonadSTM m =>
ResourceRegistry m -> TransferredTo st -> st -> m ()
untrackTransferredTo ResourceRegistry m
rr TransferredTo st
transferredTo st
st =
ResourceRegistry m -> State (RegistryState m) () -> m ()
forall (m :: * -> *) a.
MonadSTM 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 ::
(MonadSTM m, MonadMask m, MonadThread m, HasCallStack) =>
m a ->
(a -> m Bool) ->
(st -> a -> Bool) ->
WithTempRegistry st m a
allocateTemp :: forall (m :: * -> *) a st.
(MonadSTM m, MonadMask m, MonadThread m, HasCallStack) =>
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 rr varTransferredTo <- ReaderT (TempRegistry st m) m (TempRegistry st m)
forall r (m :: * -> *). MonadReader r m => m r
ask
(key, a) <-
lift
( mustBeRight
<$> allocateEither rr (fmap Right . const alloc) free
)
lift $
atomically $
modifyTVar varTransferredTo $
mappend $
TransferredTo $ \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
return a
modifyWithTempRegistry ::
forall m st a.
(MonadSTM m, MonadMask m, MonadThread m) =>
m st ->
(st -> ExitCase st -> m ()) ->
StateT st (WithTempRegistry st m) a ->
m a
modifyWithTempRegistry :: forall (m :: * -> *) st a.
(MonadSTM m, MonadMask m, MonadThread m) =>
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.
(MonadSTM m, MonadMask m, MonadThread 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 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 (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 (m :: * -> *) a. Monad m => m a -> WithTempRegistry st m a
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 (m :: * -> *) a. Monad m => m a -> WithTempRegistry st m a
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 :: forall (m :: * -> *). 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 :: MonadSTM m => ResourceRegistry m -> m Int
countResources :: forall (m :: * -> *). MonadSTM m => ResourceRegistry m -> m Int
countResources ResourceRegistry m
rr = STM m Int -> m Int
forall a. HasCallStack => STM m a -> m a
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 :: forall (m :: * -> *). 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.
(MonadSTM m, MonadMask m, MonadThread m, HasCallStack) =>
ResourceRegistry m ->
(ResourceId -> m a) ->
(a -> m ()) ->
m (ResourceKey m, a)
allocate :: forall (m :: * -> *) a.
(MonadSTM m, MonadMask m, MonadThread m, HasCallStack) =>
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.
(MonadSTM m, MonadMask m, MonadThread 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 a b. (a -> b) -> m a -> m b
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 a b. m a -> m b -> m b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Bool -> m Bool
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
True)
allocateEither ::
forall m e a.
(MonadSTM m, MonadMask m, MonadThread m, HasCallStack) =>
ResourceRegistry m ->
(ResourceId -> m (Either e a)) ->
(a -> m Bool) ->
m (Either e (ResourceKey m, a))
allocateEither :: forall (m :: * -> *) e a.
(MonadSTM m, MonadMask m, MonadThread m, HasCallStack) =>
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)
forall (m :: * -> *).
(MonadThread m, HasCallStack) =>
m (Context m)
captureContext
ensureKnownThread rr context
mKey <- updateState rr allocKey
case mKey of
Left PrettyCallStack
closed ->
ResourceRegistry m
-> Context m -> PrettyCallStack -> m (Either e (ResourceKey m, a))
forall (m :: * -> *) x.
(MonadThrow m, MonadThread 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 a. m a -> 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
ma <- ResourceId -> m (Either e a)
alloc ResourceId
key
case ma of
Left e
e -> Either e (ResourceKey m, a) -> m (Either e (ResourceKey m, a))
forall a. a -> 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
inserted <-
ResourceRegistry m
-> State (RegistryState m) (Either PrettyCallStack ())
-> m (Either PrettyCallStack ())
forall (m :: * -> *) a.
MonadSTM 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 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.
(MonadThrow m, MonadThread 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 a. a -> 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
{ 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 ::
(MonadThrow m, MonadThread m) =>
ResourceRegistry m ->
Context m ->
PrettyCallStack ->
m x
throwRegistryClosed :: forall (m :: * -> *) x.
(MonadThrow m, MonadThread m) =>
ResourceRegistry m -> Context m -> PrettyCallStack -> m x
throwRegistryClosed ResourceRegistry m
rr Context m
context PrettyCallStack
closed =
RegistryClosedException -> m x
forall e a. Exception e => e -> m a
forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwIO
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 ::
(MonadMask m, MonadSTM m, MonadThread m, HasCallStack) =>
ResourceKey m ->
m (Maybe (Context m))
release :: forall (m :: * -> *).
(MonadMask m, MonadSTM m, MonadThread m, HasCallStack) =>
ResourceKey m -> m (Maybe (Context m))
release key :: ResourceKey m
key@(ResourceKey ResourceRegistry m
rr ResourceId
_) = do
context <- m (Context m)
forall (m :: * -> *).
(MonadThread m, HasCallStack) =>
m (Context m)
captureContext
ensureKnownThread rr context
unsafeRelease key
unsafeRelease ::
(MonadMask m, MonadSTM m) =>
ResourceKey m ->
m (Maybe (Context m))
unsafeRelease :: forall (m :: * -> *).
(MonadMask m, MonadSTM m) =>
ResourceKey m -> m (Maybe (Context m))
unsafeRelease (ResourceKey ResourceRegistry m
rr ResourceId
rid) = do
m (Maybe (Context m)) -> m (Maybe (Context m))
forall a. m a -> m a
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
mResource <- ResourceRegistry m
-> State (RegistryState m) (Maybe (Resource m))
-> m (Maybe (Resource m))
forall (m :: * -> *) a.
MonadSTM 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 mResource of
Maybe (Resource m)
Nothing -> Maybe (Context m) -> m (Maybe (Context m))
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe (Context m)
forall a. Maybe a
Nothing
Just Resource m
resource -> do
actuallyReleased <- Resource m -> m Bool
forall (m :: * -> *). Resource m -> m Bool
releaseResource Resource m
resource
return $
if actuallyReleased
then Just (resourceContext resource)
else Nothing
releaseAll ::
(MonadMask m, MonadSTM m, MonadThread m, HasCallStack) =>
ResourceRegistry m ->
m ()
releaseAll :: forall (m :: * -> *).
(MonadMask m, MonadSTM m, MonadThread m, HasCallStack) =>
ResourceRegistry m -> m ()
releaseAll ResourceRegistry m
rr = do
context <- m (Context m)
forall (m :: * -> *).
(MonadThread m, HasCallStack) =>
m (Context m)
captureContext
unless (contextThreadId context == contextThreadId (registryContext rr)) $
throwIO $
ResourceRegistryClosedFromWrongThread
{ resourceRegistryCreatedIn = registryContext rr
, resourceRegistryUsedIn = context
}
void $ releaseAllHelper rr context release
unsafeReleaseAll ::
(MonadMask m, MonadSTM m, MonadThread m, HasCallStack) =>
ResourceRegistry m ->
m ()
unsafeReleaseAll :: forall (m :: * -> *).
(MonadMask m, MonadSTM m, MonadThread m, HasCallStack) =>
ResourceRegistry m -> m ()
unsafeReleaseAll ResourceRegistry m
rr = do
context <- m (Context m)
forall (m :: * -> *).
(MonadThread m, HasCallStack) =>
m (Context m)
captureContext
void $ releaseAllHelper rr context unsafeRelease
releaseAllHelper ::
(MonadMask m, MonadSTM m, MonadThread m) =>
ResourceRegistry m ->
Context m ->
(ResourceKey m -> m (Maybe (Context m))) ->
m [Context m]
releaseAllHelper :: forall (m :: * -> *).
(MonadMask m, MonadSTM m, MonadThread 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))
releaser = m [Context m] -> m [Context m]
forall a. m a -> m a
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
mKeys <- ResourceRegistry m
-> State (RegistryState m) (Either PrettyCallStack [ResourceId])
-> m (Either PrettyCallStack [ResourceId])
forall (m :: * -> *) a.
MonadSTM 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 mKeys of
Left PrettyCallStack
closed -> ResourceRegistry m -> Context m -> PrettyCallStack -> m [Context m]
forall (m :: * -> *) x.
(MonadThrow m, MonadThread 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 :: * -> *).
MonadCatch 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 = MonadThread m => Thread
{ forall (m :: * -> *) a. Thread m a -> ThreadId m
threadId :: !(ThreadId m)
, forall (m :: * -> *) a. Thread m a -> ResourceId
threadResourceId :: !ResourceId
, forall (m :: * -> *) a. Thread m a -> Async m a
threadAsync :: !(Async m a)
, forall (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
$cnoThunks :: forall (m :: * -> *) a.
Context -> Thread m a -> IO (Maybe ThunkInfo)
noThunks :: Context -> Thread m a -> IO (Maybe ThunkInfo)
$cwNoThunks :: forall (m :: * -> *) a.
Context -> Thread m a -> IO (Maybe ThunkInfo)
wNoThunks :: Context -> Thread m a -> IO (Maybe ThunkInfo)
$cshowTypeOf :: forall (m :: * -> *) a. Proxy (Thread m a) -> String
showTypeOf :: Proxy (Thread m a) -> String
NoThunks via OnlyCheckWhnfNamed "Thread" (Thread m a)
instance MonadThread m => 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 :: MonadAsync m => Thread m a -> m ()
cancelThread :: forall (m :: * -> *) a. MonadAsync m => Thread m a -> m ()
cancelThread = Async m a -> m ()
forall a. 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 :: MonadAsync m => Thread m a -> m a
waitThread :: forall (m :: * -> *) a. MonadAsync m => Thread m a -> m a
waitThread = Async m a -> m a
forall a. 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. MonadAsync m => [Thread m a] -> m a
waitAnyThread :: forall (m :: * -> *) a. MonadAsync m => [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 a. [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.
(MonadMask m, MonadAsync m, HasCallStack) =>
ResourceRegistry m ->
String ->
m a ->
m (Thread m a)
forkThread :: forall (m :: * -> *) a.
(MonadMask m, MonadAsync m, HasCallStack) =>
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.
(MonadSTM m, MonadMask m, MonadThread 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 a. 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. MonadAsync 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
{ threadId :: ThreadId m
threadId = Async m a -> ThreadId m
forall a. 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
me <- m (ThreadId m)
forall (m :: * -> *). MonadThread m => m (ThreadId m)
myThreadId
labelThread me label
(registerThread me >> body) `finally` unregisterThread me rid
registerThread :: ThreadId m -> m ()
registerThread :: ThreadId m -> m ()
registerThread ThreadId m
tid = ResourceRegistry m -> State (RegistryState m) () -> m ()
forall (m :: * -> *) a.
MonadSTM 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 :: * -> *).
MonadThread 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.
MonadSTM 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 :: * -> *).
MonadThread 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 ::
(MonadMask m, MonadAsync m) =>
ResourceRegistry m ->
String ->
m a ->
(Thread m a -> m b) ->
m b
withThread :: forall (m :: * -> *) a b.
(MonadMask m, MonadAsync m) =>
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 a b c. m a -> (a -> m b) -> (a -> m c) -> m c
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.
(MonadMask m, MonadAsync 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. MonadAsync m => Thread m a -> m ()
cancelThread
linkToRegistry :: (MonadAsync m, MonadFork m, MonadMask m) => Thread m a -> m ()
linkToRegistry :: forall (m :: * -> *) a.
(MonadAsync m, MonadFork m, MonadMask m) =>
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 ::
(MonadAsync m, MonadFork m, MonadMask m, HasCallStack) =>
ResourceRegistry m ->
String ->
m a ->
m (Thread m a)
forkLinkedThread :: forall (m :: * -> *) a.
(MonadAsync m, MonadFork m, MonadMask m, HasCallStack) =>
ResourceRegistry m -> String -> m a -> m (Thread m a)
forkLinkedThread ResourceRegistry m
rr String
label m a
body = do
t <- ResourceRegistry m -> String -> m a -> m (Thread m a)
forall (m :: * -> *) a.
(MonadMask m, MonadAsync m, HasCallStack) =>
ResourceRegistry m -> String -> m a -> m (Thread m a)
forkThread ResourceRegistry m
rr String
label m a
body
linkToRegistry t
return t
ensureKnownThread ::
forall m.
(MonadThrow m, MonadThread m, MonadSTM m) =>
ResourceRegistry m ->
Context m ->
m ()
ensureKnownThread :: forall (m :: * -> *).
(MonadThrow m, MonadThread m, MonadSTM m) =>
ResourceRegistry m -> Context m -> m ()
ensureKnownThread ResourceRegistry m
rr Context m
context = do
isKnown <- m Bool
checkIsKnown
unless isKnown $
throwIO $
ResourceRegistryUsedFromUntrackedThread
{ resourceRegistryCreatedIn = registryContext rr
, resourceRegistryUsedIn = 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 a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
True
| Bool
otherwise = STM m Bool -> m Bool
forall a. HasCallStack => STM m a -> m a
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 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)
return $ contextThreadId context `Set.member` ts
data ResourceRegistryThreadException
=
forall m. MonadThread m => ResourceRegistryUsedFromUntrackedThread
{ ()
resourceRegistryCreatedIn :: !(Context m)
, ()
resourceRegistryUsedIn :: !(Context m)
}
|
forall m. MonadThread m => ResourceRegistryClosedFromWrongThread
{ resourceRegistryCreatedIn :: !(Context m)
, resourceRegistryUsedIn :: !(Context m)
}
deriving instance Show ResourceRegistryThreadException
instance Exception ResourceRegistryThreadException
data Context m = MonadThread m => Context
{ forall (m :: * -> *). Context m -> PrettyCallStack
contextCallStack :: !PrettyCallStack
, forall (m :: * -> *). 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 (forall (name :: Symbol) a. a -> InspectHeapNamed name a
InspectHeapNamed @"ThreadId" ThreadId m
tid)
]
deriving instance Show (Context m)
captureContext :: MonadThread m => HasCallStack => m (Context m)
captureContext :: forall (m :: * -> *).
(MonadThread m, HasCallStack) =>
m (Context m)
captureContext = PrettyCallStack -> ThreadId m -> Context m
forall (m :: * -> *).
MonadThread 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
linkTo ::
(MonadAsync m, MonadFork m, MonadMask m) =>
ThreadId m ->
Async m a ->
m ()
linkTo :: forall (m :: * -> *) a.
(MonadAsync m, MonadFork m, MonadMask m) =>
ThreadId m -> Async m a -> m ()
linkTo ThreadId m
tid = ThreadId m -> (SomeException -> Bool) -> Async m a -> m ()
forall (m :: * -> *) a.
(MonadAsync m, MonadFork m, MonadMask m) =>
ThreadId m -> (SomeException -> Bool) -> Async m a -> m ()
linkToOnly ThreadId m
tid (Bool -> Bool
not (Bool -> Bool) -> (SomeException -> Bool) -> SomeException -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SomeException -> Bool
isCancel)
linkToOnly ::
forall m a.
(MonadAsync m, MonadFork m, MonadMask m) =>
ThreadId m ->
(SomeException -> Bool) ->
Async m a ->
m ()
linkToOnly :: forall (m :: * -> *) a.
(MonadAsync m, MonadFork m, MonadMask m) =>
ThreadId m -> (SomeException -> Bool) -> Async m a -> m ()
linkToOnly ThreadId m
tid SomeException -> Bool
shouldThrow Async m a
a = do
m (ThreadId m) -> m ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (m (ThreadId m) -> m ()) -> m (ThreadId m) -> m ()
forall a b. (a -> b) -> a -> b
$ String -> m () -> m (ThreadId m)
forall (m :: * -> *) a.
(MonadFork m, MonadMask m) =>
String -> m a -> m (ThreadId m)
forkRepeat (String
"linkToOnly " String -> ShowS
forall a. Semigroup a => a -> a -> a
<> ThreadId m -> String
forall a. Show a => a -> String
show ThreadId m
linkedThreadId) (m () -> m (ThreadId m)) -> m () -> m (ThreadId m)
forall a b. (a -> b) -> a -> b
$ do
r <- Async m a -> m (Either SomeException a)
forall a. Async m a -> m (Either SomeException a)
forall (m :: * -> *) a.
MonadAsync m =>
Async m a -> m (Either SomeException a)
waitCatch Async m a
a
case r of
Left SomeException
e | SomeException -> Bool
shouldThrow SomeException
e -> ThreadId m -> ExceptionInLinkedThread -> m ()
forall e. Exception e => ThreadId m -> e -> m ()
forall (m :: * -> *) e.
(MonadFork m, Exception e) =>
ThreadId m -> e -> m ()
throwTo ThreadId m
tid (SomeException -> ExceptionInLinkedThread
exceptionInLinkedThread SomeException
e)
Either SomeException a
_otherwise -> () -> m ()
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
where
linkedThreadId :: ThreadId m
linkedThreadId :: ThreadId m
linkedThreadId = Async m a -> ThreadId m
forall a. Async m a -> ThreadId m
forall (m :: * -> *) a. MonadAsync m => Async m a -> ThreadId m
asyncThreadId Async m a
a
exceptionInLinkedThread :: SomeException -> ExceptionInLinkedThread
exceptionInLinkedThread :: SomeException -> ExceptionInLinkedThread
exceptionInLinkedThread =
String -> SomeException -> ExceptionInLinkedThread
ExceptionInLinkedThread (ThreadId m -> String
forall a. Show a => a -> String
show ThreadId m
linkedThreadId)
isCancel :: SomeException -> Bool
isCancel :: SomeException -> Bool
isCancel SomeException
e
| Just AsyncCancelled
AsyncCancelled <- SomeException -> Maybe AsyncCancelled
forall e. Exception e => SomeException -> Maybe e
fromException SomeException
e = Bool
True
| Bool
otherwise = Bool
False
forkRepeat :: (MonadFork m, MonadMask m) => String -> m a -> m (ThreadId m)
forkRepeat :: forall (m :: * -> *) a.
(MonadFork m, MonadMask m) =>
String -> m a -> m (ThreadId m)
forkRepeat String
label m a
action =
((forall a. m a -> m a) -> m (ThreadId m)) -> m (ThreadId m)
forall b. ((forall a. m a -> m a) -> m b) -> m b
forall (m :: * -> *) b.
MonadMask m =>
((forall a. m a -> m a) -> m b) -> m b
mask (((forall a. m a -> m a) -> m (ThreadId m)) -> m (ThreadId m))
-> ((forall a. m a -> m a) -> m (ThreadId m)) -> m (ThreadId m)
forall a b. (a -> b) -> a -> b
$ \forall a. m a -> m a
restore ->
let go :: m ()
go = do
r <- m a -> m (Either SomeException a)
forall (m :: * -> *) a.
MonadCatch m =>
m a -> m (Either SomeException a)
tryAll (m a -> m a
forall a. m a -> m a
restore m a
action)
case r of
Left SomeException
_ -> m ()
go
Either SomeException a
_ -> () -> m ()
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
in m () -> m (ThreadId m)
forall (m :: * -> *). MonadFork m => m () -> m (ThreadId m)
forkIO (String -> m ()
forall (m :: * -> *). MonadThread m => String -> m ()
labelThisThread String
label m () -> m () -> m ()
forall a b. m a -> m b -> m b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> m ()
go)
tryAll :: MonadCatch m => m a -> m (Either SomeException a)
tryAll :: forall (m :: * -> *) a.
MonadCatch m =>
m a -> m (Either SomeException a)
tryAll = m a -> m (Either SomeException a)
forall e a. Exception e => m a -> m (Either e a)
forall (m :: * -> *) e a.
(MonadCatch m, Exception e) =>
m a -> m (Either e a)
try
mustBeRight :: Either Void a -> a
mustBeRight :: forall a. Either Void a -> a
mustBeRight (Left Void
v) = Void -> a
forall a. Void -> a
absurd Void
v
mustBeRight (Right a
a) = a
a
newtype PrettyCallStack = PrettyCallStack CallStack
deriving newtype Context -> PrettyCallStack -> IO (Maybe ThunkInfo)
Proxy PrettyCallStack -> String
(Context -> PrettyCallStack -> IO (Maybe ThunkInfo))
-> (Context -> PrettyCallStack -> IO (Maybe ThunkInfo))
-> (Proxy PrettyCallStack -> String)
-> NoThunks PrettyCallStack
forall a.
(Context -> a -> IO (Maybe ThunkInfo))
-> (Context -> a -> IO (Maybe ThunkInfo))
-> (Proxy a -> String)
-> NoThunks a
$cnoThunks :: Context -> PrettyCallStack -> IO (Maybe ThunkInfo)
noThunks :: Context -> PrettyCallStack -> IO (Maybe ThunkInfo)
$cwNoThunks :: Context -> PrettyCallStack -> IO (Maybe ThunkInfo)
wNoThunks :: Context -> PrettyCallStack -> IO (Maybe ThunkInfo)
$cshowTypeOf :: Proxy PrettyCallStack -> String
showTypeOf :: Proxy PrettyCallStack -> String
NoThunks
instance Show PrettyCallStack where
show :: PrettyCallStack -> String
show (PrettyCallStack CallStack
cs) = CallStack -> String
GHC.prettyCallStack CallStack
cs
prettyCallStack :: HasCallStack => PrettyCallStack
prettyCallStack :: HasCallStack => PrettyCallStack
prettyCallStack = CallStack -> PrettyCallStack
PrettyCallStack CallStack
HasCallStack => CallStack
GHC.callStack
instance
(NoThunks k, NoThunks v) =>
NoThunks (Bimap k v)
where
wNoThunks :: Context -> Bimap k v -> IO (Maybe ThunkInfo)
wNoThunks Context
ctxt = Context -> [(k, v)] -> IO (Maybe ThunkInfo)
forall k v.
(NoThunks k, NoThunks v) =>
Context -> [(k, v)] -> IO (Maybe ThunkInfo)
noThunksInKeysAndValues Context
ctxt ([(k, v)] -> IO (Maybe ThunkInfo))
-> (Bimap k v -> [(k, v)]) -> Bimap k v -> IO (Maybe ThunkInfo)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Bimap k v -> [(k, v)]
forall a b. Bimap a b -> [(a, b)]
Bimap.toList