Clean up and add documentation
This commit is contained in:
parent
d03e2922e9
commit
9636e1eb4d
1 changed files with 68 additions and 10 deletions
|
|
@ -1,24 +1,39 @@
|
||||||
{-# LANGUAGE RecordWildCards #-}
|
{-# LANGUAGE RecordWildCards #-}
|
||||||
|
|
||||||
|
-- | Chans that can be closed and reopened.
|
||||||
|
--
|
||||||
|
-- While a 'CloseableChan' is closed (or locked), it can not be written to or read from.
|
||||||
|
-- Calls to 'writeChan' and 'readChan' are non-blocking while a chan is closed.
|
||||||
|
--
|
||||||
|
-- If a thread is attempting to read from a chan using 'readChan' and that chan is closed,
|
||||||
|
-- the call to 'readChan' resumes and @Nothing@ is returned.
|
||||||
|
|
||||||
module EuphApi.CloseableChan
|
module EuphApi.CloseableChan
|
||||||
( CloseableChan
|
( CloseableChan
|
||||||
-- * IO versions
|
-- * IO function versions
|
||||||
, newCloseableChan
|
, newOpenChan
|
||||||
|
, newClosedChan
|
||||||
, writeChan
|
, writeChan
|
||||||
, readChan
|
, readChan
|
||||||
, closeChan
|
, closeChan
|
||||||
|
, openChan
|
||||||
, emptyChan
|
, emptyChan
|
||||||
-- * STM versions
|
-- * STM function versions
|
||||||
, newCloseableChanSTM
|
, newOpenChanSTM
|
||||||
|
, newClosedChanSTM
|
||||||
, writeChanSTM
|
, writeChanSTM
|
||||||
, readChanSTM
|
, readChanSTM
|
||||||
, closeChanSTM
|
, closeChanSTM
|
||||||
|
, openChanSTM
|
||||||
, emptyChanSTM
|
, emptyChanSTM
|
||||||
) where
|
) where
|
||||||
|
|
||||||
import Control.Concurrent.STM
|
import Control.Concurrent.STM
|
||||||
import Control.Monad
|
|
||||||
|
|
||||||
|
-- | A 'Chan' that can be closed and opened again.
|
||||||
|
--
|
||||||
|
-- Attempts to write to or read from a 'CloseableChan' while it is closed result
|
||||||
|
-- in a @Nothing@.
|
||||||
data CloseableChan a = CloseableChan
|
data CloseableChan a = CloseableChan
|
||||||
{ cClosed :: TVar Bool
|
{ cClosed :: TVar Bool
|
||||||
, cChan :: TChan (Content a)
|
, cChan :: TChan (Content a)
|
||||||
|
|
@ -31,12 +46,21 @@ data Content a = Value a
|
||||||
- Functions as STM actions
|
- Functions as STM actions
|
||||||
-}
|
-}
|
||||||
|
|
||||||
newCloseableChanSTM :: STM (CloseableChan a)
|
-- | See 'newOpenChan'.
|
||||||
newCloseableChanSTM = do
|
newOpenChanSTM :: STM (CloseableChan a)
|
||||||
|
newOpenChanSTM = do
|
||||||
cClosed <- newTVar False
|
cClosed <- newTVar False
|
||||||
cChan <- newTChan
|
cChan <- newTChan
|
||||||
return $ CloseableChan{..}
|
return $ CloseableChan{..}
|
||||||
|
|
||||||
|
-- | See 'newClosedChan'.
|
||||||
|
newClosedChanSTM :: STM (CloseableChan a)
|
||||||
|
newClosedChanSTM = do
|
||||||
|
cClosed <- newTVar True
|
||||||
|
cChan <- newTChan
|
||||||
|
return $ CloseableChan{..}
|
||||||
|
|
||||||
|
-- | See 'writeChan'.
|
||||||
writeChanSTM :: CloseableChan a -> a -> STM (Maybe ())
|
writeChanSTM :: CloseableChan a -> a -> STM (Maybe ())
|
||||||
writeChanSTM CloseableChan{..} a = do
|
writeChanSTM CloseableChan{..} a = do
|
||||||
closed <- readTVar cClosed
|
closed <- readTVar cClosed
|
||||||
|
|
@ -44,6 +68,7 @@ writeChanSTM CloseableChan{..} a = do
|
||||||
then return Nothing
|
then return Nothing
|
||||||
else Just <$> writeTChan cChan (Value a)
|
else Just <$> writeTChan cChan (Value a)
|
||||||
|
|
||||||
|
-- | See 'readChan'.
|
||||||
readChanSTM :: CloseableChan a -> STM (Maybe a)
|
readChanSTM :: CloseableChan a -> STM (Maybe a)
|
||||||
readChanSTM CloseableChan{..} = do
|
readChanSTM CloseableChan{..} = do
|
||||||
closed <- readTVar cClosed
|
closed <- readTVar cClosed
|
||||||
|
|
@ -57,11 +82,18 @@ readChanSTM CloseableChan{..} = do
|
||||||
End -> readValue -- ignore End while reading normally
|
End -> readValue -- ignore End while reading normally
|
||||||
Value v -> return v
|
Value v -> return v
|
||||||
|
|
||||||
|
-- | See 'closeChan'.
|
||||||
closeChanSTM :: CloseableChan a -> STM ()
|
closeChanSTM :: CloseableChan a -> STM ()
|
||||||
closeChanSTM CloseableChan{..} = do
|
closeChanSTM CloseableChan{..} = do
|
||||||
writeTVar cClosed True
|
writeTVar cClosed True
|
||||||
--writeTChan cChan End
|
--writeTChan cChan End
|
||||||
|
|
||||||
|
-- | See 'openChan'.
|
||||||
|
openChanSTM :: CloseableChan a -> STM ()
|
||||||
|
openChanSTM CloseableChan{..} = do
|
||||||
|
writeTVar cClosed False
|
||||||
|
|
||||||
|
-- | See 'emptyChan'.
|
||||||
emptyChanSTM :: CloseableChan a -> STM [a]
|
emptyChanSTM :: CloseableChan a -> STM [a]
|
||||||
emptyChanSTM CloseableChan{..} = do
|
emptyChanSTM CloseableChan{..} = do
|
||||||
writeTChan cChan End
|
writeTChan cChan End
|
||||||
|
|
@ -77,17 +109,43 @@ emptyChanSTM CloseableChan{..} = do
|
||||||
- Functions as IO actions
|
- Functions as IO actions
|
||||||
-}
|
-}
|
||||||
|
|
||||||
newCloseableChan :: IO (CloseableChan a)
|
-- | Create a new open 'CloseableChan'.
|
||||||
newCloseableChan = atomically newCloseableChanSTM
|
newOpenChan :: IO (CloseableChan a)
|
||||||
|
newOpenChan = atomically newOpenChanSTM
|
||||||
|
|
||||||
|
-- | Create a new closed 'CloseableChan'.
|
||||||
|
newClosedChan :: IO (CloseableChan a)
|
||||||
|
newClosedChan = atomically newClosedChanSTM
|
||||||
|
|
||||||
|
-- | Attempt to write a value into the 'CloseableChan'.
|
||||||
|
--
|
||||||
|
-- If the chan is open, succeeds with a @Just ()@.
|
||||||
|
-- If the chan is closed, fails with a @Nothing@.
|
||||||
writeChan :: CloseableChan a -> a -> IO (Maybe ())
|
writeChan :: CloseableChan a -> a -> IO (Maybe ())
|
||||||
writeChan chan = atomically . writeChanSTM chan
|
writeChan chan a = atomically $ writeChanSTM chan a
|
||||||
|
|
||||||
|
-- | Attempt to read a value @v@ from the 'CloseableChan'.
|
||||||
|
--
|
||||||
|
-- If the chan is open, succeeds with a @Just v@.
|
||||||
|
-- If the chan is closed, fails with a @Nothing@.
|
||||||
readChan :: CloseableChan a -> IO (Maybe a)
|
readChan :: CloseableChan a -> IO (Maybe a)
|
||||||
readChan = atomically . readChanSTM
|
readChan = atomically . readChanSTM
|
||||||
|
|
||||||
|
-- | Close a 'CloseableChan'.
|
||||||
|
-- Does nothing if chan is already closed.
|
||||||
|
--
|
||||||
|
-- Performing this action un-blocks all calls to 'readChan'.
|
||||||
closeChan :: CloseableChan a -> IO ()
|
closeChan :: CloseableChan a -> IO ()
|
||||||
closeChan = atomically . closeChanSTM
|
closeChan = atomically . closeChanSTM
|
||||||
|
|
||||||
|
-- | Open a 'CloseableChan'.
|
||||||
|
-- Does nothing if chan is already open.
|
||||||
|
openChan :: CloseableChan a -> IO ()
|
||||||
|
openChan = atomically . openChanSTM
|
||||||
|
|
||||||
|
-- | Remove all items currently in the 'CloseableChan' and returns them in a list.
|
||||||
|
--
|
||||||
|
-- This function also works while the chan is closed.
|
||||||
|
-- It is meant as a way to clean up the remaining values in a chan after it was closed.
|
||||||
emptyChan :: CloseableChan a -> IO [a]
|
emptyChan :: CloseableChan a -> IO [a]
|
||||||
emptyChan = atomically . emptyChanSTM
|
emptyChan = atomically . emptyChanSTM
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue