-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/
-- | A lightweight, structured-concurrency library
--
-- A lightweight, structured-concurrency library.
--
-- This package comes in two variants:
--
--
-- - Ki exposes the most stripped-down variant; start here.
-- - Ki.Implicit extends Ki with an implicit context
-- that's used to propagate soft cancellation signals.
--
--
-- Using this variant comes at a cost:
--
--
-- - You must manually add constraints to propagate the implicit
-- context to where it's needed.
-- - To remain warning-free, you must delete the implicit context
-- constraints where they are no longer needed.
--
--
-- If you don't need soft-cancellation, there is no benefit to using this
-- variant, and you should stick with Ki.
--
-- Because you'll only ever need one variant at a time, I recommend using
-- a mixin stanza to rename one module to Ki while hiding
-- the others. This also simplifies the process of upgrading from
-- Ki.Implicit to Ki if necessary.
--
--
-- mixins: ki (Ki.Implicit as Ki)
--
@package ki
@version 0.2.0
module Ki.Internal
-- | A cancel token represents a request for cancellation; this
-- request can be fulfilled by throwing the token as an exception.
newtype CancelToken
CancelToken :: Int -> CancelToken
newCancelToken :: IO CancelToken
data Context
Context :: IO () -> STM CancelToken -> STM Context -> Context
[$sel:cancelContext:Context] :: Context -> IO ()
[$sel:contextCancelTokenSTM:Context] :: Context -> STM CancelToken
-- | Derive a child context from a parent context.
--
--
-- - If the parent is already cancelled, so is the child.
-- - If the parent isn't already canceled, the child registers itself
-- with the parent such that:
-- - When the parent is cancelled, so is the child
-- - When the child is cancelled, it removes the parent's reference to
-- it
--
[$sel:deriveContext:Context] :: Context -> STM Context
dummyContext :: Context
-- | The global context. It cannot be cancelled.
globalContext :: Context
data Ctx
Ctx :: TVar (Maybe CancelToken) -> TVar (IntMap Ctx) -> TVar Int -> STM () -> Ctx
[$sel:cancelTokenVar:Ctx] :: Ctx -> TVar (Maybe CancelToken)
[$sel:childrenVar:Ctx] :: Ctx -> TVar (IntMap Ctx)
-- | The next id to assign to a child context. The child needs a unique
-- identifier so it can delete itself from its parent's children map if
-- it's cancelled independently. Wrap-around seems ok; that's a *lot* of
-- children for one parent to have.
[$sel:nextIdVar:Ctx] :: Ctx -> TVar Int
-- | When I'm cancelled, this action removes myself from my parent's
-- context. This isn't simply a pointer to the parent Ctx for
-- three reasons:
--
--
-- - Root contexts don't have a parent, so it'd have to be a
-- Maybe (one more pointer indirection)
-- - We don't really need a reference to the parent, because we only
-- want to be able to remove ourselves from its children map, so just
-- storing the STM action that does exactly seems a bit safer, even if
-- conceptually it's a bit indirect.
-- - If we stored a reference to the parent, we'd also have to store
-- our own id, rather than just currying it into this action.
--
[$sel:onCancel:Ctx] :: Ctx -> STM ()
newCtxSTM :: STM Ctx
deriveCtx :: Ctx -> STM Ctx
cancelCtx :: Ctx -> IO ()
cancelCtxSTM :: Ctx -> CancelToken -> STM ()
ctxCancelToken :: Ctx -> STM CancelToken
-- | A length of time with microsecond precision. Numeric literals are
-- treated as seconds.
newtype Duration
Duration :: Fixed E6 -> Duration
toMicroseconds :: Duration -> Int
-- | One microsecond.
microseconds :: Duration
-- | One millisecond.
milliseconds :: Duration
-- | One second.
seconds :: Duration
-- | A scope delimits the lifetime of all threads created
-- within it.
data Scope
Scope :: Context -> TVar Bool -> TVar (Set ThreadId) -> TVar Int -> Scope
[$sel:context:Scope] :: Scope -> Context
-- | Whether this scope is closed. Invariant: if closed, no threads are
-- starting.
[$sel:closedVar:Scope] :: Scope -> TVar Bool
-- | The set of threads that are currently running.
[$sel:runningVar:Scope] :: Scope -> TVar (Set ThreadId)
-- | The number of threads that are *guaranteed* to be about to start, in
-- the sense that only the GHC scheduler can continue to delay; no async
-- exception can strike here and prevent one of these threads from
-- starting.
--
-- If this number is non-zero, and that's problematic (e.g. because we're
-- trying to cancel this scope), we always respect it and wait for it to
-- drop to zero before proceeding.
[$sel:startingVar:Scope] :: Scope -> TVar Int
-- | Cancel all contexts derived from a scope.
cancel :: Scope -> IO ()
scopeCancelledSTM :: Scope -> STM (IO a)
scopeFork :: Scope -> ((forall x. IO x -> IO x) -> IO a) -> (Either SomeException a -> IO ()) -> IO ThreadId
scoped :: Context -> (Scope -> IO a) -> IO a
-- | Wait until all threads created within a scope finish.
wait :: Scope -> IO ()
-- | Variant of wait that waits for up to the given duration.
waitFor :: Scope -> Duration -> IO ()
-- | STM variant of wait.
waitSTM :: Scope -> STM ()
-- | Exception thrown by a parent thread to its children when the
-- scope is closing.
data ScopeClosing
ScopeClosing :: ScopeClosing
-- | Exception thrown by a child thread to its parent, if it fails
-- unexpectedly.
newtype ThreadFailed
ThreadFailed :: SomeException -> ThreadFailed
-- | A running thread.
data Thread a
Thread :: !ThreadId -> !STM a -> Thread a
-- | Create a thread within a scope.
--
-- Throws:
--
--
-- - Calls error if the scope is closed.
--
async :: Scope -> IO a -> IO (Thread (Either SomeException a))
-- | Variant of async that provides the thread a function
-- that unmasks asynchronous exceptions.
--
-- Throws:
--
--
-- - Calls error if the scope is closed.
--
asyncWithUnmask :: Scope -> ((forall x. IO x -> IO x) -> IO a) -> IO (Thread (Either SomeException a))
-- | Wait for a thread to finish.
await :: Thread a -> IO a
-- | STM variant of await.
awaitSTM :: Thread a -> STM a
-- | Variant of await that gives up after the given duration.
awaitFor :: Thread a -> Duration -> IO (Maybe a)
-- | Create a thread within a scope.
--
-- If the thread throws an exception, the exception is immediately
-- propagated up the call tree to the thread that opened its
-- scope.
--
-- Throws:
--
--
-- - Calls error if the scope is closed.
--
fork :: Scope -> IO a -> IO (Thread a)
-- | Variant of fork that does not return a handle to the created
-- thread.
--
-- Throws:
--
--
-- - Calls error if the scope is closed.
--
fork_ :: Scope -> IO () -> IO ()
-- | Variant of fork that provides the thread a function that
-- unmasks asynchronous exceptions.
--
-- Throws:
--
--
-- - Calls error if the scope is closed.
--
forkWithUnmask :: Scope -> ((forall x. IO x -> IO x) -> IO a) -> IO (Thread a)
-- | Variant of forkWithUnmask that does not return a handle to the
-- created thread.
--
-- Throws:
--
--
-- - Calls error if the scope is closed.
--
forkWithUnmask_ :: Scope -> ((forall x. IO x -> IO x) -> IO ()) -> IO ()
-- | Wait for an STM action to return an IO action, or if
-- the given duration elapses, return the given IO action
-- instead.
timeoutSTM :: Duration -> STM (IO a) -> IO a -> IO a
module Ki.Implicit
-- | A context models a program's call tree, and is used as a
-- mechanism to propagate cancellation requests to every
-- thread created within a scope.
--
-- Every thread is provided its own context, which is
-- derived from its scope.
--
-- A thread can query whether its context has been
-- cancelled, which is a suggestion to perform a graceful
-- termination.
type Context = ?context :: Context
-- | Perform an IO action in the global context. The global
-- context cannot be cancelled.
withGlobalContext :: (Context => IO a) -> IO a
-- | A scope delimits the lifetime of all threads created
-- within it.
data Scope
-- | Open a scope, perform an IO action with it, then close
-- the scope.
--
-- When the scope is closed, all remaining threads created
-- within it are killed.
--
-- Throws:
--
--
-- - The exception thrown by the callback to scoped itself, if
-- any.
-- - The first exception thrown by or to a thread created with
-- fork, if any.
--
--
-- Examples
--
--
-- scoped \scope -> do
-- fork_ scope worker1
-- fork_ scope worker2
-- wait scope
--
scoped :: Context => (Context => Scope -> IO a) -> IO a
-- | Wait until all threads created within a scope finish.
wait :: Scope -> IO ()
-- | STM variant of wait.
waitSTM :: Scope -> STM ()
-- | Variant of wait that waits for up to the given duration. This
-- is useful for giving threads some time to fulfill a
-- cancellation request before killing them.
waitFor :: Scope -> Duration -> IO ()
-- | A running thread.
data Thread a
-- | Create a thread within a scope.
--
-- If the thread throws an exception, the exception is immediately
-- propagated up the call tree to the thread that opened its
-- scope, unless that exception is a CancelToken that
-- fulfills a cancellation request.
--
-- Throws:
--
--
-- - Calls error if the scope is closed.
--
fork :: Scope -> (Context => IO a) -> IO (Thread a)
-- | Variant of fork that does not return a handle to the created
-- thread.
--
-- Throws:
--
--
-- - Calls error if the scope is closed.
--
fork_ :: Scope -> (Context => IO ()) -> IO ()
-- | Variant of fork that provides the thread a function that
-- unmasks asynchronous exceptions.
--
-- Throws:
--
--
-- - Calls error if the scope is closed.
--
forkWithUnmask :: Scope -> (Context => (forall x. IO x -> IO x) -> IO a) -> IO (Thread a)
-- | Variant of forkWithUnmask that does not return a handle to the
-- created thread.
--
-- Throws:
--
--
-- - Calls error if the scope is closed.
--
forkWithUnmask_ :: Scope -> (Context => (forall x. IO x -> IO x) -> IO ()) -> IO ()
-- | Create a thread within a scope.
--
-- Throws:
--
--
-- - Calls error if the scope is closed.
--
async :: Scope -> (Context => IO a) -> IO (Thread (Either SomeException a))
-- | Variant of async that provides the thread a function
-- that unmasks asynchronous exceptions.
--
-- Throws:
--
--
-- - Calls error if the scope is closed.
--
asyncWithUnmask :: Scope -> (Context => (forall x. IO x -> IO x) -> IO a) -> IO (Thread (Either SomeException a))
-- | Wait for a thread to finish.
await :: Thread a -> IO a
-- | STM variant of await.
awaitSTM :: Thread a -> STM a
-- | Variant of await that gives up after the given duration.
awaitFor :: Thread a -> Duration -> IO (Maybe a)
-- | A cancel token represents a request for cancellation; this
-- request can be fulfilled by throwing the token as an exception.
data CancelToken
-- | Cancel all contexts derived from a scope.
cancel :: Scope -> IO ()
-- | Return whether the current context is cancelled.
--
-- Threads running in a cancelled context should
-- terminate as soon as possible. The cancel token may be thrown to
-- fulfill the cancellation request in case the thread is
-- unable or unwilling to terminate normally with a value.
cancelled :: Context => IO (Maybe CancelToken)
-- | STM variant of cancelled; blocks until the current
-- context is cancelled.
cancelledSTM :: Context => STM CancelToken
-- | A length of time with microsecond precision. Numeric literals are
-- treated as seconds.
data Duration
-- | One microsecond.
microseconds :: Duration
-- | One millisecond.
milliseconds :: Duration
-- | One second.
seconds :: Duration
-- | Wait for an STM action to return an IO action, or if
-- the given duration elapses, return the given IO action
-- instead.
timeoutSTM :: Duration -> STM (IO a) -> IO a -> IO a
-- | Context-aware, duration-based threadDelay.
--
-- Throws:
--
--
-- - Throws CancelToken if the current context is (or
-- becomes) cancelled.
--
sleep :: Context => Duration -> IO ()
module Ki
-- | A scope delimits the lifetime of all threads created
-- within it.
data Scope
-- | Open a scope, perform an IO action with it, then close
-- the scope.
--
-- When the scope is closed, all remaining threads created
-- within it are killed.
--
-- Throws:
--
--
-- - The exception thrown by the callback to scoped itself, if
-- any.
-- - The first exception thrown by or to a thread created with
-- fork, if any.
--
--
-- Examples
--
--
-- scoped \scope -> do
-- fork_ scope worker1
-- fork_ scope worker2
-- wait scope
--
scoped :: (Scope -> IO a) -> IO a
-- | Wait until all threads created within a scope finish.
wait :: Scope -> IO ()
-- | STM variant of wait.
waitSTM :: Scope -> STM ()
-- | Variant of wait that waits for up to the given duration.
waitFor :: Scope -> Duration -> IO ()
-- | A running thread.
data Thread a
-- | Create a thread within a scope.
--
-- If the thread throws an exception, the exception is immediately
-- propagated up the call tree to the thread that opened its
-- scope.
--
-- Throws:
--
--
-- - Calls error if the scope is closed.
--
fork :: Scope -> IO a -> IO (Thread a)
-- | Variant of fork that does not return a handle to the created
-- thread.
--
-- Throws:
--
--
-- - Calls error if the scope is closed.
--
fork_ :: Scope -> IO () -> IO ()
-- | Variant of fork that provides the thread a function that
-- unmasks asynchronous exceptions.
--
-- Throws:
--
--
-- - Calls error if the scope is closed.
--
forkWithUnmask :: Scope -> ((forall x. IO x -> IO x) -> IO a) -> IO (Thread a)
-- | Variant of forkWithUnmask that does not return a handle to the
-- created thread.
--
-- Throws:
--
--
-- - Calls error if the scope is closed.
--
forkWithUnmask_ :: Scope -> ((forall x. IO x -> IO x) -> IO ()) -> IO ()
-- | Create a thread within a scope.
--
-- Throws:
--
--
-- - Calls error if the scope is closed.
--
async :: Scope -> IO a -> IO (Thread (Either SomeException a))
-- | Variant of async that provides the thread a function
-- that unmasks asynchronous exceptions.
--
-- Throws:
--
--
-- - Calls error if the scope is closed.
--
asyncWithUnmask :: Scope -> ((forall x. IO x -> IO x) -> IO a) -> IO (Thread (Either SomeException a))
-- | Wait for a thread to finish.
await :: Thread a -> IO a
-- | STM variant of await.
awaitSTM :: Thread a -> STM a
-- | Variant of await that gives up after the given duration.
awaitFor :: Thread a -> Duration -> IO (Maybe a)
-- | A length of time with microsecond precision. Numeric literals are
-- treated as seconds.
data Duration
-- | One microsecond.
microseconds :: Duration
-- | One millisecond.
milliseconds :: Duration
-- | One second.
seconds :: Duration
-- | Wait for an STM action to return an IO action, or if
-- the given duration elapses, return the given IO action
-- instead.
timeoutSTM :: Duration -> STM (IO a) -> IO a -> IO a
-- | Duration-based threadDelay.
sleep :: Duration -> IO ()