module Ki.Internal.Thread
( Thread,
makeThread,
await,
ThreadAffinity (..),
ThreadOptions (..),
defaultThreadOptions,
ThreadFailed (..),
unwrapThreadFailed,
)
where
import Control.Exception
( BlockedIndefinitelyOnSTM (..),
Exception (fromException, toException),
MaskingState (..),
asyncExceptionFromException,
asyncExceptionToException,
)
import GHC.Conc (STM, catchSTM)
import Ki.Internal.ByteCount
import Ki.Internal.Prelude
data Thread a = Thread
{ forall a. Thread a -> ThreadId
threadId :: {-# UNPACK #-} !ThreadId,
forall a. Thread a -> STM a
await_ :: !(STM a)
}
deriving stock ((forall a b. (a -> b) -> Thread a -> Thread b)
-> (forall a b. a -> Thread b -> Thread a) -> Functor Thread
forall a b. a -> Thread b -> Thread a
forall a b. (a -> b) -> Thread a -> Thread b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: forall a b. a -> Thread b -> Thread a
$c<$ :: forall a b. a -> Thread b -> Thread a
fmap :: forall a b. (a -> b) -> Thread a -> Thread b
$cfmap :: forall a b. (a -> b) -> Thread a -> Thread b
Functor)
instance Eq (Thread a) where
Thread ThreadId
ix STM a
_ == :: Thread a -> Thread a -> Bool
== Thread ThreadId
iy STM a
_ =
ThreadId
ix ThreadId -> ThreadId -> Bool
forall a. Eq a => a -> a -> Bool
== ThreadId
iy
instance Ord (Thread a) where
compare :: Thread a -> Thread a -> Ordering
compare (Thread ThreadId
ix STM a
_) (Thread ThreadId
iy STM a
_) =
ThreadId -> ThreadId -> Ordering
forall a. Ord a => a -> a -> Ordering
compare ThreadId
ix ThreadId
iy
makeThread :: ThreadId -> STM a -> Thread a
makeThread :: forall a. ThreadId -> STM a -> Thread a
makeThread ThreadId
threadId STM a
action =
Thread
{ ThreadId
threadId :: ThreadId
$sel:threadId:Thread :: ThreadId
threadId,
$sel:await_:Thread :: STM a
await_ = (BlockedIndefinitelyOnSTM -> STM a)
-> (a -> STM a) -> STM a -> STM a
forall e b a.
Exception e =>
(e -> STM b) -> (a -> STM b) -> STM a -> STM b
tryEitherSTM (\BlockedIndefinitelyOnSTM
BlockedIndefinitelyOnSTM -> STM a
action) a -> STM a
forall (f :: * -> *) a. Applicative f => a -> f a
pure STM a
action
}
data ThreadAffinity
=
Unbound
|
Capability Int
|
OsThread
deriving stock (ThreadAffinity -> ThreadAffinity -> Bool
(ThreadAffinity -> ThreadAffinity -> Bool)
-> (ThreadAffinity -> ThreadAffinity -> Bool) -> Eq ThreadAffinity
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ThreadAffinity -> ThreadAffinity -> Bool
$c/= :: ThreadAffinity -> ThreadAffinity -> Bool
== :: ThreadAffinity -> ThreadAffinity -> Bool
$c== :: ThreadAffinity -> ThreadAffinity -> Bool
Eq, Int -> ThreadAffinity -> ShowS
[ThreadAffinity] -> ShowS
ThreadAffinity -> String
(Int -> ThreadAffinity -> ShowS)
-> (ThreadAffinity -> String)
-> ([ThreadAffinity] -> ShowS)
-> Show ThreadAffinity
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [ThreadAffinity] -> ShowS
$cshowList :: [ThreadAffinity] -> ShowS
show :: ThreadAffinity -> String
$cshow :: ThreadAffinity -> String
showsPrec :: Int -> ThreadAffinity -> ShowS
$cshowsPrec :: Int -> ThreadAffinity -> ShowS
Show)
data ThreadOptions = ThreadOptions
{ ThreadOptions -> ThreadAffinity
affinity :: ThreadAffinity,
ThreadOptions -> Maybe ByteCount
allocationLimit :: Maybe ByteCount,
ThreadOptions -> String
label :: String,
ThreadOptions -> MaskingState
maskingState :: MaskingState
}
deriving stock (ThreadOptions -> ThreadOptions -> Bool
(ThreadOptions -> ThreadOptions -> Bool)
-> (ThreadOptions -> ThreadOptions -> Bool) -> Eq ThreadOptions
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ThreadOptions -> ThreadOptions -> Bool
$c/= :: ThreadOptions -> ThreadOptions -> Bool
== :: ThreadOptions -> ThreadOptions -> Bool
$c== :: ThreadOptions -> ThreadOptions -> Bool
Eq, Int -> ThreadOptions -> ShowS
[ThreadOptions] -> ShowS
ThreadOptions -> String
(Int -> ThreadOptions -> ShowS)
-> (ThreadOptions -> String)
-> ([ThreadOptions] -> ShowS)
-> Show ThreadOptions
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [ThreadOptions] -> ShowS
$cshowList :: [ThreadOptions] -> ShowS
show :: ThreadOptions -> String
$cshow :: ThreadOptions -> String
showsPrec :: Int -> ThreadOptions -> ShowS
$cshowsPrec :: Int -> ThreadOptions -> ShowS
Show)
defaultThreadOptions :: ThreadOptions
defaultThreadOptions :: ThreadOptions
defaultThreadOptions =
ThreadOptions
{ $sel:affinity:ThreadOptions :: ThreadAffinity
affinity = ThreadAffinity
Unbound,
$sel:allocationLimit:ThreadOptions :: Maybe ByteCount
allocationLimit = Maybe ByteCount
forall a. Maybe a
Nothing,
$sel:label:ThreadOptions :: String
label = String
"",
$sel:maskingState:ThreadOptions :: MaskingState
maskingState = MaskingState
Unmasked
}
data ThreadFailed = ThreadFailed
{ ThreadFailed -> Int
childId :: {-# UNPACK #-} !Int,
ThreadFailed -> SomeException
exception :: !SomeException
}
deriving stock (Int -> ThreadFailed -> ShowS
[ThreadFailed] -> ShowS
ThreadFailed -> String
(Int -> ThreadFailed -> ShowS)
-> (ThreadFailed -> String)
-> ([ThreadFailed] -> ShowS)
-> Show ThreadFailed
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [ThreadFailed] -> ShowS
$cshowList :: [ThreadFailed] -> ShowS
show :: ThreadFailed -> String
$cshow :: ThreadFailed -> String
showsPrec :: Int -> ThreadFailed -> ShowS
$cshowsPrec :: Int -> ThreadFailed -> ShowS
Show)
instance Exception ThreadFailed where
toException :: ThreadFailed -> SomeException
toException = ThreadFailed -> SomeException
forall e. Exception e => e -> SomeException
asyncExceptionToException
fromException :: SomeException -> Maybe ThreadFailed
fromException = SomeException -> Maybe ThreadFailed
forall e. Exception e => SomeException -> Maybe e
asyncExceptionFromException
unwrapThreadFailed :: SomeException -> SomeException
unwrapThreadFailed :: SomeException -> SomeException
unwrapThreadFailed SomeException
e0 =
case SomeException -> Maybe ThreadFailed
forall e. Exception e => SomeException -> Maybe e
fromException SomeException
e0 of
Just (ThreadFailed Int
_ SomeException
e1) -> SomeException
e1
Maybe ThreadFailed
Nothing -> SomeException
e0
await :: Thread a -> STM a
await :: forall a. Thread a -> STM a
await =
Thread a -> STM a
forall a. Thread a -> STM a
await_
tryEitherSTM :: Exception e => (e -> STM b) -> (a -> STM b) -> STM a -> STM b
tryEitherSTM :: forall e b a.
Exception e =>
(e -> STM b) -> (a -> STM b) -> STM a -> STM b
tryEitherSTM e -> STM b
onFailure a -> STM b
onSuccess STM a
action =
STM (STM b) -> STM b
forall (m :: * -> *) a. Monad m => m (m a) -> m a
join (STM (STM b) -> (e -> STM (STM b)) -> STM (STM b)
forall e a. Exception e => STM a -> (e -> STM a) -> STM a
catchSTM (a -> STM b
onSuccess (a -> STM b) -> STM a -> STM (STM b)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> STM a
action) (STM b -> STM (STM b)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (STM b -> STM (STM b)) -> (e -> STM b) -> e -> STM (STM b)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. e -> STM b
onFailure))