git.iko.soy/distributed-process
on master help sign in
Introduce low level encoding checks; Extend dependencies for DPP
cafac53Tim Watson
distributed-process.cabal+2
@@ -44,6 +44,8 @@ flag prof
44Library
44Library
45 Build-Depends: base >= 4.4 && < 5,
45 Build-Depends: base >= 4.4 && < 5,
46 binary >= 0.5 && < 0.8,
46 binary >= 0.5 && < 0.8,
47+ deepseq >= 1.3.0.1 && < 1.4,
48+ hashable >= 1.2.0.5 && < 1.3,
47 network-transport >= 0.3 && < 0.4,
49 network-transport >= 0.3 && < 0.4,
48 stm >= 2.4 && < 2.5,
50 stm >= 2.4 && < 2.5,
49 transformers >= 0.2 && < 0.4,
51 transformers >= 0.2 && < 0.4,
src/Control/Distributed/Process.hs+4
@@ -53,9 +53,11 @@ module Control.Distributed.Process
53 , Message
53 , Message
54 , matchMessage
54 , matchMessage
55 , matchMessageIf
55 , matchMessageIf
56+ , isEncoded
56 , wrapMessage
57 , wrapMessage
57 , unwrapMessage
58 , unwrapMessage
58 , handleMessage
59 , handleMessage
60+ , handleMessageIf
59 , forward
61 , forward
60 , delegate
62 , delegate
61 , relay
63 , relay
@@ -206,9 +208,11 @@ import Control.Distributed.Process.Internal.Primitives
206 , matchChan
208 , matchChan
207 , matchMessage
209 , matchMessage
208 , matchMessageIf
210 , matchMessageIf
211+ , isEncoded
209 , wrapMessage
212 , wrapMessage
210 , unwrapMessage
213 , unwrapMessage
211 , handleMessage
214 , handleMessage
215+ , handleMessageIf
212 , forward
216 , forward
213 , delegate
217 , delegate
214 , relay
218 , relay
src/Control/Distributed/Process/Internal/Primitives.hs+31−17
@@ -30,9 +30,11 @@ module Control.Distributed.Process.Internal.Primitives
30 , matchChan
30 , matchChan
31 , matchMessage
31 , matchMessage
32 , matchMessageIf
32 , matchMessageIf
33+ , isEncoded
33 , wrapMessage
34 , wrapMessage
34 , unwrapMessage
35 , unwrapMessage
35 , handleMessage
36 , handleMessage
37+ , handleMessageIf
36 , forward
38 , forward
37 , delegate
39 , delegate
38 , relay
40 , relay
@@ -173,10 +175,11 @@ import Control.Distributed.Process.Internal.Types
173 , ProcessRegistrationException(..)
175 , ProcessRegistrationException(..)
174 , ProcessInfo(..)
176 , ProcessInfo(..)
175 , ProcessInfoNone(..)
177 , ProcessInfoNone(..)
178+ , isEncoded
176 , createMessage
179 , createMessage
177 , createUnencodedMessage
180 , createUnencodedMessage
178 , runLocalProcess
181 , runLocalProcess
179− , ImplicitReconnect(NoImplicitReconnect)
182+ , ImplicitReconnect( NoImplicitReconnect)
180 , LocalProcessState
183 , LocalProcessState
181 , LocalSendPortId
184 , LocalSendPortId
182 , messageToPayload
185 , messageToPayload
@@ -444,14 +447,14 @@ wrapMessage = createUnencodedMessage -- see [note Serializable UnencodedMessage]
444-- Whereas this expression, will yield @Just "foo"@
447-- Whereas this expression, will yield @Just "foo"@
445-- > unwrapMessage (wrapMessage "foo") :: Process (Maybe String)
448-- > unwrapMessage (wrapMessage "foo") :: Process (Maybe String)
446--
449--
447−unwrapMessage :: forall a. Serializable a => Message -> Process (Maybe a)
450+unwrapMessage :: forall m a. (Monad m, Serializable a) => Message -> m (Maybe a)
448unwrapMessage msg =
451unwrapMessage msg =
449 case messageFingerprint msg == fingerprint (undefined :: a) of
452 case messageFingerprint msg == fingerprint (undefined :: a) of
450− False -> return Nothing
453+ False -> return Nothing :: m (Maybe a)
451 True -> case msg of
454 True -> case msg of
452− (UnencodedMessage _ m) ->
455+ (UnencodedMessage _ ms) ->
453− let m' = unsafeCoerce m :: a
456+ let ms' = unsafeCoerce ms :: a
454− in return (Just m')
457+ in return (Just ms')
455 (EncodedMessage _ _) ->
458 (EncodedMessage _ _) ->
456 return (Just (decoded))
459 return (Just (decoded))
457 where
460 where
@@ -467,17 +470,28 @@ unwrapMessage msg =
467--
470--
468-- Intended for use in `catchesExit` and `matchAny` primitives.
471-- Intended for use in `catchesExit` and `matchAny` primitives.
469--
472--
470−handleMessage :: forall a b. (Serializable a)
473+handleMessage :: forall m a b. (Monad m, Serializable a)
471− => Message -> (a -> Process b) -> Process (Maybe b)
474+ => Message -> (a -> m b) -> m (Maybe b)
472−handleMessage msg proc = do
475+handleMessage msg proc = handleMessageIf msg (const True) proc
476+
477+handleMessageIf :: forall m a b . (Monad m, Serializable a)
478+ => Message
479+ -> (a -> Bool)
480+ -> (a -> m b)
481+ -> m (Maybe b)
482+handleMessageIf msg c proc = do
473 case messageFingerprint msg == fingerprint (undefined :: a) of
483 case messageFingerprint msg == fingerprint (undefined :: a) of
474− False -> return Nothing
484+ False -> return Nothing :: m (Maybe b)
475 True -> case msg of
485 True -> case msg of
476− (UnencodedMessage _ m) ->
486+ (UnencodedMessage _ ms) ->
477− let m' = unsafeCoerce m :: a -- note [decoding]
487+ let ms' = unsafeCoerce ms :: a in
488+ case (c ms') of
478− in do { r <- proc m'; return (Just r) }
489+ True -> do { r <- proc ms'; return (Just r) }
490+ False -> return Nothing :: m (Maybe b)
479 (EncodedMessage _ _) ->
491 (EncodedMessage _ _) ->
492+ case (c decoded) of
480− do { r <- proc (decoded :: a); return (Just r) }
493+ True -> do { r <- proc (decoded :: a); return (Just r) }
494+ False -> return Nothing :: m (Maybe b)
481 where
495 where
482 decoded :: a -- note [decoding]
496 decoded :: a -- note [decoding]
483 !decoded = decode (messageEncoding msg)
497 !decoded = decode (messageEncoding msg)
@@ -627,12 +641,12 @@ catchExit act exitHandler = catch act handleExit
627-- | Lift 'Control.Exception.catches' (almost).
641-- | Lift 'Control.Exception.catches' (almost).
628--
642--
629-- As 'ProcessExitException' stores the exit @reason@ as a typed, encoded
643-- As 'ProcessExitException' stores the exit @reason@ as a typed, encoded
630−-- message, a handler must accept an input of the expected type. In order to
644+-- message, a handler must accept inputs of the expected type. In order to
631-- handle a list of potentially different handlers (and therefore input types),
645-- handle a list of potentially different handlers (and therefore input types),
632−-- a handler passed to 'catchesExit' must accept 'AbstractMessage' and return
646+-- a handler passed to 'catchesExit' must accept 'Message' and return
633-- @Maybe@ (i.e., @Just p@ if it handled the exit reason, otherwise @Nothing@).
647-- @Maybe@ (i.e., @Just p@ if it handled the exit reason, otherwise @Nothing@).
634--
648--
635−-- See 'maybeHandleMessage' and 'AsbtractMessage' for more details.
649+-- See 'maybeHandleMessage' and 'Message' for more details.
636catchesExit :: Process b
650catchesExit :: Process b
637 -> [(ProcessId -> Message -> (Process (Maybe b)))]
651 -> [(ProcessId -> Message -> (Process (Maybe b)))]
638 -> Process b
652 -> Process b
src/Control/Distributed/Process/Internal/Spawn.hs+1−2
@@ -7,7 +7,6 @@ module Control.Distributed.Process.Internal.Spawn
7 , spawnChannel
7 , spawnChannel
8 ) where
8 ) where
9
9
10−import Data.Typeable (Typeable)
11import Control.Distributed.Static
10import Control.Distributed.Static
12 ( Static
11 ( Static
13 , Closure
12 , Closure
@@ -144,7 +143,7 @@ spawnSupervised nid proc = do
144
143
145-- | Spawn a new process, supplying it with a new 'ReceivePort' and return
144-- | Spawn a new process, supplying it with a new 'ReceivePort' and return
146-- the corresponding 'SendPort'.
145-- the corresponding 'SendPort'.
147−spawnChannel :: forall a. Typeable a => Static (SerializableDict a)
146+spawnChannel :: forall a. Serializable a => Static (SerializableDict a)
148 -> NodeId
147 -> NodeId
149 -> Closure (ReceivePort a -> Process ())
148 -> Closure (ReceivePort a -> Process ())
150 -> Process (SendPort a)
149 -> Process (SendPort a)
src/Control/Distributed/Process/Internal/Types.hs+50−16
@@ -1,3 +1,5 @@
1+{-# LANGUAGE DeriveGeneric #-}
2+
1-- | Types used throughout the Cloud Haskell framework
3-- | Types used throughout the Cloud Haskell framework
2--
4--
3-- We collect all types used internally in a single module because
5-- We collect all types used internally in a single module because
@@ -29,6 +31,7 @@ module Control.Distributed.Process.Internal.Types
29 , ReceivePort(..)
31 , ReceivePort(..)
30 -- * Messages
32 -- * Messages
31 , Message(..)
33 , Message(..)
34+ , isEncoded
32 , createMessage
35 , createMessage
33 , createUnencodedMessage
36 , createUnencodedMessage
34 , unsafeCreateUnencodedMessage
37 , unsafeCreateUnencodedMessage
@@ -77,7 +80,7 @@ module Control.Distributed.Process.Internal.Types
77import System.Mem.Weak (Weak)
80import System.Mem.Weak (Weak)
78import Data.Map (Map)
81import Data.Map (Map)
79import Data.Int (Int32)
82import Data.Int (Int32)
80−import Data.Typeable (Typeable)
83+import Data.Typeable (Typeable, typeOf)
81import Data.Binary (Binary(put, get), putWord8, getWord8, encode)
84import Data.Binary (Binary(put, get), putWord8, getWord8, encode)
82import qualified Data.ByteString as BSS (ByteString, concat, copy)
85import qualified Data.ByteString as BSS (ByteString, concat, copy)
83import qualified Data.ByteString.Lazy as BSL
86import qualified Data.ByteString.Lazy as BSL
@@ -90,6 +93,7 @@ import qualified Data.ByteString.Lazy as BSL
90import qualified Data.ByteString.Lazy.Internal as BSL (ByteString(..))
93import qualified Data.ByteString.Lazy.Internal as BSL (ByteString(..))
91import Data.Accessor (Accessor, accessor)
94import Data.Accessor (Accessor, accessor)
92import Control.Category ((>>>))
95import Control.Category ((>>>))
96+import Control.DeepSeq (NFData(..))
93import Control.Exception (Exception)
97import Control.Exception (Exception)
94import Control.Concurrent (ThreadId)
98import Control.Concurrent (ThreadId)
95import Control.Concurrent.Chan (Chan)
99import Control.Concurrent.Chan (Chan)
@@ -113,14 +117,19 @@ import Control.Distributed.Process.Internal.WeakTQueue (TQueue)
113import Control.Distributed.Static (RemoteTable, Closure)
117import Control.Distributed.Static (RemoteTable, Closure)
114import qualified Control.Distributed.Process.Internal.StrictContainerAccessors as DAC (mapMaybe)
118import qualified Control.Distributed.Process.Internal.StrictContainerAccessors as DAC (mapMaybe)
115
119
120+import Data.Hashable
121+import GHC.Generics
122+
116--------------------------------------------------------------------------------
123--------------------------------------------------------------------------------
117-- Node and process identifiers --
124-- Node and process identifiers --
118--------------------------------------------------------------------------------
125--------------------------------------------------------------------------------
119
126
120-- | Node identifier
127-- | Node identifier
121newtype NodeId = NodeId { nodeAddress :: NT.EndPointAddress }
128newtype NodeId = NodeId { nodeAddress :: NT.EndPointAddress }
122− deriving (Eq, Ord, Binary, Typeable)
129+ deriving (Eq, Ord, Typeable, Generic)
123−
130+instance Binary NodeId where
131+instance NFData NodeId
132+instance Hashable NodeId where
124instance Show NodeId where
133instance Show NodeId where
125 show (NodeId addr) = "nid://" ++ show addr
134 show (NodeId addr) = "nid://" ++ show addr
126
135
@@ -130,7 +139,9 @@ data LocalProcessId = LocalProcessId
130 { lpidUnique :: {-# UNPACK #-} !Int32
139 { lpidUnique :: {-# UNPACK #-} !Int32
131 , lpidCounter :: {-# UNPACK #-} !Int32
140 , lpidCounter :: {-# UNPACK #-} !Int32
132 }
141 }
133− deriving (Eq, Ord, Typeable, Show)
142+ deriving (Eq, Ord, Typeable, Generic, Show)
143+
144+instance Hashable LocalProcessId where
134
145
135-- | Process identifier
146-- | Process identifier
136data ProcessId = ProcessId
147data ProcessId = ProcessId
@@ -139,7 +150,11 @@ data ProcessId = ProcessId
139 -- | Node-local identifier for the process
150 -- | Node-local identifier for the process
140 , processLocalId :: {-# UNPACK #-} !LocalProcessId
151 , processLocalId :: {-# UNPACK #-} !LocalProcessId
141 }
152 }
142− deriving (Eq, Ord, Typeable)
153+ deriving (Eq, Ord, Typeable, Generic)
154+
155+instance Binary ProcessId where
156+instance NFData ProcessId where
157+instance Hashable ProcessId where
143
158
144instance Show ProcessId where
159instance Show ProcessId where
145 show (ProcessId (NodeId addr) (LocalProcessId _ lid))
160 show (ProcessId (NodeId addr) (LocalProcessId _ lid))
@@ -150,7 +165,9 @@ data Identifier =
150 NodeIdentifier !NodeId
165 NodeIdentifier !NodeId
151 | ProcessIdentifier !ProcessId
166 | ProcessIdentifier !ProcessId
152 | SendPortIdentifier !SendPortId
167 | SendPortIdentifier !SendPortId
153− deriving (Eq, Ord)
168+ deriving (Eq, Ord, Generic)
169+
170+instance Hashable Identifier where
154
171
155instance Show Identifier where
172instance Show Identifier where
156 show (NodeIdentifier nid) = show nid
173 show (NodeIdentifier nid) = show nid
@@ -276,8 +293,9 @@ data SendPortId = SendPortId {
276 -- | Process-local ID of the channel
293 -- | Process-local ID of the channel
277 , sendPortLocalId :: {-# UNPACK #-} !LocalSendPortId
294 , sendPortLocalId :: {-# UNPACK #-} !LocalSendPortId
278 }
295 }
279− deriving (Eq, Ord)
296+ deriving (Eq, Ord, Typeable, Generic)
280
297
298+instance Hashable SendPortId where
281instance Show SendPortId where
299instance Show SendPortId where
282 show (SendPortId (ProcessId (NodeId addr) (LocalProcessId _ plid)) clid)
300 show (SendPortId (ProcessId (NodeId addr) (LocalProcessId _ plid)) clid)
283 = "cid://" ++ show addr ++ ":" ++ show plid ++ ":" ++ show clid
301 = "cid://" ++ show addr ++ ":" ++ show plid ++ ":" ++ show clid
@@ -289,7 +307,11 @@ newtype SendPort a = SendPort {
289 -- | The (unique) ID of this send port
307 -- | The (unique) ID of this send port
290 sendPortId :: SendPortId
308 sendPortId :: SendPortId
291 }
309 }
292− deriving (Typeable, Binary, Show, Eq, Ord)
310+ deriving (Typeable, Generic, Show, Eq, Ord)
311+
312+instance (Serializable a) => Binary (SendPort a) where
313+instance (Hashable a) => Hashable (SendPort a) where
314+instance (NFData a) => NFData (SendPort a) where
293
315
294-- | The receive end of a typed channel (not serializable)
316-- | The receive end of a typed channel (not serializable)
295--
317--
@@ -329,7 +351,19 @@ data Message =
329
351
330instance Show Message where
352instance Show Message where
331 show (EncodedMessage fp enc) = show enc ++ " :: " ++ showFingerprint fp []
353 show (EncodedMessage fp enc) = show enc ++ " :: " ++ showFingerprint fp []
332− show (UnencodedMessage fp _) = "[unencoded message] :: " ++ (showFingerprint fp [])
354+ show (UnencodedMessage _ uenc) = "[unencoded message] :: " ++ (show $ typeOf uenc)
355+
356+-- | /internal use only/.
357+isEncoded :: Message -> Bool
358+isEncoded (EncodedMessage _ _) = True
359+isEncoded _ = False
360+-- [note] isEncoded:
361+-- This is just as internal as it looks and yes, it does feel a bit odd that
362+-- we're exporting it for use, however DPP does a /lot/ of work with low
363+-- level APIs such as unwrapMessage and handleMessage, and in the process
364+-- tries very hard to avoid copying (and re-serialisation) where possible.
365+-- Being able to determine that a message is encoded (or otherwise) makes
366+-- that a lot more manageable.
333
367
334-- | Turn any serialiable term into a message
368-- | Turn any serialiable term into a message
335createMessage :: Serializable a => a -> Message
369createMessage :: Serializable a => a -> Message
@@ -377,7 +411,8 @@ data MonitorRef = MonitorRef
377 -- | Unique to distinguish multiple monitor requests by the same process
411 -- | Unique to distinguish multiple monitor requests by the same process
378 , monitorRefCounter :: !Int32
412 , monitorRefCounter :: !Int32
379 }
413 }
380− deriving (Eq, Ord, Show)
414+ deriving (Eq, Ord, Show, Generic)
415+instance Hashable MonitorRef where
381
416
382-- | Message sent by process monitors
417-- | Message sent by process monitors
383data ProcessMonitorNotification =
418data ProcessMonitorNotification =
@@ -531,10 +566,6 @@ instance Binary LocalProcessId where
531 put lpid = put (lpidUnique lpid) >> put (lpidCounter lpid)
566 put lpid = put (lpidUnique lpid) >> put (lpidCounter lpid)
532 get = LocalProcessId <$> get <*> get
567 get = LocalProcessId <$> get <*> get
533
568
534−instance Binary ProcessId where
535− put pid = put (processNodeId pid) >> put (processLocalId pid)
536− get = ProcessId <$> get <*> get
537−
538instance Binary ProcessMonitorNotification where
569instance Binary ProcessMonitorNotification where
539 put (ProcessMonitorNotification ref pid reason) = put ref >> put pid >> put reason
570 put (ProcessMonitorNotification ref pid reason) = put ref >> put pid >> put reason
540 get = ProcessMonitorNotification <$> get <*> get <*> get
571 get = ProcessMonitorNotification <$> get <*> get <*> get
@@ -567,7 +598,7 @@ instance Binary ProcessSignal where
567 put (NamedSend label msg) = putWord8 8 >> put label >> put (messageToPayload msg)
598 put (NamedSend label msg) = putWord8 8 >> put label >> put (messageToPayload msg)
568 put (Kill pid reason) = putWord8 9 >> put pid >> put reason
599 put (Kill pid reason) = putWord8 9 >> put pid >> put reason
569 put (Exit pid reason) = putWord8 10 >> put pid >> put (messageToPayload reason)
600 put (Exit pid reason) = putWord8 10 >> put pid >> put (messageToPayload reason)
570− put (LocalSend to msg) = putWord8 11 >> put to >> put (messageToPayload msg)
601+ put (LocalSend to' msg) = putWord8 11 >> put to' >> put (messageToPayload msg)
571 put (LocalPortSend sid msg) = putWord8 12 >> put sid >> put (messageToPayload msg)
602 put (LocalPortSend sid msg) = putWord8 12 >> put sid >> put (messageToPayload msg)
572 put (GetInfo about) = putWord8 30 >> put about
603 put (GetInfo about) = putWord8 30 >> put about
573 put (SigShutdown) = putWord8 31
604 put (SigShutdown) = putWord8 31
@@ -615,6 +646,9 @@ instance Binary SendPortId where
615 put cid = put (sendPortProcessId cid) >> put (sendPortLocalId cid)
646 put cid = put (sendPortProcessId cid) >> put (sendPortLocalId cid)
616 get = SendPortId <$> get <*> get
647 get = SendPortId <$> get <*> get
617
648
649+instance NFData SendPortId where
650+ rnf cid = (sendPortProcessId cid) `seq` (sendPortLocalId cid) `seq` ()
651+
618instance Binary Identifier where
652instance Binary Identifier where
619 put (ProcessIdentifier pid) = putWord8 0 >> put pid
653 put (ProcessIdentifier pid) = putWord8 0 >> put pid
620 put (NodeIdentifier nid) = putWord8 1 >> put nid
654 put (NodeIdentifier nid) = putWord8 1 >> put nid
@@ -667,7 +701,7 @@ localProcessWithId :: LocalProcessId -> Accessor LocalNodeState (Maybe LocalProc
667localProcessWithId lpid = localProcesses >>> DAC.mapMaybe lpid
701localProcessWithId lpid = localProcesses >>> DAC.mapMaybe lpid
668
702
669localConnectionBetween :: Identifier -> Identifier -> Accessor LocalNodeState (Maybe (NT.Connection, ImplicitReconnect))
703localConnectionBetween :: Identifier -> Identifier -> Accessor LocalNodeState (Maybe (NT.Connection, ImplicitReconnect))
670−localConnectionBetween from to = localConnections >>> DAC.mapMaybe (from, to)
704+localConnectionBetween from' to' = localConnections >>> DAC.mapMaybe (from', to')
671
705
672monitorCounter :: Accessor LocalProcessState Int32
706monitorCounter :: Accessor LocalProcessState Int32
673monitorCounter = accessor _monitorCounter (\cnt st -> st { _monitorCounter = cnt })
707monitorCounter = accessor _monitorCounter (\cnt st -> st { _monitorCounter = cnt })
tests/TestCH.hs+31−7
@@ -36,11 +36,11 @@ import Control.Distributed.Process.Internal.Types
36import Control.Distributed.Process.Node
36import Control.Distributed.Process.Node
37import Control.Distributed.Process.Serializable (Serializable)
37import Control.Distributed.Process.Serializable (Serializable)
38
38
39−import Test.HUnit (Assertion)
39+import Test.HUnit (Assertion, assertFailure)
40import Test.Framework (Test, defaultMain, testGroup)
40import Test.Framework (Test, defaultMain, testGroup)
41import Test.Framework.Providers.HUnit (testCase)
41import Test.Framework.Providers.HUnit (testCase)
42−import Control.Rematch hiding (expect, match)
42+import Control.Rematch hiding (match)
43−import qualified Control.Rematch as Rematch (expect)
43+import Control.Rematch.Run (Match(..))
44
44
45newtype Ping = Ping ProcessId
45newtype Ping = Ping ProcessId
46 deriving (Typeable, Binary, Show)
46 deriving (Typeable, Binary, Show)
@@ -52,6 +52,12 @@ newtype Pong = Pong ProcessId
52-- Supporting definitions --
52-- Supporting definitions --
53--------------------------------------------------------------------------------
53--------------------------------------------------------------------------------
54
54
55+expectThat :: a -> Matcher a -> Assertion
56+expectThat a matcher = case res of
57+ MatchSuccess -> return ()
58+ (MatchFailure msg) -> assertFailure msg
59+ where res = runMatch matcher a
60+
55-- | Like fork, but throw exceptions in the child thread to the parent
61-- | Like fork, but throw exceptions in the child thread to the parent
56forkTry :: IO () -> IO ThreadId
62forkTry :: IO () -> IO ThreadId
57forkTry p = do
63forkTry p = do
@@ -1080,6 +1086,22 @@ testCatchesExit transport = do
1080
1086
1081 takeMVar done
1087 takeMVar done
1082
1088
1089+testHandleMessageIf :: NT.Transport -> Assertion
1090+testHandleMessageIf transport = do
1091+ localNode <- newLocalNode transport initRemoteTable
1092+ done <- newEmptyMVar
1093+ _ <- forkProcess localNode $ do
1094+ self <- getSelfPid
1095+ send self (5 :: Integer, 10 :: Integer)
1096+ msg <- receiveWait [ matchMessage return ]
1097+ Nothing <- handleMessageIf msg (\() -> True) (\() -> die $ "whoops")
1098+ handleMessageIf msg (\(x :: Integer, y :: Integer) -> x == 5 && y == 10)
1099+ (\input -> liftIO $ putMVar done input)
1100+ return ()
1101+
1102+ result <- takeMVar done
1103+ expectThat result $ equalTo (5, 10)
1104+
1083testCatches :: NT.Transport -> Assertion
1105testCatches :: NT.Transport -> Assertion
1084testCatches transport = do
1106testCatches transport = do
1085 localNode <- newLocalNode transport initRemoteTable
1107 localNode <- newLocalNode transport initRemoteTable
@@ -1106,7 +1128,7 @@ testMaskRestoreScope transport = do
1106
1128
1107 parent <- liftIO $ takeMVar parentPid
1129 parent <- liftIO $ takeMVar parentPid
1108 child <- liftIO $ takeMVar spawnedPid
1130 child <- liftIO $ takeMVar spawnedPid
1109− Rematch.expect parent $ isNot $ equalTo child
1131+ expectThat parent $ isNot $ equalTo child
1110
1132
1111testDie :: NT.Transport -> Assertion
1133testDie :: NT.Transport -> Assertion
1112testDie transport = do
1134testDie transport = do
@@ -1256,6 +1278,7 @@ tests (transport, transportInternals) = [
1256 , testCase "Registry" (testRegistry transport)
1278 , testCase "Registry" (testRegistry transport)
1257 , testCase "RemoteRegistry" (testRemoteRegistry transport)
1279 , testCase "RemoteRegistry" (testRemoteRegistry transport)
1258 , testCase "SpawnLocal" (testSpawnLocal transport)
1280 , testCase "SpawnLocal" (testSpawnLocal transport)
1281+ , testCase "HandleMessageIf" (testHandleMessageIf transport)
1259 , testCase "MatchAny" (testMatchAny transport)
1282 , testCase "MatchAny" (testMatchAny transport)
1260 , testCase "MatchAnyHandle" (testMatchAnyHandle transport)
1283 , testCase "MatchAnyHandle" (testMatchAnyHandle transport)
1261 , testCase "MatchAnyNoHandle" (testMatchAnyNoHandle transport)
1284 , testCase "MatchAnyNoHandle" (testMatchAnyNoHandle transport)
@@ -1272,6 +1295,10 @@ tests (transport, transportInternals) = [
1272 , testCase "MaskRestoreScope" (testMaskRestoreScope transport)
1295 , testCase "MaskRestoreScope" (testMaskRestoreScope transport)
1273 , testCase "ExitLocal" (testExitLocal transport)
1296 , testCase "ExitLocal" (testExitLocal transport)
1274 , testCase "ExitRemote" (testExitRemote transport)
1297 , testCase "ExitRemote" (testExitRemote transport)
1298+ -- Unsafe Primitives
1299+ , testCase "TestUnsafeSend" (testUnsafeSend transport)
1300+ , testCase "TestUnsafeNSend" (testUnsafeNSend transport)
1301+ , testCase "TestUnsafeSendChan" (testUnsafeSendChan transport)
1275 ]
1302 ]
1276 , testGroup "Monitoring and Linking" [
1303 , testGroup "Monitoring and Linking" [
1277 -- Monitoring processes
1304 -- Monitoring processes
@@ -1303,9 +1330,6 @@ tests (transport, transportInternals) = [
1303 , testCase "MonitorChannel" (testMonitorChannel transport)
1330 , testCase "MonitorChannel" (testMonitorChannel transport)
1304 -- Reconnect
1331 -- Reconnect
1305 , testCase "Reconnect" (testReconnect transport transportInternals)
1332 , testCase "Reconnect" (testReconnect transport transportInternals)
1306− , testCase "TestUnsafeSend" (testUnsafeSend transport)
1307− , testCase "TestUnsafeNSend" (testUnsafeNSend transport)
1308− , testCase "TestUnsafeSendChan" (testUnsafeSendChan transport)
1309 ]
1333 ]
1310 ]
1334 ]
1311
1335