on master help sign in
making timeout manager connection-local.
commitc70e45dc3ce7bbec36dbf2802a638d26b32e193f authorKazu Yamamoto <kazu@iij.ad.jp> dateWed 16 Dec 2015, 14:16 (11 years ago) parent35870c8
3 files changed+42−51
warp/Network/Wai/Handler/Warp/HTTP2.hs+3−4 warp/Network/Wai/Handler/Warp/HTTP2/Manager.hs+31−31 warp/Network/Wai/Handler/Warp/HTTP2/Worker.hs+8−16
warp/Network/Wai/Handler/Warp/HTTP2.hs+3−4
@@ -28,10 +28,10 @@ http2 conn ii addr transport settings readN app = do
2828 ok <- checkPreface
2929 when ok $ do
3030 ctx <- newContext
31− -- Workers & Manager
32− mgr <- start
31+ -- Workers, worker manager and timer manager
32+ mgr <- start settings
3333 let responder = response ii settings ctx mgr
34− action = worker ctx settings tm app responder
34+ action = worker ctx settings app responder
3535 setAction mgr action
3636 -- fixme: hard coding: 10
3737 replicateM_ 10 $ spawnAction mgr
@@ -46,7 +46,6 @@ http2 conn ii addr transport settings readN app = do
4646 stop mgr
4747 killThread tid
4848 where
49− tm = timeoutManager ii
5049 checkTLS = case transport of
5150 TCP -> return () -- direct
5251 tls -> unless (tls12orLater tls) $ goaway conn InadequateSecurity "Weak TLS"
warp/Network/Wai/Handler/Warp/HTTP2/Manager.hs+31−31
@@ -1,4 +1,4 @@
1−{-# LANGUAGE CPP #-}
1+{-# LANGUAGE CPP, BangPatterns #-}
22
33-- | A thread pool manager.
44-- The manager has responsibility to spawn and kill
@@ -20,42 +20,45 @@ import Control.Concurrent.STM
2020import Control.Monad (void)
2121import Data.Set (Set)
2222import qualified Data.Set as Set
23+import Data.Foldable
2324import Network.Wai.Handler.Warp.IORef
25+import Network.Wai.Handler.Warp.Settings
26+import qualified Network.Wai.Handler.Warp.Timeout as T
2427
2528----------------------------------------------------------------
2629
30+type Action = T.Manager -> IO ()
31+
2732data Command = Stop | Spawn | Replace ThreadId
2833
29−data Manager = Manager (TQueue Command) (IORef (IO ()))
34+data Manager = Manager (TQueue Command) (IORef Action)
3035
3136-- | Starting a thread pool manager.
3237-- Its action is initially set to 'return ()' and should be set
3338-- by 'setAction'. This allows that the action can include
3439-- the manager itself.
35−start :: IO Manager
36−start = do
37− tset <- newThreadSet
40+start :: Settings -> IO Manager
41+start set = do
3842 q <- newTQueueIO
39− ref <- newIORef (return ())
40− void $ forkIO $ go q tset ref
43+ ref <- newIORef (\_ -> return ())
44+ timmgr <- T.initialize $ settingsTimeout set * 1000000
45+ void $ forkIO $ go q Set.empty ref timmgr
4146 return $ Manager q ref
4247 where
43− go q tset ref = do
48+ go q !tset0 ref timmgr = do
4449 x <- atomically $ readTQueue q
4550 case x of
46− Stop -> kill tset
47− Spawn -> next
48− Replace oldtid -> do
49− del tset oldtid
50− next
51+ Stop -> kill tset0 >> T.killManager timmgr
52+ Spawn -> next tset0
53+ Replace oldtid -> next $ del oldtid tset0
5154 where
52− next = do
55+ next tset = do
5356 action <- readIORef ref
54− newtid <- forkIO action
55− add tset newtid
56− go q tset ref
57+ newtid <- forkIO (action timmgr)
58+ let !tset' = add newtid tset
59+ go q tset' ref timmgr
5760
58−setAction :: Manager -> IO () -> IO ()
61+setAction :: Manager -> Action -> IO ()
5962setAction (Manager _ ref) action = writeIORef ref action
6063
6164stop :: Manager -> IO ()
@@ -69,18 +72,15 @@ replaceWithAction (Manager q _) tid = atomically $ writeTQueue q $ Replace tid
6972
7073----------------------------------------------------------------
7174
72−newtype ThreadSet = ThreadSet (IORef (Set ThreadId))
73−
74−newThreadSet :: IO ThreadSet
75−newThreadSet = ThreadSet <$> newIORef Set.empty
76−
77−add :: ThreadSet -> ThreadId -> IO ()
78−add (ThreadSet ref) tid =
79− atomicModifyIORef' ref (\set -> (Set.insert tid set, ()))
75+add :: ThreadId -> Set ThreadId -> Set ThreadId
76+add tid set = set'
77+ where
78+ !set' = Set.insert tid set
8079
81−del :: ThreadSet -> ThreadId -> IO ()
82−del (ThreadSet ref) tid =
83− atomicModifyIORef' ref (\set -> (Set.delete tid set, ()))
80+del :: ThreadId -> Set ThreadId -> Set ThreadId
81+del tid set = set'
82+ where
83+ !set' = Set.delete tid set
8484
85−kill :: ThreadSet -> IO ()
86−kill (ThreadSet ref) = Set.toList <$> readIORef ref >>= mapM_ killThread
85+kill :: Set ThreadId -> IO ()
86+kill set = traverse_ killThread set
warp/Network/Wai/Handler/Warp/HTTP2/Worker.hs+8−16
@@ -133,17 +133,11 @@ response ii settings Context{outputQ} mgr tconf th strm req rsp
133133 atomically $ writeTBQueue sq SFinish
134134 return ResponseReceived
135135
136−data Break = Break deriving (Show, Typeable)
137−
138−instance Exception Break
139−
140−worker :: Context -> S.Settings -> T.Manager -> Application -> Responder -> IO ()
141−worker ctx@Context{inputQ,outputQ} set tm app responder = do
142− tid <- myThreadId
136+worker :: Context -> S.Settings -> Application -> Responder -> T.Manager -> IO ()
137+worker ctx@Context{inputQ,outputQ} set app responder tm = do
143138 sinfo <- newStreamInfo
144139 tcont <- newThreadContinue
145− let setup = T.register tm $ E.throwTo tid Break
146− E.bracket setup T.cancel $ go sinfo tcont
140+ E.bracket (T.registerKillThread tm) T.cancel $ go sinfo tcont
147141 where
148142 go sinfo tcont th = do
149143 setThreadContinue tcont True
@@ -157,17 +151,16 @@ worker ctx@Context{inputQ,outputQ} set tm app responder = do
157151 cont1 <- case ex of
158152 Right ResponseReceived -> return True
159153 Left e@(SomeException _)
160− | Just Break <- E.fromException e -> do
154+ -- killed by the worker manager
155+ | Just ThreadKilled <- E.fromException e -> return False
156+ | Just T.TimeoutThread <- E.fromException e -> do
161157 cleanup sinfo Nothing
162158 return True
163− -- killed by the sender
164− | Just ThreadKilled <- E.fromException e -> do
165− cleanup sinfo Nothing
166− return False
167159 | otherwise -> do
168− cleanup sinfo (Just e)
160+ cleanup sinfo $ Just e
169161 return True
170162 cont2 <- getThreadContinue tcont
163+ clearStreamInfo sinfo
171164 when (cont1 && cont2) $ go sinfo tcont th
172165 cleanup sinfo me = do
173166 m <- getStreamInfo sinfo
@@ -180,7 +173,6 @@ worker ctx@Context{inputQ,outputQ} set tm app responder = do
180173 case me of
181174 Nothing -> return ()
182175 Just e -> S.settingsOnException set (Just req) e
183− clearStreamInfo sinfo
184176
185177waiter :: TVar Sync -> TBQueue Sequence -> PriorityTree Output -> IO ()
186178waiter tvar sq outQ = do