------------------------------------------------------------------------------- |-- Module : Control.Concurrent.STM.TChan-- Copyright : (c) The University of Glasgow 2004-- License : BSD-style (see the file libraries/base/LICENSE)-- -- Maintainer : libraries@haskell.org-- Stability : experimental-- Portability : non-portable (requires STM)---- TChan: Transactional channels-- (GHC only)-------------------------------------------------------------------------------moduleControl.Concurrent.STM.TChan(#ifdef __GLASGOW_HASKELL__-- * TChansTChan,newTChan,newTChanIO,readTChan,writeTChan,dupTChan,unGetTChan,isEmptyTChan#endif)where#ifdef __GLASGOW_HASKELL__importGHC.Conc-- | 'TChan' is an abstract type representing an unbounded FIFO channel.dataTChana=TChan(TVar(TVarLista))(TVar(TVarLista))typeTVarLista=TVar(TLista)dataTLista=TNil|TConsa(TVarLista)-- |Build and returns a new instance of 'TChan'newTChan::STM(TChana)newTChan=dohole<-newTVarTNilread<-newTVarholewrite<-newTVarholereturn(TChanreadwrite)-- |@IO@ version of 'newTChan'. This is useful for creating top-level-- 'TChan's using 'System.IO.Unsafe.unsafePerformIO', because using-- 'atomically' inside 'System.IO.Unsafe.unsafePerformIO' isn't-- possible.newTChanIO::IO(TChana)newTChanIO=dohole<-newTVarIOTNilread<-newTVarIOholewrite<-newTVarIOholereturn(TChanreadwrite)-- |Write a value to a 'TChan'.writeTChan::TChana->a->STM()writeTChan(TChan_readwrite)a=dolistend<-readTVarwrite-- listend == TVar pointing to TNilnew_listend<-newTVarTNilwriteTVarlistend(TConsanew_listend)writeTVarwritenew_listend-- |Read the next value from the 'TChan'.readTChan::TChana->STMareadTChan(TChanread_write)=dolisthead<-readTVarreadhead<-readTVarlistheadcaseheadofTNil->retryTConsatail->dowriteTVarreadtailreturna-- |Duplicate a 'TChan': the duplicate channel begins empty, but data written to-- either channel from then on will be available from both. Hence this creates-- a kind of broadcast channel, where data written by anyone is seen by-- everyone else.dupTChan::TChana->STM(TChana)dupTChan(TChanreadwrite)=dohole<-readTVarwritenew_read<-newTVarholereturn(TChannew_readwrite)-- |Put a data item back onto a channel, where it will be the next item read.unGetTChan::TChana->a->STM()unGetTChan(TChanread_write)a=dolisthead<-readTVarreadnewhead<-newTVar(TConsalisthead)writeTVarreadnewhead-- |Returns 'True' if the supplied 'TChan' is empty.isEmptyTChan::TChana->STMBoolisEmptyTChan(TChanreadwrite)=dolisthead<-readTVarreadhead<-readTVarlistheadcaseheadofTNil->returnTrueTCons__->returnFalse#endif