-- 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 2.0.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. -- -- On top of forkPromise is forkPromises, -- racePromises, and declarePromise. -- -- 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 -- instance: 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) -- | declarePromise is built on top of forkPromise. It creates a promise -- and an function to fulfill the promise with an action. The first time -- the fulfull function is used it gives the action to the promise and -- returns True. All additional usages of the fulfill function will do -- nothing and return False. Note that the Promise may be aborted before -- the fulfill function is used, and in this case the fulfill function -- will appear to succeed but achieve nothing. declarePromise :: IO (Promise a, IO a -> IO Bool) -- | forkPromises is build on top of forkPromise. It converts a list of -- actions into a list of promises, and additionally collects the -- results, in completion order, into the returned Chan. forkPromises :: [IO a] -> IO ([Promise a], Chan (PromiseResult a)) -- | racePromises is build on top of forkPromise. It runs a list of actions -- as promises and waits for the first result (which may be an -- exception). Once the result is found it asynchronously kills the -- threads. 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 action has stored a result then the -- result is set to an exception. The first call to abort gets the -- threadId and performs the, possibly blocking, killThread. If it -- completes then the ThreadId is forgotten (so the thread can be garbage -- collected). 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 Eq (Promise a)