@@ -123,26 +123,10 @@ runSettingsConnectionMakerSecure :: Settings -> IO (IO (Connection, Bool), SockA
123runSettingsConnectionMakerSecure set getConnMaker app = do
123runSettingsConnectionMakerSecure set getConnMaker app = do
124 settingsBeforeMainLoop set
124 settingsBeforeMainLoop set
126− -- Note that there is a thorough discussion of the exception safety of the
127− -- following code at: https://github.com/yesodweb/wai/issues/146
129− -- We need to make sure of two things:
131− -- 1. Asynchronous exceptions are not blocked entirely in the main loop.
132− -- Doing so would make it impossible to kill the Warp thread.
134− -- 2. Once a connection maker is received via getConnLoop, the connection
135− -- is guaranteed to be closed, even in the presence of async exceptions.
137− -- Our approach is explained in the comments below.
139− -- First mask all exceptions in the main loop. This is necessary to ensure
140− -- that no async exception is throw between the call to getConnLoop and the
141− -- registering of connClose.
142 D.withDateCache $ \dc ->
126 D.withDateCache $ \dc ->
143 F.withFdCache fdCacheDurationInSeconds $ \fc ->
127 F.withFdCache fdCacheDurationInSeconds $ \fc ->
144 withTimeoutManager $ \tm ->
128 withTimeoutManager $ \tm ->
145− mask_ $ acceptConnection set getConnMaker app dc fc tm
129+ acceptConnection set getConnMaker app dc fc tm
147 fdCacheDurationInSeconds = settingsFdCacheDuration set * 1000000
131 fdCacheDurationInSeconds = settingsFdCacheDuration set * 1000000
148 withTimeoutManager f =
132 withTimeoutManager f =
@@ -153,6 +137,18 @@ runSettingsConnectionMakerSecure set getConnMaker app = do
154 Just tm -> f tm
138 Just tm -> f tm
140+-- Note that there is a thorough discussion of the exception safety of the
141+-- following code at: https://github.com/yesodweb/wai/issues/146
143+-- We need to make sure of two things:
145+-- 1. Asynchronous exceptions are not blocked entirely in the main loop.
146+-- Doing so would make it impossible to kill the Warp thread.
148+-- 2. Once a connection maker is received via getConnLoop, the connection
149+-- is guaranteed to be closed, even in the presence of async exceptions.
151+-- Our approach is explained in the comments below.
156acceptConnection :: Settings
152acceptConnection :: Settings
157 -> IO (IO (Connection, Bool), SockAddr)
153 -> IO (IO (Connection, Bool), SockAddr)
158 -> Application
154 -> Application
@@ -160,7 +156,10 @@ acceptConnection :: Settings
160 -> Maybe F.MutableFdCache
156 -> Maybe F.MutableFdCache
161 -> T.Manager
157 -> T.Manager
159+-- First mask all exceptions in the main loop. This is necessary to ensure
160+-- that no async exception is throw between the call to getConnLoop and the
161+-- registering of connClose.
163−acceptConnection set getConnMaker app dc fc tm = do
162+acceptConnection set getConnMaker app dc fc tm = mask_ $ do
164 -- Allow async exceptions before receiving the next connection maker.
163 -- Allow async exceptions before receiving the next connection maker.
165 allowInterrupt
164 allowInterrupt