@@ -9,6 +9,7 @@ module Asyncly.Threads
99 , threads
1010
1111 , async
12+ , makeAsync
1213 , each
1314 , gather
1415
@@ -317,6 +318,25 @@ async action = AsyncT $ do
317318 -- here after it is completely done.
318319 spawningParentDone
319320
321+-- | Makes an asyncly action from a callback setter function; can be used to
322+-- convert existing callback style code into asyncly style code. The first
323+-- parameter is a callback setter function. When we are called back,
324+-- 'makeAsync' behaves as if it was an async computation that just returned a
325+-- value of type 'a'. After the computation is done the result of the action
326+-- in second parameter is returned to the callback.
327+--
328+makeAsync :: (MonadAsync m) => ((a -> m b) -> m ()) -> m b -> AsyncT m a
329+makeAsync cbsetter cbret = AsyncT $ do
330+ val <- takeContextMailBox
331+ case val of
332+ Right m -> runAsyncT m -- child
333+ Left ctx -> do -- parent
334+ lift $ cbsetter $ \a -> do
335+ let s = resumeContextWith ctx False (return a)
336+ _ <- runStateT s ctx
337+ cbret
338+ spawningParentDone
339+
320340-- scatter
321341each :: (MonadIO m, MonadBaseControl IO m, MonadThrow m)
322342 => [a] -> AsyncT m a