{-# LANGUAGE RecordWildCards #-} {-# LANGUAGE UnicodeSyntax #-} -- | -- Module: Control.Concurrent.STM.ETQueue -- Copyright: Copyright © 2014 AlephCloud Systems, Inc. -- License: MIT -- Maintainer: Jon Sterling -- Stability: experimental -- module Control.Concurrent.STM.ETQueue ( ETQueue , newETQueue , newETQueueIO , readETQueue , tryReadETQueue , peekETQueue , tryPeekETQueue , writeETQueue , unGetETQueue , isEmptyETQueue , awaitEmpty ) where import Control.Applicative import Control.Concurrent.STM import Control.Monad -- | A variant of 'TQueue' such that you can await its emptiness. data ETQueue α = ETQueue { etqQueue ∷ TQueue α , etqVar ∷ TMVar () } newETQueue ∷ STM (ETQueue α) newETQueue = do etqQueue ← newTQueue etqVar ← newTMVar () return ETQueue {..} newETQueueIO ∷ IO (ETQueue α) newETQueueIO = do etqQueue ← newTQueueIO etqVar ← newTMVarIO () return ETQueue {..} readETQueue ∷ ETQueue α → STM α readETQueue ETQueue{..} = do a ← readTQueue etqQueue isEmpty ← isEmptyTQueue etqQueue when isEmpty $ () <$ tryPutTMVar etqVar () return a tryReadETQueue ∷ ETQueue α → STM (Maybe α) tryReadETQueue q = (Just <$> readETQueue q) `orElse` return Nothing peekETQueue ∷ ETQueue α → STM α peekETQueue ETQueue{..} = peekTQueue etqQueue tryPeekETQueue ∷ ETQueue α → STM (Maybe α) tryPeekETQueue ETQueue{..} = tryPeekTQueue etqQueue writeETQueue ∷ ETQueue α → α → STM () writeETQueue ETQueue{..} a = do writeTQueue etqQueue a () <$ tryTakeTMVar etqVar unGetETQueue ∷ ETQueue α → α → STM () unGetETQueue ETQueue{..} a = do unGetTQueue etqQueue a () <$ tryTakeTMVar etqVar isEmptyETQueue ∷ ETQueue α → STM Bool isEmptyETQueue ETQueue{..} = isEmptyTQueue etqQueue awaitEmpty ∷ ETQueue α → STM () awaitEmpty ETQueue{..} = readTMVar etqVar