----------------------------------------------------------------------------- {-# LANGUAGE ScopedTypeVariables #-} ----------------------------------------------------------------------------- -- | -- Module : Miso.Concurrent -- Copyright : (C) 2016-2025 David M. Johnson -- License : BSD3-style (see the file LICENSE) -- Maintainer : David M. Johnson <code@dmj.io> -- Stability : experimental -- Portability : non-portable ---------------------------------------------------------------------------- module Miso.Concurrent ( -- ** Synchronization primitives Waiter (..) , waiter , oneshot ) where ----------------------------------------------------------------------------- import Control.Concurrent ----------------------------------------------------------------------------- -- | Synchronization primitive for event loop data Waiter = Waiter { Waiter -> IO () wait :: IO () -- ^ Blocks on MVar , Waiter -> IO () notify :: IO () -- ^ Unblocks threads waiting on MVar } ----------------------------------------------------------------------------- -- | Creates a new @Waiter@ -- -- Useful for multiple threads to wake-up / notify a single thread running in an -- infinite loop, waiting for work (e.g. to process an event queue). -- waiter :: IO Waiter waiter :: IO Waiter waiter = do mvar <- IO (MVar ()) forall a. IO (MVar a) newEmptyMVar pure Waiter { wait = takeMVar mvar , notify = do _ <- tryPutMVar mvar () pure () } ----------------------------------------------------------------------------- -- | Creates a new @Waiter@ -- -- Useful for a single thread to wake-up multiple threads that are waiting -- to run a oneshot task (e.g. like forking a thread). -- oneshot :: IO Waiter oneshot :: IO Waiter oneshot = do mvar <- IO (MVar ()) forall a. IO (MVar a) newEmptyMVar pure Waiter { wait = readMVar mvar , notify = putMVar mvar () } -----------------------------------------------------------------------------