ivar-simple 0.2 → 0.3
raw patch · 6 files changed
+44/−24 lines, 6 filesdep ~base
Dependency ranges changed: base
Files
- HISTORY +4/−0
- LICENSE +1/−1
- ivar-simple.cabal +7/−6
- src/Data/IVar/Simple.hs +24/−9
- src/Data/IVar/Simple/IChan.hs +4/−4
- src/Data/IVar/Simple/MIChan.hs +4/−4
HISTORY view
@@ -1,3 +1,7 @@+0.3 (2012-07-24)+ change NonTermination to a custom BlockedIndefinitelyOnIVar exception,+ and require base >= 4. (using NonTermination leads to <<loop>> messages)+ 0.2 (2012-07-23) change BlockedIndefinitely exception (gone since ghc 7.0) to NonTermination
LICENSE view
@@ -1,4 +1,4 @@-Copyright (c) 2008, 2009 Bertram Felgenhauer+Copyright (c) 2008-2012 Bertram Felgenhauer Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal
ivar-simple.cabal view
@@ -1,5 +1,5 @@ Name: ivar-simple-Version: 0.2+Version: 0.3 Category: Concurrency Stability: experimental Copyright: (c) 2008-2012 Bertram Felgenhauer@@ -19,12 +19,13 @@ HISTORY Library- HS-Source-Dirs: src+ Hs-Source-Dirs:+ src Exposed-Modules: Data.IVar.Simple Data.IVar.Simple.IChan Data.IVar.Simple.MIChan- Build-Depends: base < 5- -- workaround for http://hackage.haskell.org/trac/ghc/ticket/2756- if impl(ghc <= 6.10.1)- GHC-Options: -fno-state-hack+ Build-Depends:+ base >= 4 && < 5+ Extensions:+ DeriveDataTypeable
src/Data/IVar/Simple.hs view
@@ -1,6 +1,7 @@+{-# LANGUAGE DeriveDataTypeable #-} -- | -- Module : Data.IVar.Simple--- Copyright : (c) 2008-2012 Bertram Felgenhauer+-- Copyright : (c) 2008, 2009 Bertram Felgenhauer -- License : BSD3 -- -- Maintainer : Bertram Felgenhauer <int-e@gmx.de>@@ -23,18 +24,20 @@ tryRead, write, tryWrite,+ BlockedIndefinitelyOnIVar, ) where import Control.Concurrent.MVar import Control.Exception import Control.Monad+import Data.Typeable import System.IO.Unsafe import Prelude hiding (read) -- | A write-once (/immutable/) Variable data IVar a = IVar (MVar ()) (MVar a) a --- | Creates a new, empty 'IVar'.+-- | Create a new, empty 'IVar'. new :: IO (IVar a) new = do lock <- newMVar ()@@ -53,30 +56,42 @@ -- | Returns the value of an 'IVar'. ----- The evaluation will block until a value is written to the 'IVar' if there--- is no value yet.+-- The evaluation will block until a value is written to the 'IVar' if it+-- has no value yet. read :: IVar a -> a read (IVar _ _ value) = value --- | Try to read an 'IVar'. Returns 'Nothing' if there is not value yet.+-- | Try to read an 'IVar'. Returns 'Nothing' if it has no value yet. tryRead :: IVar a -> IO (Maybe a) tryRead (IVar lock _ value) = do empty <- isEmptyMVar lock if empty then return (Just value) else return Nothing --- | Writes a value to an 'IVar'. Raises a 'NonTermination' exception if--- it fails.+-- | Writes a value to an 'IVar'. Raises a 'BlockedIndefinitelyOnIVar'+-- exception if the variable already has a value. write :: IVar a -> a -> IO () write ivar value = do result <- tryWrite ivar value- when (not result) $ throwIO NonTermination+ when (not result) $ throwIO BlockedIndefinitelyOnIVar -- Note: It would be easier to block forever when the IVar is full. However, -- the thread would likely not be garbage collected then. --- | Writes a value to an 'IVar'. Returns 'True' if successful.+-- | Writes a value to an 'IVar'. Returns 'True' if successful, and+-- 'False' otherwise. tryWrite :: IVar a -> a -> IO Bool tryWrite (IVar lock trans _) value = block $ do a <- tryTakeMVar lock case a of Just _ -> putMVar trans value >> return True Nothing -> return False++-- | The thread has attempted to write to a full 'IVar'.+data BlockedIndefinitelyOnIVar = BlockedIndefinitelyOnIVar+ deriving (Typeable)++instance Exception BlockedIndefinitelyOnIVar++instance Show BlockedIndefinitelyOnIVar where+ showsPrec _ BlockedIndefinitelyOnIVar =+ showString "thread blocked indefinitely writing full IVar"+
src/Data/IVar/Simple/IChan.hs view
@@ -8,8 +8,8 @@ -- Portability : ghc -- -- An 'IChan's is a type of multicast channel built on top of 'IVar.IVar's.--- It supports multiple readers. The 'IChan' data type represents the head--- of a channel.+-- It supports multiple readers. The channel is represented as a linked+-- list. The 'IChan' data type represents the head of a channel. -- -- Writing to an 'IChan' head has write-once semantics similar to 'IVar.IVar's: -- only the first of several attempts to write to the head will succeed,@@ -45,8 +45,8 @@ -- | Write a single value to the channel. ----- Raises a 'NonTermination' exception if a value has already been--- written to the channel. Otherwise, returns a new channel head for+-- Raises a 'BlockedIndefinitelyOnIVar' exception if a value has already+-- been written to the channel. Otherwise, returns a new channel head for -- writing further values. write :: IChan a -> a -> IO (IChan a) write (IChan as) a = do
src/Data/IVar/Simple/MIChan.hs view
@@ -1,6 +1,6 @@ -- | -- Module : Data.IVar.Simple.MIChan--- Copyright : (c) 2008, 2009 Bertram Felgenhauer+-- Copyright : (c) 2008-2012 Bertram Felgenhauer -- License : BSD3 -- -- Maintainer : Bertram Felgenhauer <int-e@gmx.de>@@ -9,9 +9,9 @@ -- -- An 'MIChan' is a multicast channel built on top of an 'IChan.IChan'. ----- Like 'IChan.IChan', this supports multiple readers. It is comparable to--- a @Control.Concurrent.Chan.Chan@ for the writing end: Each write will--- append an element to the channel. No writes will fail.+-- Like 'IChan.IChan', this channel supports multiple readers. It is+-- comparable to a @Control.Concurrent.Chan.Chan@ for the writing end:+-- Each write will append an element to the channel. No writes will fail. module Data.IVar.Simple.MIChan ( -- $comparison