{-| Module: STM.Flag Description: A flag plus a function to run an 'Async' and lower the flag when it's started. Copyright: © 2017 All rights reserved. License: GPL-3 Maintainer: Evan Cofsky Stability: experimental Portability: POSIX -} module STM.Flag where import Lawless import Control.Concurrent.Async.Lifted import Control.Concurrent.STM.TSem import STM.Base -- | A 'Flag' used for mutexes. newtype Flag = Flag TSem -- | Creates a new 'Flag' in the held state. newFlag ∷ (MonadBase IO m) ⇒ m Flag newFlag = Flag <$> atomically (newTSem 0) -- | Waits for a 'Flag' to be unheld. waitFlag ∷ Flag → STM () waitFlag (Flag s) = waitTSem s -- | Signals a 'Flag' has been released. lowerFlag ∷ Flag → STM () lowerFlag (Flag s) = signalTSem s -- | Runs @f@ in a new 'Async', waiting for the 'Async' to start -- before continuing. run ∷ MonadBaseControl IO m ⇒ m a → m (Async (StM m a)) run f = do g ← newFlag a ← async $ do atomically $ lowerFlag g f atomically $ waitFlag g return a