module HaskellWorks.Polysemy.Control.Concurrent.QSem
  ( QSem,

    newQSem,
    waitQSem,
    signalQSem,
    bracketQSem,
  ) where

import           Control.Concurrent.QSem       (QSem)
import qualified Control.Concurrent.QSem       as IO
import           Control.Monad.IO.Class        (MonadIO (..))
import           HaskellWorks.Polysemy.Prelude
import           Polysemy
import           Polysemy.Resource

newQSem :: ()
  => MonadIO m
  => Member (Embed m) r
  => Int
  -> Sem r QSem
newQSem :: forall (m :: * -> *) (r :: EffectRow).
(MonadIO m, Member (Embed m) r) =>
Int -> Sem r QSem
newQSem Int
n = do
  m QSem -> Sem r QSem
forall (m :: * -> *) (r :: EffectRow) a.
Member (Embed m) r =>
m a -> Sem r a
embed (m QSem -> Sem r QSem) -> m QSem -> Sem r QSem
forall a b. (a -> b) -> a -> b
$ IO QSem -> m QSem
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO QSem -> m QSem) -> IO QSem -> m QSem
forall a b. (a -> b) -> a -> b
$ Int -> IO QSem
IO.newQSem Int
n

waitQSem :: ()
  => MonadIO m
  => Member (Embed m) r
  => QSem
  -> Sem r ()
waitQSem :: forall (m :: * -> *) (r :: EffectRow).
(MonadIO m, Member (Embed m) r) =>
QSem -> Sem r ()
waitQSem QSem
sem =
  m () -> Sem r ()
forall (m :: * -> *) (r :: EffectRow) a.
Member (Embed m) r =>
m a -> Sem r a
embed (m () -> Sem r ()) -> m () -> Sem r ()
forall a b. (a -> b) -> a -> b
$ IO () -> m ()
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> m ()) -> IO () -> m ()
forall a b. (a -> b) -> a -> b
$ QSem -> IO ()
IO.waitQSem QSem
sem

signalQSem :: ()
  => MonadIO m
  => Member (Embed m) r
  => QSem
  -> Sem r ()
signalQSem :: forall (m :: * -> *) (r :: EffectRow).
(MonadIO m, Member (Embed m) r) =>
QSem -> Sem r ()
signalQSem QSem
sem =
  m () -> Sem r ()
forall (m :: * -> *) (r :: EffectRow) a.
Member (Embed m) r =>
m a -> Sem r a
embed (m () -> Sem r ()) -> m () -> Sem r ()
forall a b. (a -> b) -> a -> b
$ IO () -> m ()
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> m ()) -> IO () -> m ()
forall a b. (a -> b) -> a -> b
$ QSem -> IO ()
IO.signalQSem QSem
sem

bracketQSem :: ()
  => MonadIO m
  => Member (Embed m) r
  => Member Resource r
  => QSem
  -> Sem r a
  -> Sem r a
bracketQSem :: forall (m :: * -> *) (r :: EffectRow) a.
(MonadIO m, Member (Embed m) r, Member Resource r) =>
QSem -> Sem r a -> Sem r a
bracketQSem QSem
sem =
  Sem r () -> Sem r () -> Sem r a -> Sem r a
forall (r :: EffectRow) a b c.
Member Resource r =>
Sem r a -> Sem r b -> Sem r c -> Sem r c
bracket_ (QSem -> Sem r ()
forall (m :: * -> *) (r :: EffectRow).
(MonadIO m, Member (Embed m) r) =>
QSem -> Sem r ()
waitQSem QSem
sem) (QSem -> Sem r ()
forall (m :: * -> *) (r :: EffectRow).
(MonadIO m, Member (Embed m) r) =>
QSem -> Sem r ()
signalQSem QSem
sem)