module HaskellWorks.Polysemy.Control.Concurrent
  ( ThreadId,
    myThreadId,
    killThread,
    getNumCapabilities,
    threadCapability,
    yield,
    threadDelay,
    isCurrentThreadBound,
    mkWeakThreadId,
  ) where

import           Control.Concurrent            (ThreadId)
import qualified Control.Concurrent            as IO
import           HaskellWorks.Polysemy.Prelude
import           Polysemy
import           System.Mem.Weak               (Weak)

myThreadId :: ()
  => Member (Embed IO) r
  => Sem r ThreadId
myThreadId :: forall (r :: EffectRow). Member (Embed IO) r => Sem r ThreadId
myThreadId =
  IO ThreadId -> Sem r ThreadId
forall (m :: * -> *) (r :: EffectRow) a.
Member (Embed m) r =>
m a -> Sem r a
embed IO ThreadId
IO.myThreadId

killThread :: ()
  => Member (Embed IO) r
  => ThreadId
  -> Sem r ()
killThread :: forall (r :: EffectRow).
Member (Embed IO) r =>
ThreadId -> Sem r ()
killThread ThreadId
tid =
  IO () -> Sem r ()
forall (m :: * -> *) (r :: EffectRow) a.
Member (Embed m) r =>
m a -> Sem r a
embed (IO () -> Sem r ()) -> IO () -> Sem r ()
forall a b. (a -> b) -> a -> b
$ ThreadId -> IO ()
IO.killThread ThreadId
tid

getNumCapabilities :: ()
  => Member (Embed IO) r
  => Sem r Int
getNumCapabilities :: forall (r :: EffectRow). Member (Embed IO) r => Sem r Int
getNumCapabilities =
  IO Int -> Sem r Int
forall (m :: * -> *) (r :: EffectRow) a.
Member (Embed m) r =>
m a -> Sem r a
embed IO Int
IO.getNumCapabilities

threadCapability :: ()
  => Member (Embed IO) r
  => ThreadId
  -> Sem r (Int, Bool)
threadCapability :: forall (r :: EffectRow).
Member (Embed IO) r =>
ThreadId -> Sem r (Int, Bool)
threadCapability ThreadId
tid =
  IO (Int, Bool) -> Sem r (Int, Bool)
forall (m :: * -> *) (r :: EffectRow) a.
Member (Embed m) r =>
m a -> Sem r a
embed (IO (Int, Bool) -> Sem r (Int, Bool))
-> IO (Int, Bool) -> Sem r (Int, Bool)
forall a b. (a -> b) -> a -> b
$ ThreadId -> IO (Int, Bool)
IO.threadCapability ThreadId
tid

yield :: ()
  => Member (Embed IO) r
  => Sem r ()
yield :: forall (r :: EffectRow). Member (Embed IO) r => Sem r ()
yield =
  IO () -> Sem r ()
forall (m :: * -> *) (r :: EffectRow) a.
Member (Embed m) r =>
m a -> Sem r a
embed IO ()
IO.yield

threadDelay :: ()
  => Member (Embed IO) r
  => Int
  -> Sem r ()
threadDelay :: forall (r :: EffectRow). Member (Embed IO) r => Int -> Sem r ()
threadDelay Int
n =
  IO () -> Sem r ()
forall (m :: * -> *) (r :: EffectRow) a.
Member (Embed m) r =>
m a -> Sem r a
embed (IO () -> Sem r ()) -> IO () -> Sem r ()
forall a b. (a -> b) -> a -> b
$ Int -> IO ()
IO.threadDelay Int
n

isCurrentThreadBound :: ()
  => Member (Embed IO) r
  => Sem r Bool
isCurrentThreadBound :: forall (r :: EffectRow). Member (Embed IO) r => Sem r Bool
isCurrentThreadBound =
  IO Bool -> Sem r Bool
forall (m :: * -> *) (r :: EffectRow) a.
Member (Embed m) r =>
m a -> Sem r a
embed IO Bool
IO.isCurrentThreadBound

mkWeakThreadId :: ()
  => Member (Embed IO) r
  => ThreadId
  -> Sem r (Weak ThreadId)
mkWeakThreadId :: forall (r :: EffectRow).
Member (Embed IO) r =>
ThreadId -> Sem r (Weak ThreadId)
mkWeakThreadId ThreadId
tid =
  IO (Weak ThreadId) -> Sem r (Weak ThreadId)
forall (m :: * -> *) (r :: EffectRow) a.
Member (Embed m) r =>
m a -> Sem r a
embed (IO (Weak ThreadId) -> Sem r (Weak ThreadId))
-> IO (Weak ThreadId) -> Sem r (Weak ThreadId)
forall a b. (a -> b) -> a -> b
$ ThreadId -> IO (Weak ThreadId)
IO.mkWeakThreadId ThreadId
tid