{-# LANGUAGE CPP #-}
-- | Lifted version of "Control.Concurrent.STM"
--
-- @since 0.2.1.0
module UnliftIO.STM
  ( -- * Core
    STM.STM
  , atomically
  , retrySTM
  , checkSTM
  , STM.orElse

    -- * TVar
  , STM.TVar
  , newTVarIO
  , readTVarIO
  , STM.newTVar
  , STM.readTVar
  , STM.writeTVar
  , STM.modifyTVar
  , STM.modifyTVar'
  , STM.swapTVar
  , registerDelay
  , mkWeakTVar

    -- * TMVar
  , STM.TMVar
  , STM.newTMVar
  , STM.newEmptyTMVar
  , newTMVarIO
  , newEmptyTMVarIO
  , STM.takeTMVar
  , STM.putTMVar
  , STM.readTMVar
  , STM.tryReadTMVar
  , STM.swapTMVar
  , STM.tryTakeTMVar
  , STM.tryPutTMVar
  , STM.isEmptyTMVar
  , mkWeakTMVar

    -- * TChan
  , STM.TChan
  , STM.newTChan
  , newTChanIO
  , STM.newBroadcastTChan
  , newBroadcastTChanIO
  , STM.dupTChan
  , STM.cloneTChan
  , STM.readTChan
  , STM.tryReadTChan
  , STM.peekTChan
  , STM.tryPeekTChan
  , STM.writeTChan
  , STM.unGetTChan
  , STM.isEmptyTChan

    -- * TQueue
  , STM.TQueue
  , STM.newTQueue
  , newTQueueIO
  , STM.readTQueue
  , STM.tryReadTQueue
  , STM.peekTQueue
  , STM.tryPeekTQueue
  , STM.writeTQueue
  , STM.unGetTQueue
  , STM.isEmptyTQueue

    -- * TBQueue
  , STM.TBQueue
  , STM.newTBQueue
  , newTBQueueIO
  , STM.readTBQueue
  , STM.tryReadTBQueue
  , STM.peekTBQueue
  , STM.tryPeekTBQueue
  , STM.writeTBQueue
  , STM.unGetTBQueue
  , STM.isEmptyTBQueue
  , STM.isFullTBQueue
  ) where

import Control.Concurrent.STM (STM, TVar, TMVar, TChan, TQueue, TBQueue)
import qualified Control.Concurrent.STM as STM
import Control.Monad.IO.Unlift
import System.Mem.Weak (Weak)
#if MIN_VERSION_base(4, 8, 0)
import GHC.Natural (Natural)
#else
import Numeric.Natural (Natural)
#endif

-- | Lifted version of 'STM.atomically'
--
-- @since 0.2.1.0
atomically :: MonadIO m => STM a -> m a
atomically :: STM a -> m a
atomically = IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO a -> m a) -> (STM a -> IO a) -> STM a -> m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. STM a -> IO a
forall a. STM a -> IO a
STM.atomically

-- | Renamed 'STM.retry' for unqualified export
--
-- @since 0.2.1.0
retrySTM :: STM a
retrySTM :: STM a
retrySTM = STM a
forall a. STM a
STM.retry

-- | Renamed 'STM.check' for unqualified export
--
-- @since 0.2.1.0
checkSTM :: Bool -> STM ()
checkSTM :: Bool -> STM ()
checkSTM = Bool -> STM ()
STM.check

-- | Lifted version of 'STM.newTVarIO'
--
-- @since 0.2.1.0
newTVarIO :: MonadIO m => a -> m (TVar a)
newTVarIO :: a -> m (TVar a)
newTVarIO = IO (TVar a) -> m (TVar a)
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (TVar a) -> m (TVar a))
-> (a -> IO (TVar a)) -> a -> m (TVar a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> IO (TVar a)
forall a. a -> IO (TVar a)
STM.newTVarIO

-- | Lifted version of 'STM.readTVarIO'
--
-- @since 0.2.1.0
readTVarIO :: MonadIO m => TVar a -> m a
readTVarIO :: TVar a -> m a
readTVarIO = IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO a -> m a) -> (TVar a -> IO a) -> TVar a -> m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TVar a -> IO a
forall a. TVar a -> IO a
STM.readTVarIO

-- | Lifted version of 'STM.registerDelay'
--
-- @since 0.2.1.0
registerDelay :: MonadIO m => Int -> m (TVar Bool)
registerDelay :: Int -> m (TVar Bool)
registerDelay = IO (TVar Bool) -> m (TVar Bool)
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (TVar Bool) -> m (TVar Bool))
-> (Int -> IO (TVar Bool)) -> Int -> m (TVar Bool)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> IO (TVar Bool)
STM.registerDelay

