@@ -77,18 +77,6 @@ run p = runSettings defaultSettings { settingsPort = p }
7777
7878-- | Run an 'Application' with the given 'Settings'.
7979runSettings :: Settings -> Application -> IO ()
80−#if WINDOWS
81−runSettings set app = withSocketsDo $ do
82− var <- MV.newMVar Nothing
83− let clean = MV.modifyMVar_ var $ \s -> maybe (return ()) sClose s >> return Nothing
84− void . forkIO $ bracket
85− (bindPortTCP (settingsPort set) (settingsHost set))
86− (const clean)
87− (\s -> do
88− MV.modifyMVar_ var (\_ -> return $ Just s)
89− runSettingsSocket set s app)
90− forever (threadDelay maxBound) `finally` clean
91−#else
9280runSettings set app =
9381 bracket
9482 (bindPortTCP (settingsPort set) (settingsHost set))
@@ -96,6 +84,17 @@ runSettings set app =
9684 (\socket -> do
9785 setSocketCloseOnExec socket
9886 runSettingsSocket set socket app)
87+
88+#if WINDOWS
89+windowsThreadBlockHack :: IO a -> IO a
90+windowsThreadBlockHack act =
91+ do
92+ var <- MV.newEmptyMVar :: IO (MV.MVar (Either SomeException a))
93+ void . forkIO $ E.try act >>= MV.putMVar var
94+ res <- MV.takeMVar var
95+ case res of
96+ Left e -> throwIO e
97+ Right r -> return r
9998#endif
10099
101100-- | Same as 'runSettings', but uses a user-supplied socket instead of opening
@@ -109,7 +108,11 @@ runSettingsSocket set socket app =
109108 runSettingsConnection set getConn app
110109 where
111110 getConn = do
111+#if WINDOWS
112+ (s, sa) <- windowsThreadBlockHack $ accept socket
113+#else
112114 (s, sa) <- accept socket
115+#endif
113116 setSocketCloseOnExec s
114117 conn <- socketConnection s
115118 return (conn, sa)