#ifdef __GLASGOW_HASKELL__ #endif module Control.Concurrent.QSemN ( QSemN, newQSemN, waitQSemN, signalQSemN ) where import Prelude import Control.Concurrent.MVar import Control.Exception ( mask_ ) import Data.Typeable #include "Typeable.h" newtype QSemN = QSemN (MVar (Int,[(Int,MVar ())])) deriving Eq INSTANCE_TYPEABLE0(QSemN,qSemNTc,"QSemN") newQSemN :: Int -> IO QSemN newQSemN initial = if initial < 0 then fail "newQSemN: Initial quantity must be non-negative" else do sem <- newMVar (initial, []) return (QSemN sem) waitQSemN :: QSemN -> Int -> IO () waitQSemN (QSemN sem) sz = mask_ $ do (avail,blocked) <- takeMVar sem let remaining = avail sz if remaining >= 0 then putMVar sem (remaining,blocked) else do b <- newEmptyMVar putMVar sem (avail, blocked++[(sz,b)]) takeMVar b signalQSemN :: QSemN -> Int -> IO () signalQSemN (QSemN sem) n = mask_ $ do (avail,blocked) <- takeMVar sem (avail',blocked') <- free (avail+n) blocked avail' `seq` putMVar sem (avail',blocked') where free avail [] = return (avail,[]) free avail ((req,b):blocked) | avail >= req = do putMVar b () free (availreq) blocked | otherwise = do (avail',blocked') <- free avail blocked return (avail',(req,b):blocked')
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4