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 +4/−0
- Network/QUIC/Client/Reader.hs +3/−1
- Network/QUIC/Client/Run.hs +1/−2
- Network/QUIC/Connection/Misc.hs +26/−5
- Network/QUIC/Connection/Types.hs +3/−2
- Network/QUIC/Imports.hs +12/−0
- quic.cabal +1/−1
- test/IOSpec.hs +30/−0
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