module Concur.Core.Notify
( Notify
, fetch
, await
, notify
, newNotify
, newNotifyIO
) where
import Control.Concurrent.STM (STM, TVar, newTVar, newTVarIO,
readTVar, retry, writeTVar)
import Control.Monad (void)
newtype Notify a = Notify (TVar (Maybe a))
fetch :: Notify a -> STM (Maybe a)
fetch (Notify v) = tryTakeTVar v
await :: Notify a -> STM a
await (Notify v) = takeTVar v
notify :: Notify a -> a -> STM ()
notify (Notify v) a = void (writeTVar v (Just a))
newNotify :: STM (Notify a)
newNotify = Notify <$> newTVar Nothing
newNotifyIO :: IO (Notify a)
newNotifyIO = Notify <$> newTVarIO Nothing
takeTVar :: TVar (Maybe a) -> STM a
takeTVar t = do
m <- readTVar t
case m of
Nothing -> retry
Just a -> do writeTVar t Nothing; return a
tryTakeTVar :: TVar (Maybe a) -> STM (Maybe a)
tryTakeTVar t = do
m <- readTVar t
case m of
Nothing -> return Nothing
Just a -> do writeTVar t Nothing; return (Just a)