content: module Control.Effect.Mask
    ( -- * Effects
      Mask(..)
    , MaskMode(..)
  
      -- * Actions
    , mask
    , mask_
    , uninterruptibleMask
    , uninterruptibleMask_
  
      -- * Interpretations
    , maskToIO
  
    , ignoreMask
  
      -- * Threading utilities
    , threadMaskViaClass
  
      -- * MonadMask
    , C.MonadMask
  
      -- * Carriers
    , MaskToIOC
    , IgnoreMaskC
    ) where
  
  import Control.Effect
  import Control.Effect.Primitive
  import Control.Effect.Type.Mask
  
  import Control.Monad.Catch (MonadMask)
  import qualified Control.Monad.Catch as C
  
  mask :: Eff Mask m => ((forall x. m x -> m x) -> m a) -> m a
  mask main = send (Mask InterruptibleMask main)
  {-# INLINE mask #-}
  
  mask_ :: Eff Mask m => m a -> m a
  mask_ main = mask $ \_ -> main
  {-# INLINE mask_ #-}
  
  uninterruptibleMask :: Eff Mask m => ((forall x. m x -> m x) -> m a) -> m a
  uninterruptibleMask main = send (Mask UninterruptibleMask main)
  {-# INLINE uninterruptibleMask #-}
  
  uninterruptibleMask_ :: Eff Mask m => m a -> m a
  uninterruptibleMask_ main = uninterruptibleMask $ \_ -> main
  {-# INLINE uninterruptibleMask_ #-}
  
  data MaskToIOH
  
  instance ( Carrier m
           , MonadMask m
           )
        => PrimHandler MaskToIOH Mask m where
    effPrimHandler (Mask InterruptibleMask main)   = C.mask main
    effPrimHandler (Mask UninterruptibleMask main) = C.uninterruptibleMask main
    {-# INLINEABLE effPrimHandler #-}
  
  type MaskToIOC = InterpretPrimC MaskToIOH Mask
  
  -- | Run a 'Mask' effect by making use of the 'IO'-based 'Control.Exception.mask' and
  -- 'Control.Exception.uninterruptibleMask'.
  --
  -- @'Derivs' ('MaskToIOC' m) = 'Mask' ': 'Derivs' m@
  --
  -- @'Prims'  ('MaskToIOC' m) = 'Mask' ': 'Prims' m@
  maskToIO :: ( Carrier m
              , MonadMask m
              )
           => MaskToIOC m a
           -> m a
  maskToIO = interpretPrimViaHandler
  {-# INLINE maskToIO #-}
  
  data IgnoreMaskH
  
  instance Carrier m
        => Handler IgnoreMaskH Mask m where
    effHandler (Mask _ main) = main id
    {-# INLINEABLE effHandler #-}
  
  type IgnoreMaskC = InterpretC IgnoreMaskH Mask
  
  -- | Run a 'Mask' effect by ignoring it, providing no protection
  -- against asynchronous exceptions.
  --
  -- @'Derivs' ('IgnoreMaskC' m) = 'Mask' ': 'Derivs' m@
  --
  -- @'Prims'  ('IgnoreMaskC' m) = 'Prims' m@
  ignoreMask :: Carrier m
             => IgnoreMaskC m a
             -> m a
  ignoreMask = interpretViaHandler
  {-# INLINE ignoreMask #-}
  