@@ -9,7 +9,12 @@ import Network.Transport.Test (TestTransport(..))
9
9
import Data.Binary (Binary (.. ))
10
10
import Data.Typeable (Typeable )
11
11
import Data.Foldable (forM_ )
12
- import Control.Concurrent (forkIO , threadDelay , myThreadId , throwTo , ThreadId )
12
+ import Data.IORef
13
+ ( readIORef
14
+ , writeIORef
15
+ , newIORef
16
+ )
17
+ import Control.Concurrent (forkIO , threadDelay , myThreadId , throwTo , ThreadId , yield )
13
18
import Control.Concurrent.MVar
14
19
( MVar
15
20
, newEmptyMVar
@@ -18,7 +23,7 @@ import Control.Concurrent.MVar
18
23
, readMVar
19
24
)
20
25
import Control.Monad (replicateM_ , replicateM , forever , void , unless , join )
21
- import Control.Exception (SomeException , throwIO )
26
+ import Control.Exception (SomeException , throwIO , ErrorCall ( .. ) )
22
27
import qualified Control.Exception as Ex (catch )
23
28
import Control.Applicative ((<$>) , (<*>) , pure , (<|>) )
24
29
import qualified Network.Transport as NT (closeEndPoint , EndPointAddress )
@@ -1371,6 +1376,86 @@ testUnsafeSendChan TestTransport{..} = do
1371
1376
1372
1377
takeMVar clientDone
1373
1378
1379
+ testCallLocal :: TestTransport -> Assertion
1380
+ testCallLocal TestTransport {.. } = do
1381
+ node <- newLocalNode testTransport initRemoteTable
1382
+
1383
+ -- Testing that (/=) <$> getSelfPid <*> callLocal getSelfPid.
1384
+ result <- newEmptyMVar
1385
+ runProcess node $ do
1386
+ r <- (/=) <$> getSelfPid <*> callLocal getSelfPid
1387
+ liftIO $ putMVar result r
1388
+ True <- takeMVar result
1389
+ return ()
1390
+
1391
+ -- Testing that when callLocal is interrupted, the worker is interrupted.
1392
+ ibox <- newIORef False
1393
+ runProcess node $ do
1394
+ keeper <- getSelfPid
1395
+ spawnLocal $ do
1396
+ caller <- getSelfPid
1397
+ send keeper caller
1398
+ onException
1399
+ (callLocal $ do
1400
+ onException (do send keeper caller
1401
+ expect)
1402
+ (do liftIO $ writeIORef ibox True ))
1403
+ (send keeper () )
1404
+ caller <- expect
1405
+ exit caller " test"
1406
+ () <- expect
1407
+ return ()
1408
+ True <- readIORef ibox
1409
+ return ()
1410
+
1411
+ -- Testing that when the worker raises an exception, the exception is propagated to the parent.
1412
+ ibox2 <- newIORef False
1413
+ runProcess node $ do
1414
+ r <- try (callLocal $ error " e" >> return () )
1415
+ liftIO $ writeIORef ibox2 (r == Left (ErrorCall " e" ))
1416
+ True <- readIORef ibox
1417
+ return ()
1418
+
1419
+ -- Test that caller waits for the worker in correct situation
1420
+ ibox3 <- newIORef False
1421
+ result3 <- newEmptyMVar
1422
+ runProcess node $ do
1423
+ keeper <- getSelfPid
1424
+ spawnLocal $ do
1425
+ callLocal $
1426
+ (do us <- getSelfPid
1427
+ send keeper us
1428
+ () <- expect
1429
+ liftIO yield)
1430
+ `finally` (liftIO $ writeIORef ibox3 True )
1431
+ liftIO $ putMVar result3 =<< readIORef ibox3
1432
+ worker <- expect
1433
+ send worker ()
1434
+ True <- takeMVar result3
1435
+ return ()
1436
+
1437
+ -- Test that caller waits for the worker in case when caller gets an exception
1438
+ ibox4 <- newIORef False
1439
+ result4 <- newEmptyMVar
1440
+ runProcess node $ do
1441
+ keeper <- getSelfPid
1442
+ spawnLocal $ do
1443
+ caller <- getSelfPid
1444
+ callLocal
1445
+ ((do send keeper caller
1446
+ expect)
1447
+ `finally` (liftIO $ writeIORef ibox4 True ))
1448
+ `finally` (liftIO $ putMVar result4 =<< readIORef ibox4)
1449
+ caller <- expect
1450
+ exit caller " hi!"
1451
+ True <- takeMVar result4
1452
+ return ()
1453
+ -- XXX: Testing that when mask_ $ callLocal p runs p in masked state.
1454
+
1455
+
1456
+
1457
+
1458
+
1374
1459
tests :: TestTransport -> IO [Test ]
1375
1460
tests testtrans = return [
1376
1461
testGroup " Basic features" [
@@ -1403,6 +1488,7 @@ tests testtrans = return [
1403
1488
, testCase " MaskRestoreScope" (testMaskRestoreScope testtrans)
1404
1489
, testCase " ExitLocal" (testExitLocal testtrans)
1405
1490
, testCase " ExitRemote" (testExitRemote testtrans)
1491
+ , testCase " TextCallLocal" (testCallLocal testtrans)
1406
1492
-- Unsafe Primitives
1407
1493
, testCase " TestUnsafeSend" (testUnsafeSend testtrans)
1408
1494
, testCase " TestUnsafeNSend" (testUnsafeNSend testtrans)
0 commit comments