-- | -- Module : Control.Concurrent.Classy.QSem -- Copyright : (c) 2016 Michael Walker -- License : MIT -- Maintainer : Michael Walker <mike@barrucadu.co.uk> -- Stability : stable -- Portability : portable -- -- Simple quantity semaphores. module Control.Concurrent.Classy.QSem ( -- * Simple Quantity Semaphores QSem , newQSem , waitQSem , signalQSem ) where import Control.Concurrent.Classy.QSemN import Control.Monad.Conc.Class (MonadConc) import Control.Monad.Fail (MonadFail) -- | @QSem@ is a quantity semaphore in which the resource is acquired -- and released in units of one. It provides guaranteed FIFO ordering -- for satisfying blocked 'waitQSem' calls. -- -- The pattern -- -- > bracket_ qaitQSem signalSSem (...) -- -- is safe; it never loses a unit of the resource. -- -- @since 1.0.0.0 newtype QSem m = QSem (QSemN m) -- | Build a new 'QSem' with a supplied initial quantity. The initial -- quantity must be at least 0. -- -- @since 1.0.0.0 newQSem :: (MonadConc m, MonadFail m) => Int -> m (QSem m) newQSem initial | initial < 0 = fail "newQSem: Initial quantity mus tbe non-negative." | otherwise = QSem <$> newQSemN initial -- | Wait for a unit to become available. -- -- @since 1.0.0.0 waitQSem :: MonadConc m => QSem m -> m () waitQSem (QSem qSemN) = waitQSemN qSemN 1 -- | Signal that a unit of the 'QSem' is available. -- -- @since 1.0.0.0 signalQSem :: MonadConc m => QSem m -> m () signalQSem (QSem qSemN) = signalQSemN qSemN 1