packages feed

quic 0.2.6 → 0.2.7

raw patch · 8 files changed

+80/−11 lines, 8 filesdep ~randomPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

Dependency ranges changed: random

API changes (from Hackage documentation)

- Network.QUIC.Internal: addReader :: Connection -> ThreadId -> IO ()
+ Network.QUIC.Internal: forkManaged :: Connection -> IO () -> IO ()
- Network.QUIC.Internal: Connection :: ConnState -> DebugLogger -> QLogger -> Hooks -> ~Send -> ~Recv -> RecvQ -> IORef Socket -> IORef (IO ()) -> ThreadId -> Rate -> IORef RoleInfo -> IORef VersionInfo -> VersionInfo -> Parameters -> IORef CIDDB -> IORef Parameters -> TVar CIDDB -> IORef PeerInfo -> InputQ -> CryptoQ -> OutputQ -> OutputQLim -> MigrationQ -> Shared -> IORef Int -> IORef (IO ()) -> IORef PacketNumber -> IORef StreamTable -> TVar Concurrency -> TVar Concurrency -> IORef Concurrency -> IORef Concurrency -> TVar TxFlow -> IORef RxFlow -> TVar MigrationState -> IORef Microseconds -> TVar Int -> TVar Int -> TVar Bool -> Array EncryptionLevel (TVar [ReceivedPacket]) -> IOArray EncryptionLevel Cipher -> IOArray EncryptionLevel Coder -> IOArray Bool Coder1RTT -> IOArray EncryptionLevel Protector -> IORef (Bool, PacketNumber) -> IORef Negotiated -> IORef AuthCIDs -> IORef AuthCIDs -> IORef (IO ()) -> Buffer -> SizedBuffer -> Buffer -> LDCC -> Connection
+ Network.QUIC.Internal: Connection :: ConnState -> DebugLogger -> QLogger -> Hooks -> ~Send -> ~Recv -> RecvQ -> IORef Socket -> IORef (Map Word64 (Weak ThreadId)) -> ThreadId -> Rate -> IORef RoleInfo -> IORef VersionInfo -> VersionInfo -> Parameters -> IORef CIDDB -> IORef Parameters -> TVar CIDDB -> IORef PeerInfo -> InputQ -> CryptoQ -> OutputQ -> OutputQLim -> MigrationQ -> Shared -> IORef Int -> IORef (IO ()) -> IORef PacketNumber -> IORef StreamTable -> TVar Concurrency -> TVar Concurrency -> IORef Concurrency -> IORef Concurrency -> TVar TxFlow -> IORef RxFlow -> TVar MigrationState -> IORef Microseconds -> TVar Int -> TVar Int -> TVar Bool -> Array EncryptionLevel (TVar [ReceivedPacket]) -> IOArray EncryptionLevel Cipher -> IOArray EncryptionLevel Coder -> IOArray Bool Coder1RTT -> IOArray EncryptionLevel Protector -> IORef (Bool, PacketNumber) -> IORef Negotiated -> IORef AuthCIDs -> IORef AuthCIDs -> IORef (IO ()) -> Buffer -> SizedBuffer -> Buffer -> LDCC -> Connection
- Network.QUIC.Internal: [readers] :: Connection -> IORef (IO ())
+ Network.QUIC.Internal: [readers] :: Connection -> IORef (Map Word64 (Weak ThreadId))

Files

