Skip to content

Commit 9718f0d

Browse files
committed
WIP: Add kindaUnlift to find out what happens where
1 parent 639dcb3 commit 9718f0d

File tree

2 files changed

+36
-22
lines changed

2 files changed

+36
-22
lines changed

troupe/src/Troupe.hs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ module Troupe
1313
spawn,
1414
spawnLink,
1515
spawnMonitor,
16+
kindaUnlift,
1617

1718
-- *** Spawning processes with options
1819
spawnWithOptions,
@@ -118,6 +119,7 @@ import Troupe.Process
118119
sendLazy,
119120
setProcessOption,
120121
spawnWithOptions,
122+
kindaUnlift,
121123
unlink,
122124
)
123125
import Troupe.Types (Down (..), MonitorRef, ProcessId)

troupe/src/Troupe/Process.hs

Lines changed: 34 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ module Troupe.Process
3333
exit,
3434
isProcessAlive,
3535
spawnWithOptions,
36+
kindaUnlift,
3637
SpawnOptions (..),
3738
ThreadAffinity (..),
3839
WithMonitor (..),
@@ -46,7 +47,7 @@ module Troupe.Process
4647
where
4748

4849
import Control.Applicative (Alternative, (<|>))
49-
import Control.Concurrent (throwTo)
50+
import Control.Concurrent (threadDelay, throwTo)
5051
import Control.Concurrent.Async
5152
( async,
5253
asyncThreadId,
@@ -100,7 +101,7 @@ import Control.Exception.Safe
100101
uninterruptibleMask_,
101102
withException,
102103
)
103-
import Control.Monad (MonadPlus, forM, unless, when)
104+
import Control.Monad (MonadPlus, forever, forM, unless, when)
104105
import Control.Monad.Error.Class (MonadError)
105106
import Control.Monad.Fix (MonadFix)
106107
import Control.Monad.IO.Class (MonadIO, liftIO)
@@ -583,17 +584,7 @@ data ThreadAffinity
583584
-- 'Troupe.spawn', 'Troupe.spawnLink' and 'Troupe.spawnMonitor' are specialized
584585
-- versions of this function.
585586
spawnWithOptions :: (MonadProcess r m, MonadIO m) => SpawnOptions t -> Process r a -> m t
586-
spawnWithOptions !options process = do
587-
let cb pid = do
588-
when (spawnOptionsLink options) $
589-
linkSTM pid
590-
case spawnOptionsMonitor options of
591-
WithoutMonitor -> pure pid
592-
WithMonitor -> do
593-
ref <- monitorSTM pid
594-
pure (pid, ref)
595-
596-
spawnImpl (spawnOptionsAffinity options) cb process
587+
spawnWithOptions options = spawnImpl (spawnOptionsAffinity options) (mkCallback options)
597588
{-# SPECIALIZE spawnWithOptions :: SpawnOptions t -> Process r a -> Process r t #-}
598589

599590
data SendOptions = SendOptions
@@ -719,22 +710,43 @@ after ::
719710
after = MatchAfter
720711
{-# INLINE after #-}
721712

713+
kindaUnlift :: (MonadProcess r m, MonadIO io) => ((ThreadAffinity -> Process r a -> io ()) -> m b) -> m b
714+
kindaUnlift foreignSpawner = do
715+
env <- getProcessEnv
716+
foreignSpawner $ \affinity action -> do
717+
_pid <- spawnImplWith env affinity pure action -- XXX: does it make sense to link/monitor a wrapped process?
718+
-- TODO: spawnImplWith should have a blocking version
719+
liftIO . forever $
720+
threadDelay 10000000
721+
722+
mkCallback :: SpawnOptions r -> ProcessId -> ReaderT (ProcessEnv a) STM r
723+
mkCallback !options pid = do
724+
when (spawnOptionsLink options) $
725+
linkSTM pid
726+
case spawnOptionsMonitor options of
727+
WithoutMonitor -> pure pid
728+
WithMonitor -> do
729+
ref <- monitorSTM pid
730+
pure (pid, ref)
731+
722732
spawnImpl :: (MonadProcess r m, MonadIO m) => ThreadAffinity -> (ProcessId -> ReaderT (ProcessEnv r) STM t) -> Process r a -> m t
723733
spawnImpl affinity cb process = do
724734
currentEnv <- getProcessEnv
735+
spawnImplWith currentEnv affinity cb process
725736

726-
liftIO $ do
727-
processContext <- newProcessContext (processEnvNodeContext currentEnv)
728-
let processEnv = currentEnv {processEnvProcessContext = processContext}
737+
spawnImplWith :: MonadIO m => ProcessEnv r -> ThreadAffinity -> (ProcessId -> ReaderT (ProcessEnv r) STM t) -> Process r a -> m t
738+
spawnImplWith currentEnv affinity cb process = liftIO $ do
739+
processContext <- newProcessContext (processEnvNodeContext currentEnv)
740+
let processEnv = currentEnv {processEnvProcessContext = processContext}
729741

730-
m <- newEmptyTMVarIO
742+
m <- newEmptyTMVarIO
731743

732-
bracketOnError
733-
(run currentEnv processEnv m)
734-
uninterruptibleCancel
735-
(wrapup m)
744+
bracketOnError
745+
(run processEnv m)
746+
uninterruptibleCancel
747+
(wrapup m)
736748
where
737-
run currentEnv processEnv m = mask_ $ async $ do
749+
run processEnv m = mask_ $ async $ do
738750
c <- newEmptyTMVarIO
739751
let act restore = atomically (readTMVar c) >>= \() -> restore (runProcess process processEnv)
740752

0 commit comments

Comments
 (0)