@@ -46,11 +46,11 @@ import Control.Distributed.Process.Debug
46import Control.Distributed.Process.Management.Internal.Types
46import Control.Distributed.Process.Management.Internal.Types
47import Control.Distributed.Process.Tests.Internal.Utils (shouldBe, pause)
47import Control.Distributed.Process.Tests.Internal.Utils (shouldBe, pause)
48import Control.Distributed.Process.Serializable (Serializable)
48import Control.Distributed.Process.Serializable (Serializable)
49−
49+import Data.Maybe (isNothing)
50import Test.HUnit (Assertion, assertBool, assertFailure)
50import Test.HUnit (Assertion, assertBool, assertFailure)
51import Test.Framework (Test, testGroup)
51import Test.Framework (Test, testGroup)
52import Test.Framework.Providers.HUnit (testCase)
52import Test.Framework.Providers.HUnit (testCase)
53−import Control.Rematch hiding (match)
53+import Control.Rematch hiding (match, isNothing)
54import Control.Rematch.Run (Match(..))
54import Control.Rematch.Run (Match(..))
56newtype Ping = Ping ProcessId
56newtype Ping = Ping ProcessId
@@ -1272,6 +1272,76 @@ testReceiveChanFeatures TestTransport{..} = do
1273 takeMVar done
1273 takeMVar done
1275+testChanLifecycle :: TestTransport -> Assertion
1276+testChanLifecycle TestTransport{..} = let delay = 3000000 in do
1277+ result <- newEmptyMVar
1278+ tchMV <- newEmptyMVar
1279+ localNode <- newLocalNode testTransport initRemoteTable
1280+ runProcess localNode $ do
1282+ pid <- spawnLocal $ do tCh <- newChan :: Process (SendPort (), ReceivePort ())
1283+ liftIO $ putMVar tchMV tCh
1284+ expect :: Process ()
1287+ expect :: Process ()
1289+ mRefPid <- monitor pid
1291+ cPid <- spawnLocal $ do
1292+ (sp', rp) <- liftIO $ takeMVar tchMV
1293+ -- say "picked up our test channel"
1295+ -- say "told pid to continue"
1296+ res <- receiveChanTimeout delay rp
1298+ Nothing -> say "initial chan () missing!" >> (liftIO $ putMVar result False)
1299+ Just () -> do mr <- monitor pid
1301+ -- say "sending pid a second () will cause it to exit"
1304+ -- say "make sure we see a DOWN notification for pid having stopped"
1305+ receiveWait [ match (\(_ :: ProcessMonitorNotification) -> return ()) ]
1307+ -- now that pid has died, the send port should be useless...
1308+ liftIO $ putMVar tchMV (sp', rp)
1310+ -- let's verify that we do not see the message from our
1311+ -- parent process on the channel, once pid has died...
1312+ recv <- receiveChanTimeout delay rp
1313+ -- say $ "finished waiting for second (), writing result" ++ (show recv)
1314+ liftIO $ putMVar result $ isNothing recv
1316+ mRefCPid <- monitor cPid
1319+ [ matchIf (\(ProcessMonitorNotification r _ _) -> r == mRefPid)
1323+ -- say "seen first pid die..."
1325+ (sendPort, _) <- liftIO $ takeMVar tchMV
1326+ sendChan sendPort ()
1327+ -- say "sent () after owning pid died"
1329+ -- let cPid know we've written to the channel...
1333+ [ matchIf (\(ProcessMonitorNotification r _ _) -> r == mRefCPid)
1337+ -- say "seen both pids die now..."
1339+ -- and wait on the result back in IO land...
1340+ testRes <- takeMVar result
1341+ -- runProcess localNode $ say "got result..."
1342+ assertBool "Expected sending on the channel to fail, but received data!" testRes
1275testKillLocal :: TestTransport -> Assertion
1345testKillLocal :: TestTransport -> Assertion
1276testKillLocal TestTransport{..} = do
1346testKillLocal TestTransport{..} = do
1277 localNode <- newLocalNode testTransport initRemoteTable
1347 localNode <- newLocalNode testTransport initRemoteTable
@@ -1736,6 +1806,7 @@ tests testtrans = return [
1736 , testCase "MatchMessageUnwrap" (testMatchMessageWithUnwrap testtrans)
1806 , testCase "MatchMessageUnwrap" (testMatchMessageWithUnwrap testtrans)
1737 , testCase "ReceiveChanTimeout" (testReceiveChanTimeout testtrans)
1807 , testCase "ReceiveChanTimeout" (testReceiveChanTimeout testtrans)
1738 , testCase "ReceiveChanFeatures" (testReceiveChanFeatures testtrans)
1808 , testCase "ReceiveChanFeatures" (testReceiveChanFeatures testtrans)
1809+ , testCase "ChanLifecycle" (testChanLifecycle testtrans)
1739 , testCase "KillLocal" (testKillLocal testtrans)
1810 , testCase "KillLocal" (testKillLocal testtrans)
1740 , testCase "KillRemote" (testKillRemote testtrans)
1811 , testCase "KillRemote" (testKillRemote testtrans)
1741 , testCase "Die" (testDie testtrans)
1812 , testCase "Die" (testDie testtrans)