    -- | Unlifted "Control.Concurrent.QSemN".
    --
    -- @since 0.2.14
    module UnliftIO.QSemN
      ( QSemN
      , newQSemN
      , waitQSemN
      , signalQSemN
      , withQSemN
      ) where

    import Control.Concurrent.QSemN (QSemN)
    import Control.Monad.IO.Unlift
    import UnliftIO.Exception
    import qualified Control.Concurrent.QSemN as Q

    -- | Lifted 'Q.newQSemN'.
    --
    -- @since 0.2.14
    newQSemN :: MonadIO m => Int -> m QSemN
    newQSemN :: forall (m :: * -> *). MonadIO m => Int -> m QSemN
    newQSemN = IO QSemN -> m QSemN
    forall a. IO a -> m a
    forall (m :: * -> *) a. MonadIO m => IO a -> m a
    liftIO (IO QSemN -> m QSemN) -> (Int -> IO QSemN) -> Int -> m QSemN
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Int -> IO QSemN
    Q.newQSemN

    -- | Lifted 'Q.waitQSemN'.
    --
    -- @since 0.2.14
    waitQSemN :: MonadIO m => QSemN -> Int -> m ()
    waitQSemN :: forall (m :: * -> *). MonadIO m => QSemN -> Int -> m ()
    waitQSemN QSemN
    x = IO () -> m ()
    forall a. IO a -> m a
    forall (m :: * -> *) a. MonadIO m => IO a -> m a
    liftIO (IO () -> m ()) -> (Int -> IO ()) -> Int -> m ()
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . QSemN -> Int -> IO ()
    Q.waitQSemN QSemN
    x

    -- | Lifted 'Q.signalQSemN'.
    --
    -- @since 0.2.14
    signalQSemN :: MonadIO m => QSemN -> Int -> m ()
    signalQSemN :: forall (m :: * -> *). MonadIO m => QSemN -> Int -> m ()
    signalQSemN QSemN
    x = IO () -> m ()
    forall a. IO a -> m a
    forall (m :: * -> *) a. MonadIO m => IO a -> m a
    liftIO (IO () -> m ()) -> (Int -> IO ()) -> Int -> m ()
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . QSemN -> Int -> IO ()
    Q.signalQSemN QSemN
    x

    -- | 'withQSemN' is an exception-safe wrapper for performing the
    -- provided operation while holding N unit of value from the semaphore.
    -- It ensures the semaphore cannot be leaked if there are exceptions.
    --
    -- @since 0.2.14
    {-# INLINE withQSemN #-}
    withQSemN :: MonadUnliftIO m => QSemN -> Int -> m a -> m a
    withQSemN :: forall (m :: * -> *) a.
    MonadUnliftIO m =>
    QSemN -> Int -> m a -> m a
    withQSemN QSemN
    x Int
    n m a
    io = ((forall a. m a -> IO a) -> IO a) -> m a
    forall b. ((forall a. m a -> IO a) -> IO b) -> m b
    forall (m :: * -> *) b.
    MonadUnliftIO m =>
    ((forall a. m a -> IO a) -> IO b) -> m b
    withRunInIO (((forall a. m a -> IO a) -> IO a) -> m a)
    -> ((forall a. m a -> IO a) -> IO a) -> m a
    forall a b. (a -> b) -> a -> b
    $ \forall a. m a -> IO a
    run ->
      IO () -> IO () -> IO a -> IO a
    forall (m :: * -> *) a b c.
    MonadUnliftIO m =>
    m a -> m b -> m c -> m c
    bracket_ (QSemN -> Int -> IO ()
    forall (m :: * -> *). MonadIO m => QSemN -> Int -> m ()
    waitQSemN QSemN
    x Int
    n) (QSemN -> Int -> IO ()
    forall (m :: * -> *). MonadIO m => QSemN -> Int -> m ()
    signalQSemN QSemN
    x Int
    n) (m a -> IO a
    forall a. m a -> IO a
    run m a
    io)