{-# OPTIONS_GHC -fno-warn-name-shadowing #-}
{-# LANGUAGE CPP, DeriveDataTypeable #-}
#if __GLASGOW_HASKELL__ >= 701
{-# LANGUAGE Trustworthy #-}
#endif
module Control.Concurrent.STM.TChan (
#ifdef __GLASGOW_HASKELL__
TChan,
newTChan,
newTChanIO,
newBroadcastTChan,
newBroadcastTChanIO,
dupTChan,
cloneTChan,
readTChan,
tryReadTChan,
peekTChan,
tryPeekTChan,
writeTChan,
unGetTChan,
isEmptyTChan
#endif
) where
#ifdef __GLASGOW_HASKELL__
import GHC.Conc
import Data.Typeable (Typeable)
#define _UPK_(x) {-# UNPACK #-} !(x)
data TChan a = TChan _UPK_(TVar (TVarList a))
_UPK_(TVar (TVarList a))
deriving (Eq, Typeable)
type TVarList a = TVar (TList a)
data TList a = TNil | TCons a _UPK_(TVarList a)
newTChan :: STM (TChan a)
newTChan = do
hole <- newTVar TNil
read <- newTVar hole
write <- newTVar hole
return (TChan read write)
newTChanIO :: IO (TChan a)
newTChanIO = do
hole <- newTVarIO TNil
read <- newTVarIO hole
write <- newTVarIO hole
return (TChan read write)
newBroadcastTChan :: STM (TChan a)
newBroadcastTChan = do
write_hole <- newTVar TNil
read <- newTVar (error "reading from a TChan created by newBroadcastTChan; use dupTChan first")
write <- newTVar write_hole
return (TChan read write)
newBroadcastTChanIO :: IO (TChan a)
newBroadcastTChanIO = do
write_hole <- newTVarIO TNil
read <- newTVarIO (error "reading from a TChan created by newBroadcastTChanIO; use dupTChan first")
write <- newTVarIO write_hole
return (TChan read write)
writeTChan :: TChan a -> a -> STM ()
writeTChan (TChan _read write) a = do
listend <- readTVar write
new_listend <- newTVar TNil
writeTVar listend (TCons a new_listend)
writeTVar write new_listend
readTChan :: TChan a -> STM a
readTChan (TChan read _write) = do
listhead <- readTVar read
head <- readTVar listhead
case head of
TNil -> retry
TCons a tail -> do
writeTVar read tail
return a
tryReadTChan :: TChan a -> STM (Maybe a)
tryReadTChan (TChan read _write) = do
listhead <- readTVar read
head <- readTVar listhead
case head of
TNil -> return Nothing
TCons a tl -> do
writeTVar read tl
return (Just a)
peekTChan :: TChan a -> STM a
peekTChan (TChan read _write) = do
listhead <- readTVar read
head <- readTVar listhead
case head of
TNil -> retry
TCons a _ -> return a
tryPeekTChan :: TChan a -> STM (Maybe a)
tryPeekTChan (TChan read _write) = do
listhead <- readTVar read
head <- readTVar listhead
case head of
TNil -> return Nothing
TCons a _ -> return (Just a)
dupTChan :: TChan a -> STM (TChan a)
dupTChan (TChan _read write) = do
hole <- readTVar write
new_read <- newTVar hole
return (TChan new_read write)
unGetTChan :: TChan a -> a -> STM ()
unGetTChan (TChan read _write) a = do
listhead <- readTVar read
newhead <- newTVar (TCons a listhead)
writeTVar read newhead
isEmptyTChan :: TChan a -> STM Bool
isEmptyTChan (TChan read _write) = do
listhead <- readTVar read
head <- readTVar listhead
case head of
TNil -> return True
TCons _ _ -> return False
cloneTChan :: TChan a -> STM (TChan a)
cloneTChan (TChan read write) = do
readpos <- readTVar read
new_read <- newTVar readpos
return (TChan new_read write)
#endif