-- | Lifted version of 'STM.mkWeakTVar'
--
-- @since 0.2.1.0
mkWeakTVar :: MonadUnliftIO m => TVar a -> m () -> m (Weak (TVar a))
mkWeakTVar :: TVar a -> m () -> m (Weak (TVar a))
mkWeakTVar TVar a
var m ()
final = ((forall a. m a -> IO a) -> IO (Weak (TVar a)))
-> m (Weak (TVar a))
forall (m :: * -> *) b.
MonadUnliftIO m =>
((forall a. m a -> IO a) -> IO b) -> m b
withRunInIO (((forall a. m a -> IO a) -> IO (Weak (TVar a)))
 -> m (Weak (TVar a)))
-> ((forall a. m a -> IO a) -> IO (Weak (TVar a)))
-> m (Weak (TVar a))
forall a b. (a -> b) -> a -> b
$ \forall a. m a -> IO a
run -> TVar a -> IO () -> IO (Weak (TVar a))
forall a. TVar a -> IO () -> IO (Weak (TVar a))
STM.mkWeakTVar TVar a
var (m () -> IO ()
forall a. m a -> IO a
run m ()
final)

-- | Lifted version of 'STM.newTMVarIO'
--
-- @since 0.2.1.0
newTMVarIO :: MonadIO m => a -> m (TMVar a)
newTMVarIO :: a -> m (TMVar a)
newTMVarIO = IO (TMVar a) -> m (TMVar a)
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (TMVar a) -> m (TMVar a))
-> (a -> IO (TMVar a)) -> a -> m (TMVar a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> IO (TMVar a)
forall a. a -> IO (TMVar a)
STM.newTMVarIO

-- | Lifted version of 'STM.newEmptyTMVarIO'
--
-- @since 0.2.1.0
newEmptyTMVarIO :: MonadIO m => m (TMVar a)
newEmptyTMVarIO :: m (TMVar a)
newEmptyTMVarIO = IO (TMVar a) -> m (TMVar a)
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO IO (TMVar a)
forall a. IO (TMVar a)
STM.newEmptyTMVarIO

-- | Lifted version of 'STM.mkWeakTMVar'
--
-- @since 0.2.1.0
mkWeakTMVar :: MonadUnliftIO m => TMVar a -> m () -> m (Weak (TMVar a))
mkWeakTMVar :: TMVar a -> m () -> m (Weak (TMVar a))
mkWeakTMVar TMVar a
var m ()
final = ((forall a. m a -> IO a) -> IO (Weak (TMVar a)))
-> m (Weak (TMVar a))
forall (m :: * -> *) b.
MonadUnliftIO m =>
((forall a. m a -> IO a) -> IO b) -> m b
withRunInIO (((forall a. m a -> IO a) -> IO (Weak (TMVar a)))
 -> m (Weak (TMVar a)))
-> ((forall a. m a -> IO a) -> IO (Weak (TMVar a)))
-> m (Weak (TMVar a))
forall a b. (a -> b) -> a -> b
$ \forall a. m a -> IO a
run -> TMVar a -> IO () -> IO (Weak (TMVar a))
forall a. TMVar a -> IO () -> IO (Weak (TMVar a))
STM.mkWeakTMVar TMVar a
var (m () -> IO ()
forall a. m a -> IO a
run m ()
final)

-- | Lifted version of 'STM.newTChanIO'
--
-- @since 0.2.1.0
newTChanIO :: MonadIO m => m (TChan a)
newTChanIO :: m (TChan a)
newTChanIO = IO (TChan a) -> m (TChan a)
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO IO (TChan a)
forall a. IO (TChan a)
STM.newTChanIO

-- | Lifted version of 'STM.newBroadcastTChanIO'
--
-- @since 0.2.1.0
newBroadcastTChanIO :: MonadIO m => m (TChan a)
newBroadcastTChanIO :: m (TChan a)
newBroadcastTChanIO = IO (TChan a) -> m (TChan a)
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO IO (TChan a)
forall a. IO (TChan a)
STM.newBroadcastTChanIO

-- | Lifted version of 'STM.newTQueueIO'
--
-- @since 0.2.1.0
newTQueueIO :: MonadIO m => m (TQueue a)
newTQueueIO :: m (TQueue a)
newTQueueIO = IO (TQueue a) -> m (TQueue a)
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO IO (TQueue a)
forall a. IO (TQueue a)
STM.newTQueueIO

-- | Lifted version of 'STM.newTBQueueIO'
--
-- @since 0.2.1.0
#if MIN_VERSION_stm(2, 5, 0)
newTBQueueIO :: MonadIO m => Natural -> m (TBQueue a)
#else
newTBQueueIO :: MonadIO m => Int -> m (TBQueue a)
#endif
newTBQueueIO :: Natural -> m (TBQueue a)
newTBQueueIO = IO (TBQueue a) -> m (TBQueue a)
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (TBQueue a) -> m (TBQueue a))
-> (Natural -> IO (TBQueue a)) -> Natural -> m (TBQueue a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Natural -> IO (TBQueue a)
forall a. Natural -> IO (TBQueue a)
STM.newTBQueueIO