{-

I/O, asynchronous, with task results discarded

This is just the same as its STM equivalent, but with an 'atomically' thrown in for convenience.

-}

module Unfork.Async.FireAndForget.IO
    (
        unforkAsyncIO_,
    )
    where

import Unfork.Async.Core

import Prelude (IO, pure)

import Control.Monad.STM (atomically)

{- |

    Turns an IO action into a fire-and-forget async action

    For example, use @('unforkAsyncIO_' 'System.IO.putStrLn')@ to log to 'System.IO.stdout' in a multi-threaded application.

    Related functions:

      - 'Unfork.unforkAsyncIO' does not discard the action result, and it allows polling or waiting for completion
      - 'Unfork.unforkAsyncSTM_' gives the unforked action result as 'Control.Monad.STM.STM' instead of 'IO'

-}

unforkAsyncIO_ ::
    (task -> IO result) -- ^ Action that needs to be run serially
    -> ((task -> IO ()) -> IO conclusion) -- ^ Continuation with the unforked action
    -> IO conclusion

unforkAsyncIO_ :: (task -> IO result)
-> ((task -> IO ()) -> IO conclusion) -> IO conclusion
unforkAsyncIO_ task -> IO result
action =
    Unfork task (IO ())
-> ((task -> IO ()) -> IO conclusion) -> IO conclusion
forall a c b. Unfork a c -> ((a -> c) -> IO b) -> IO b
unforkAsync Unfork :: forall a c q. (Ctx q -> a -> c) -> (q -> IO ()) -> Unfork a c
Unfork{ Ctx task -> task -> IO ()
forall q. Ctx q -> q -> IO ()
unforkedAction :: Ctx task -> task -> IO ()
unforkedAction :: forall q. Ctx q -> q -> IO ()
unforkedAction, task -> IO ()
executeOneTask :: task -> IO ()
executeOneTask :: task -> IO ()
executeOneTask }
  where
    unforkedAction :: Ctx q -> q -> IO ()
unforkedAction Ctx q
ctx q
arg = STM () -> IO ()
forall a. STM a -> IO a
atomically (Ctx q -> q -> STM ()
forall q. Ctx q -> q -> STM ()
enqueue Ctx q
ctx q
arg)
    executeOneTask :: task -> IO ()
executeOneTask task
a = do{ result
_ <- task -> IO result
action task
a; () -> IO ()
forall (f :: * -> *) a. Applicative f => a -> f a
pure () }