stm 2.4 → 2.4.2
raw patch · 4 files changed
+83/−5 lines, 4 files
Files
- Control/Concurrent/STM/TChan.hs +1/−2
- Control/Concurrent/STM/TSem.hs +54/−0
- Control/Monad/STM.hs +18/−2
- stm.cabal +10/−1
Control/Concurrent/STM/TChan.hs view
@@ -97,9 +97,8 @@ -- garbage collected after clients have seen them. newBroadcastTChan :: STM (TChan a) newBroadcastTChan = do- dummy_hole <- newTVar TNil write_hole <- newTVar TNil- read <- newTVar dummy_hole+ read <- newTVar (error "reading from a TChan created by newBroadcastTChan; use dupTChan first") write <- newTVar write_hole return (TChan read write)
+ Control/Concurrent/STM/TSem.hs view
@@ -0,0 +1,54 @@+-----------------------------------------------------------------------------+-- |+-- Module : Control.Concurrent.STM.TSem+-- Copyright : (c) The University of Glasgow 2012+-- License : BSD-style (see the file libraries/base/LICENSE)+-- +-- Maintainer : libraries@haskell.org+-- Stability : experimental+-- Portability : non-portable (requires STM)+--+-- 'TSem': transactional semaphores.+--+-----------------------------------------------------------------------------++{-# LANGUAGE DeriveDataTypeable #-}+module Control.Concurrent.STM.TSem (+ TSem, newTSem, waitTSem, signalTSem+ ) where++import Control.Concurrent.STM+import Control.Monad+import Data.Typeable+import Control.Exception++-- | 'TSem' is a transactional semaphore. It holds a certain number+-- of units, and units may be acquired or released by 'waitTSem' and+-- 'signalTSem' respectively. When the 'TSem' is empty, 'waitTSem'+-- blocks.+--+-- Note that 'TSem' has no concept of fairness, and there is no+-- guarantee that threads blocked in `waitTSem` will be unblocked in+-- the same order; in fact they will all be unblocked at the same time+-- and will fight over the 'TSem'. Hence 'TSem' is not suitable if+-- you expect there to be a high number of threads contending for the+-- resource. However, like other STM abstractions, 'TSem' is+-- composable.+--+newtype TSem = TSem (TVar Int)+ deriving (Eq, Typeable)++newTSem :: Int -> STM TSem+newTSem i = fmap TSem (newTVar i)++waitTSem :: TSem -> STM ()+waitTSem (TSem t) = do+ i <- readTVar t+ when (i <= 0) retry+ writeTVar t $! (i-1)++signalTSem :: TSem -> STM ()+signalTSem (TSem t) = do+ i <- readTVar t+ writeTVar t $! i+1+
Control/Monad/STM.hs view
@@ -57,13 +57,29 @@ #ifdef __GLASGOW_HASKELL__ #if ! (MIN_VERSION_base(4,3,0))+import Control.Applicative+import Control.Monad (ap)+#endif+#endif+++#ifdef __GLASGOW_HASKELL__+#if ! (MIN_VERSION_base(4,3,0)) instance MonadPlus STM where mzero = retry mplus = orElse++instance Applicative STM where+ pure = return+ (<*>) = ap++instance Alternative STM where+ empty = retry+ (<|>) = orElse #endif -check :: Bool -> STM a-check b = if b then return undefined else retry+check :: Bool -> STM ()+check b = if b then return () else retry #endif #if ! (MIN_VERSION_base(4,3,0))
stm.cabal view
@@ -1,5 +1,5 @@ name: stm-version: 2.4+version: 2.4.2 license: BSD3 license-file: LICENSE maintainer: libraries@haskell.org@@ -8,6 +8,14 @@ description: A modular composable concurrency abstraction. .+ Changes in version 2.4.2+ .+ * Added "Control.Concurrent.STM.TSem" (transactional semaphore)+ .+ Changes in version 2.4.1+ .+ * Added Applicative/Alternative instances of STM for GHC <7.0+ . Changes in version 2.4 . * Added "Control.Concurrent.STM.TQueue" (a faster @TChan@)@@ -40,6 +48,7 @@ Control.Concurrent.STM.TMVar Control.Concurrent.STM.TQueue Control.Concurrent.STM.TBQueue+ Control.Concurrent.STM.TSem Control.Monad.STM other-modules: Control.Sequential.STM