-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/
-- | Supposed to mimics and enhance proposed C++ "future" features
--
-- Similar to futures in C++ (with support for cotinuations). This
-- differs from IVars in that the value is from an action in a spawned
-- thread, and exceptions are caught and returned.
@package future
@version 1.1.0
-- | This Future module was written by Chris Kuklewicz to see if he
-- understood the design and utility of the new C++ standard's future. In
-- particular the ability to cleanly access either a resulting value or
-- exception.
--
-- There a methods to poll (with check), to block (with
-- wait or timedWait), and to block and retrieve the actual
-- value or rethrow the exception in the accessing thread (with
-- get or timedGet). Timeouts are in micro seconds, values
-- less than or equal to zero use non-blocking check. The timeout
-- should be detected reagarless of the blocking or FFI state of the
-- worker thread.
--
-- One can also manage the threadBy calling abort, which may cause
-- the promise to store the exception from the abort as well as killing
-- the worker thread. The worker thread Id is a secret, this is needed to
-- ensure the running of the continuations. The abort operation
-- has the same synchronous behavior as killThread.
--
-- Note: There is no way for an outside thread to directly set the value
-- of the promise to a non-exception value. Using abort (or
-- throwTo with getPromiseThreadId) creates a race
-- condition in setting the result of the promise. There is no way to
-- change the result of promise once it has been set.
--
-- The extension to the C++ standard is in the continuation attachment.
-- The addTodo command will, while the worker is running, add the
-- todo continuation to an internal list. Immediately upon
-- finishing the action the worker thread will always run through the
-- queued continuations. Each todo will be run in its own forkIO
-- thread (unblocked). If the addTodo command is issued after the
-- promise value has been set then it simplify runs the todo in
-- a new thread. Thus there is no way multiple continuations can
-- interfere with each other, and there are no ordering guarantees
-- between them. The todo action will not be able to distinguish
-- whether it is being run from the stored queue or immediately.
--
-- The use of block and finally should ensure that no
-- matter how the worker ends the stored continations are run. For
-- instnace: if abort is used then the continations might be run
-- with that thread killing exception or with the custom
-- Promise.abort exception if no other result is already present.
--
-- One use case for addTodo is to allow multiplexing. Several
-- promises could be given a continuation to write the results to an
-- MChan or MVar, allowing another process to block waiting for the first
-- one to finish.
module Control.Concurrent.Future
data Promise a
type PromiseResult a = Either SomeException a
-- | forkPromise take an action to run, and runs it in a new thread. This
-- is run in an unblock context. If the action succeeds it will
-- store its result as (Right {}). If the action throws an exception, or
-- the
forkPromise :: IO a -> IO (Promise a)
forkPromises :: [IO a] -> IO ([Promise a], Chan (PromiseResult a))
racePromises :: [IO a] -> IO (PromiseResult a)
-- | check is a non-blocking read. Like timedWait with 0
-- delay.
check :: Promise a -> IO (Maybe (PromiseResult a))
-- | wait is a blocking read.
wait :: Promise a -> IO (PromiseResult a)
-- | get is wait which rethrows a SomeException in the calling
-- thread
get :: Promise a -> IO a
-- | timedWait with a positive value in micro seconds is a blocking
-- read with timeout.
timedWait :: Int -> Promise a -> IO (Maybe (PromiseResult a))
-- | timedGet is a timedWait which rethrows a SomeException
-- in the calling thread
timedGet :: Int -> Promise a -> IO (Maybe a)
-- | If the abort occurs before the act has stored a result then the result
-- is set to (userError Promise.abort :: IOError), or the
-- killThread exception.
abort :: Promise t -> IO ()
-- | Post an action to perform in a new thread with the reasult of the
-- promise. All are run unblocked in a fresh thread.
addTodo :: Promise a -> (PromiseResult a -> IO ()) -> IO ()
instance Show (Promise a)
instance Ord (Promise a)
instance Eq (Promise a)