summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/Network/QueryResponse.hs44
-rw-r--r--src/Network/Tox.hs5
2 files changed, 28 insertions, 21 deletions
diff --git a/src/Network/QueryResponse.hs b/src/Network/QueryResponse.hs
index b7a402b4..8c793a1a 100644
--- a/src/Network/QueryResponse.hs
+++ b/src/Network/QueryResponse.hs
@@ -22,6 +22,7 @@ import Control.Monad
22import qualified Data.ByteString as B 22import qualified Data.ByteString as B
23 ;import Data.ByteString (ByteString) 23 ;import Data.ByteString (ByteString)
24import Data.Function 24import Data.Function
25import Data.Functor.Contravariant
25import qualified Data.IntMap.Strict as IntMap 26import qualified Data.IntMap.Strict as IntMap
26 ;import Data.IntMap.Strict (IntMap) 27 ;import Data.IntMap.Strict (IntMap)
27import qualified Data.Map.Strict as Map 28import qualified Data.Map.Strict as Map
@@ -160,7 +161,7 @@ sendQuery (Client net d err pending whoami _) meth q addr = do
160 mvar <- newEmptyMVar 161 mvar <- newEmptyMVar
161 tid <- atomically $ do 162 tid <- atomically $ do
162 tbl <- readTVar pending 163 tbl <- readTVar pending
163 let (tid, tbl') = dispatchRegister (tableMethods d) mvar tbl 164 (tid, tbl') <- dispatchRegister (tableMethods d) mvar tbl
164 writeTVar pending tbl' 165 writeTVar pending tbl'
165 return tid 166 return tid
166 self <- whoami (Just addr) 167 self <- whoami (Just addr)
@@ -169,7 +170,7 @@ sendQuery (Client net d err pending whoami _) meth q addr = do
169 case mres of 170 case mres of
170 Just x -> return $ Just $ unwrapResponse meth x 171 Just x -> return $ Just $ unwrapResponse meth x
171 Nothing -> do 172 Nothing -> do
172 atomically $ modifyTVar' pending (dispatchCancel (tableMethods d) tid) 173 atomically $ readTVar pending >>= dispatchCancel (tableMethods d) tid >>= writeTVar pending
173 reportTimeout err (method meth) tid addr 174 reportTimeout err (method meth) tid addr
174 return Nothing 175 return Nothing
175 176
@@ -278,15 +279,15 @@ data TransactionMethods d tid x = TransactionMethods
278 -- response will be written too. The returned /tid/ is a transaction id 279 -- response will be written too. The returned /tid/ is a transaction id
279 -- that can be used to forget the 'MVar' if the remote peer is not 280 -- that can be used to forget the 'MVar' if the remote peer is not
280 -- responding. 281 -- responding.
281 dispatchRegister :: MVar x -> d -> (tid, d) 282 dispatchRegister :: MVar x -> d -> STM (tid, d)
282 -- | This method is invoked when an incomming packet /x/ indicates it is 283 -- | This method is invoked when an incomming packet /x/ indicates it is
283 -- a response to the transaction with id /tid/. The returned IO action 284 -- a response to the transaction with id /tid/. The returned IO action
284 -- is will write the packet to the correct 'MVar' thus completing the 285 -- is will write the packet to the correct 'MVar' thus completing the
285 -- dispatch. 286 -- dispatch.
286 , dispatchResponse :: tid -> x -> d -> (d, IO ()) 287 , dispatchResponse :: tid -> x -> d -> STM (d, IO ())
287 -- | When a timeout interval elapses, this method is called to remove the 288 -- | When a timeout interval elapses, this method is called to remove the
288 -- transaction from the table. 289 -- transaction from the table.
289 , dispatchCancel :: tid -> d -> d 290 , dispatchCancel :: tid -> d -> STM d
290 } 291 }
291 292
292-- | The standard lookup table methods for use as input to 'transactionMethods' 293-- | The standard lookup table methods for use as input to 'transactionMethods'
@@ -314,10 +315,12 @@ mapMethods = TableMethods Map.insert Map.delete Map.lookup
314-- only a part of the generated /tid/ value. This is useful for /tid/ types 315-- only a part of the generated /tid/ value. This is useful for /tid/ types
315-- that are especially large due their use for other purposes, such as secure 316-- that are especially large due their use for other purposes, such as secure
316-- nonces for encryption. 317-- nonces for encryption.
317contramapT f (TableMethods ins del lookup) = 318instance Contravariant (TableMethods t) where
318 TableMethods (\k v t -> ins (f k) v t) 319 -- contramap :: (tid -> t1) -> TableMethods t t1 -> TableMethods t tid
319 (\k t -> del (f k) t) 320 contramap f (TableMethods ins del lookup) =
320 (\k t -> lookup (f k) t) 321 TableMethods (\k v t -> ins (f k) v t)
322 (\k t -> del (f k) t)
323 (\k t -> lookup (f k) t)
321 324
322-- | Since 'Int' may be 32 or 64 bits, this function is provided as a 325-- | Since 'Int' may be 32 or 64 bits, this function is provided as a
323-- convenience to test if an integral type, such as 'Data.Word.Word64', can be 326-- convenience to test if an integral type, such as 'Data.Word.Word64', can be
@@ -338,16 +341,16 @@ transactionMethods ::
338 -> (g -> (tid,g)) -- ^ Generate a new unique /tid/ value and update the generator state /g/. 341 -> (g -> (tid,g)) -- ^ Generate a new unique /tid/ value and update the generator state /g/.
339 -> TransactionMethods (g,t (MVar x)) tid x 342 -> TransactionMethods (g,t (MVar x)) tid x
340transactionMethods (TableMethods insert delete lookup) generate = TransactionMethods 343transactionMethods (TableMethods insert delete lookup) generate = TransactionMethods
341 { dispatchCancel = \tid (g,t) -> (g, delete tid t) 344 { dispatchCancel = \tid (g,t) -> return (g, delete tid t)
342 , dispatchRegister = \v (g,t) -> 345 , dispatchRegister = \v (g,t) ->
343 let (tid,g') = generate g 346 let (tid,g') = generate g
344 t' = insert tid v t 347 t' = insert tid v t
345 in ( tid, (g',t') ) 348 in return ( tid, (g',t') )
346 , dispatchResponse = \tid x (g,t) -> 349 , dispatchResponse = \tid x (g,t) ->
347 case lookup tid t of 350 case lookup tid t of
348 Just v -> let t' = delete tid t 351 Just v -> let t' = delete tid t
349 in ((g,t'),void $ tryPutMVar v x) 352 in return ((g,t'),void $ tryPutMVar v x)
350 Nothing -> ((g,t), return ()) 353 Nothing -> return ((g,t), return ())
351 } 354 }
352 355
353-- | A set of methods neccessary for dispatching incomming packets. 356-- | A set of methods neccessary for dispatching incomming packets.
@@ -402,11 +405,13 @@ printErrors h = ErrorReporter
402 } 405 }
403 406
404-- Change the /err/ type for an 'ErrorReporter'. 407-- Change the /err/ type for an 'ErrorReporter'.
405contramapE f (ErrorReporter pe mh unk tim) 408instance Contravariant (ErrorReporter addr x meth tid) where
406 = ErrorReporter (\e -> pe (f e)) 409 -- contramap :: (t5 -> t4) -> ErrorReporter t3 t2 t1 t t4 -> ErrorReporter t3 t2 t1 t t5
407 mh 410 contramap f (ErrorReporter pe mh unk tim)
408 (\addr x e -> unk addr x (f e)) 411 = ErrorReporter (\e -> pe (f e))
409 tim 412 mh
413 (\addr x e -> unk addr x (f e))
414 tim
410 415
411-- | Handle a single inbound packet and then invoke the given continuation. 416-- | Handle a single inbound packet and then invoke the given continuation.
412-- The 'forkListener' function is implemeneted by passing this function to 417-- The 'forkListener' function is implemeneted by passing this function to
@@ -436,7 +441,7 @@ handleMessage (Client net d err pending whoami responseID) addr plain = do
436 IsResponse tid -> do 441 IsResponse tid -> do
437 action <- atomically $ do 442 action <- atomically $ do
438 ts0 <- readTVar pending 443 ts0 <- readTVar pending
439 let (ts, action) = dispatchResponse (tableMethods d) tid plain ts0 444 (ts, action) <- dispatchResponse (tableMethods d) tid plain ts0
440 writeTVar pending ts 445 writeTVar pending ts
441 return action 446 return action
442 action 447 action
@@ -458,6 +463,7 @@ sockAddrFamily (SockAddrCan _ ) = AF_CAN
458-- | Packets with an empty payload may trigger eof exception. 463-- | Packets with an empty payload may trigger eof exception.
459-- 'udpTransport' uses this function to avoid throwing in that 464-- 'udpTransport' uses this function to avoid throwing in that
460-- case. 465-- case.
466ignoreEOF :: a -> IOError -> IO a
461ignoreEOF def e | isEOFError e = pure def 467ignoreEOF def e | isEOFError e = pure def
462 | otherwise = throwIO e 468 | otherwise = throwIO e
463 469
diff --git a/src/Network/Tox.hs b/src/Network/Tox.hs
index 7893d84a..8df1a09d 100644
--- a/src/Network/Tox.hs
+++ b/src/Network/Tox.hs
@@ -46,6 +46,7 @@ import qualified Data.ByteString.Char8 as C8
46import Data.ByteString.Lazy (toStrict) 46import Data.ByteString.Lazy (toStrict)
47import Data.Char 47import Data.Char
48import Data.Data 48import Data.Data
49import Data.Functor.Contravariant
49import Data.Hashable 50import Data.Hashable
50import Data.IP 51import Data.IP
51import Data.Maybe 52import Data.Maybe
@@ -165,11 +166,11 @@ newClient drg net classify selfAddr handlers modifynet = do
165 tblvar <- 166 tblvar <-
166 if fitsInInt (Proxy :: Proxy Word64) 167 if fitsInInt (Proxy :: Proxy Word64)
167 then do 168 then do
168 let intmapT = transactionMethods (contramapT intKey intMapMethods) gen 169 let intmapT = transactionMethods (contramap intKey intMapMethods) gen
169 intmap_var <- atomically $ newTVar (drg, mempty) 170 intmap_var <- atomically $ newTVar (drg, mempty)
170 return $ Right (intmapT,intmap_var) 171 return $ Right (intmapT,intmap_var)
171 else do 172 else do
172 let mapT = transactionMethods (contramapT nonceKey mapMethods) gen 173 let mapT = transactionMethods (contramap nonceKey mapMethods) gen
173 map_var <- atomically $ newTVar (drg, mempty) 174 map_var <- atomically $ newTVar (drg, mempty)
174 return $ Left (mapT,map_var) 175 return $ Left (mapT,map_var)
175 let dispatch tbl var handlers = DispatchMethods 176 let dispatch tbl var handlers = DispatchMethods