@@ -163,7 +163,12 @@ import Prelude hiding (catch)
163
163
import Control.Monad.IO.Class (liftIO )
164
164
import Control.Applicative ((<$>) )
165
165
import Control.Monad.Reader (ask )
166
- import Control.Concurrent.MVar (newEmptyMVar , takeMVar , putMVar )
166
+ import Control.Concurrent.MVar
167
+ ( MVar
168
+ , newEmptyMVar
169
+ , takeMVar
170
+ , putMVar
171
+ )
167
172
import Control.Distributed.Static
168
173
( Closure
169
174
, closure
@@ -305,7 +310,7 @@ import Control.Distributed.Process.Internal.Spawn
305
310
, spawnSupervised
306
311
, call
307
312
)
308
- import Control.Exception (SomeException , throwIO )
313
+ import Control.Exception (SomeException , throw )
309
314
310
315
-- INTERNAL NOTES
311
316
--
@@ -401,15 +406,10 @@ spawnChannelLocal proc = do
401
406
-- messages sent to the caller process, and also allows silently dropping late
402
407
-- or duplicate messages sent to the isolated process after it exits.
403
408
-- Silently dropping messages may not always be the best approach.
404
- callLocal ::
405
- Process a -- ^ Process to run
406
- -> Process a -- ^ Value returned
407
- callLocal proc = do
408
- mv <- liftIO newEmptyMVar
409
- self <- getSelfPid
410
- _ <- spawnLocal $ do
411
- link self
412
- try proc >>= liftIO . putMVar mv
413
- liftIO $ takeMVar mv >>=
414
- either (throwIO :: SomeException -> IO a ) return
415
-
409
+ callLocal :: Process a -> Process a
410
+ callLocal proc = mask $ \ release -> do
411
+ mv <- liftIO newEmptyMVar :: Process (MVar (Either SomeException a ))
412
+ child <- spawnLocal $ try (release proc ) >>= liftIO . putMVar mv
413
+ rs <- liftIO (takeMVar mv) `onException`
414
+ (kill child " exception in parent process" >> liftIO (takeMVar mv))
415
+ either throw return rs
0 commit comments