ChangeLog.md view
@@ -1,5 +1,9 @@ # ChangeLog +## 0.2.7++* Introducing `forkManaged` to manage readers of clients properly.+ ## 0.2.6  * Using `ServerState` instead of `killThread`.
Network/QUIC/Client/Reader.hs view
@@ -15,6 +15,7 @@ import Network.Socket (Socket, close, getSocketName) import qualified Network.Socket.ByteString as NSB +import Network.QUIC.Common import Network.QUIC.Connection import Network.QUIC.Connector import Network.QUIC.Crypto@@ -30,6 +31,7 @@ -- | readerClient dies when the socket is closed. readerClient :: Socket -> Connection -> IO () readerClient s0 conn = handleLogUnit logAction $ do+    labelMe "readerClient"     wait     loop   where@@ -146,5 +148,5 @@     newSock <- natRebinding peersa     oldSock <- setSocket conn newSock     let reader = readerClient newSock conn-    forkIO reader >>= addReader conn+    forkManaged conn reader     fire conn microseconds $ close oldSock
Network/QUIC/Client/Run.hs view
@@ -7,7 +7,6 @@     migrate, ) where -import Control.Concurrent import Control.Concurrent.Async import qualified Control.Exception as E import qualified Network.Socket as NS@@ -58,7 +57,7 @@ runClient :: ClientConfig -> (Connection -> IO a) -> Bool -> VersionInfo -> IO a runClient conf client0 isICVN verInfo = do     E.bracket open clse $ \(ConnRes conn myAuthCIDs reader) -> do-        forkIO reader >>= addReader conn+        forkManaged conn reader         let conf' =                 conf                     { ccParameters =
Network/QUIC/Connection/Misc.hs view
@@ -21,7 +21,7 @@     delayedAck,     resetDealyedAck,     setMaxPacketSize,-    addReader,+    forkManaged,     killReaders,     addResource,     freeResources,@@ -35,6 +35,7 @@  import Control.Concurrent import qualified Control.Exception as E+import qualified Data.Map.Strict as Map import Network.Socket (Socket) import System.Mem.Weak @@ -161,12 +162,32 @@ addReader :: Connection -> ThreadId -> IO () addReader Connection{..} tid = do     wtid <- mkWeakThreadId tid-    atomicModifyIORef'' readers $ \m -> do-        m-        deRefWeak wtid >>= mapM_ killThread+    let n = fromThreadId tid+    atomicModifyIORef'' readers $ Map.insert n wtid +delReader :: Connection -> ThreadId -> IO ()+delReader Connection{..} tid = do+    let n = fromThreadId tid+    atomicModifyIORef'' readers $ Map.delete n++forkManaged :: Connection -> IO () -> IO ()+forkManaged conn action = void $ forkIO $ do+    E.bracket setup clean $ \_ -> action+  where+    setup = do+        tid <- myThreadId+        addReader conn tid+        return tid+    clean = delReader conn+ killReaders :: Connection -> IO ()-killReaders Connection{..} = join $ readIORef readers+killReaders Connection{..} = do+    wtids <- readIORef readers+    forM_ wtids $ \wtid -> do+        mtid <- deRefWeak wtid+        case mtid of+            Nothing -> return ()+            Just tid -> killThread tid  ---------------------------------------------------------------- 
Network/QUIC/Connection/Types.hs view
@@ -20,6 +20,7 @@ import Network.Control (Rate, RxFlow, TxFlow, newRate, newRxFlow, newTxFlow) import Network.Socket (Cmsg, SockAddr, Socket) import Network.TLS.QUIC+import System.Mem.Weak (Weak)  import Network.QUIC.Config import Network.QUIC.Connector@@ -202,7 +203,7 @@     -- Manage     , connRecvQ :: RecvQ     , connSocket :: IORef Socket-    , readers :: IORef (IO ())+    , readers :: IORef (Map Word64 (Weak ThreadId))     , mainThreadId :: ThreadId     , controlRate :: Rate     , -- Info@@ -306,7 +307,7 @@     ecrptBuf <- mallocBytes bufsiz     dcrptBuf <- mallocBytes bufsiz     Connection connstate debugLog qLog hooks send recv recvQ sref-        <$> newIORef (return ())+        <$> newIORef Map.empty         <*> myThreadId         <*> newRate         -- Info
Network/QUIC/Imports.hs view
@@ -25,6 +25,7 @@ #endif     atomicModifyIORef'',     copyBS,+    fromThreadId, ) where  import Control.Applicative@@ -49,6 +50,12 @@ import Network.QUIC.Utils import Numeric +#if __GLASGOW_HASKELL__ >= 908+import GHC.Conc.Sync (fromThreadId)+#else+import Control.Concurrent (ThreadId)+#endif+ -- | All internal byte sequences. --   `ByteString` should be used for FFI related stuff. type Bytes = ShortByteString@@ -71,3 +78,8 @@     let src = src0 `plusPtr` off     copyBytes dst src len     return len++#if __GLASGOW_HASKELL__ < 908+fromThreadId :: ThreadId -> Word64+fromThreadId tid = read (drop 9 $ show tid)+#endif
quic.cabal view
@@ -1,6 +1,6 @@ cabal-version:      >=1.10 name:               quic-version:            0.2.6+version:            0.2.7 license:            BSD3 license-file:       LICENSE maintainer:         kazu@iij.ad.jp
test/IOSpec.hs view
@@ -89,6 +89,9 @@     describe "concurrency" $ do         it "can handle multiple clients" $ do             withPipe (Randomly 20) $ testMultiSendRecv cc sc waitS 500+    describe "abortConnection" $ do+        it "can abort connection" $ do+            withPipe (Randomly 20) $ testAbort cc sc waitS  consumeBytes :: Stream -> Int -> IO () consumeBytes _ 0 = return ()@@ -200,4 +203,31 @@                 consumeBytes strm (chunklen * times)                 assertEndOfStream strm                 putMVar (mvars !! n) ()+            loop conn++appErr :: QUICException -> Bool+appErr (ApplicationProtocolErrorIsReceived _ _) = True+appErr _ = False++testAbort :: C.ClientConfig -> ServerConfig -> IO () -> IO ()+testAbort cc sc waitS = do+    E.bracket (forkIO server) killThread $ \_ ->+        client `shouldThrow` appErr+  where+    client = do+        waitS+        C.run cc $ \conn -> do+            strm <- stream conn+            sendStream strm "foo"+            void $ recvStream strm 10+    server = run sc loop+      where+        loop conn = do+            _strm <- acceptStream conn+            void $+                forkIO $+                    abortConnection+                        conn+                        (ApplicationProtocolError 1)+                        "testing abortConnection"             loop conn