Tweak docs
[ghc-base.git] / Control / Concurrent / QSem.hs
index 2ef6dff..cc78470 100644 (file)
 -----------------------------------------------------------------------------
 
 module Control.Concurrent.QSem
-       ( -- * Simple Quantity Semaphores
-         QSem,         -- abstract
-         newQSem,      -- :: Int  -> IO QSem
-         waitQSem,     -- :: QSem -> IO ()
-         signalQSem    -- :: QSem -> IO ()
-       ) where
+        ( -- * Simple Quantity Semaphores
+          QSem,         -- abstract
+          newQSem,      -- :: Int  -> IO QSem
+          waitQSem,     -- :: QSem -> IO ()
+          signalQSem    -- :: QSem -> IO ()
+        ) where
 
 import Prelude
 import Control.Concurrent.MVar
+import Data.Typeable
+
+#include "Typeable.h"
 
 -- General semaphores are also implemented readily in terms of shared
 -- @MVar@s, only have to catch the case when the semaphore is tried
@@ -34,11 +37,16 @@ import Control.Concurrent.MVar
 -- \"quantity\" is always dealt with in units of one.
 newtype QSem = QSem (MVar (Int, [MVar ()]))
 
--- |Build a new 'QSem'
+INSTANCE_TYPEABLE0(QSem,qSemTc,"QSem")
+
+-- |Build a new 'QSem' with a supplied initial quantity.
+--  The initial quantity must be at least 0.
 newQSem :: Int -> IO QSem
-newQSem init = do
-   sem <- newMVar (init,[])
-   return (QSem sem)
+newQSem initial =
+    if initial < 0
+    then fail "newQSem: Initial quantity must be non-negative"
+    else do sem <- newMVar (initial, [])
+            return (QSem sem)
 
 -- |Wait for a unit to become available
 waitQSem :: QSem -> IO ()
@@ -49,13 +57,13 @@ waitQSem (QSem sem) = do
     else do
      block <- newEmptyMVar
       {-
-       Stuff the reader at the back of the queue,
-       so as to preserve waiting order. A signalling
-       process then only have to pick the MVar at the
-       front of the blocked list.
+        Stuff the reader at the back of the queue,
+        so as to preserve waiting order. A signalling
+        process then only have to pick the MVar at the
+        front of the blocked list.
 
-       The version of waitQSem given in the paper could
-       lead to starvation.
+        The version of waitQSem given in the paper could
+        lead to starvation.
       -}
      putMVar sem (0, blocked++[block])
      takeMVar block
@@ -68,5 +76,5 @@ signalQSem (QSem sem) = do
      [] -> putMVar sem (avail+1,[])
 
      (block:blocked') -> do
-          putMVar sem (0,blocked')
-          putMVar block ()
+           putMVar sem (0,blocked')
+           putMVar block ()