Skip to content

Commit 670e4eb

Browse files
committed
Merge branch 'nested-bracket' (see #590)
2 parents 1fd5bf7 + 78704fc commit 670e4eb

File tree

1 file changed

+24
-25
lines changed

1 file changed

+24
-25
lines changed

Network/Socket/Shutdown.hs

Lines changed: 24 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
{-# LANGUAGE CPP #-}
2+
{-# LANGUAGE ScopedTypeVariables #-}
23

34
#include "HsNetDef.h"
45

@@ -59,7 +60,8 @@ gracefulClose s tmout0 = sendRecvFIN `E.finally` close s
5960
-- Sending TCP FIN.
6061
ex <- E.try $ shutdown s ShutdownSend
6162
case ex of
62-
Left (E.SomeException _) -> return ()
63+
-- Don't catch asynchronous exceptions
64+
Left (_ :: E.IOException) -> return ()
6365
Right () -> do
6466
-- Giving CPU time to other threads hoping that
6567
-- FIN arrives meanwhile.
@@ -93,29 +95,26 @@ recvEOFevent :: Socket -> Int -> Ptr Word8 -> IO ()
9395
recvEOFevent s tmout0 buf = do
9496
tmmgr <- Ev.getSystemTimerManager
9597
tvar <- newTVarIO False
96-
E.bracket (setup tmmgr tvar) teardown $ \(wait, _) -> do
97-
waitRes <- wait
98-
case waitRes of
99-
TimeoutTripped -> return ()
100-
-- We don't check the (positive) length.
101-
-- In normal case, it's 0. That is, only FIN is received.
102-
-- In error cases, data is available. But there is no
103-
-- application which can read it. So, let's stop receiving
104-
-- to prevent attacks.
105-
MoreData -> void $ recvBufNoWait s buf bufSize
98+
E.bracket (setupTimeout tmmgr tvar) (cancelTimeout tmmgr) $ \_ -> do
99+
E.bracket (setupRead s) cancelRead $ \(rxWait,_) -> do
100+
let toWait = readTVar tvar >>= check
101+
wait = atomically ((toWait >> return TimeoutTripped)
102+
<|> (rxWait >> return MoreData))
103+
waitRes <- wait
104+
case waitRes of
105+
TimeoutTripped -> return ()
106+
-- We don't check the (positive) length.
107+
-- In normal case, it's 0. That is, only FIN is received.
108+
-- In error cases, data is available. But there is no
109+
-- application which can read it. So, let's stop receiving
110+
-- to prevent attacks.
111+
MoreData -> void $ recvBufNoWait s buf bufSize
106112
where
107-
setup tmmgr tvar = do
108-
-- millisecond to microsecond
109-
key <- Ev.registerTimeout tmmgr (tmout0 * 1000) $
110-
atomically $ writeTVar tvar True
111-
(evWait, evCancel) <- waitAndCancelReadSocketSTM s
112-
let toWait = do
113-
tmout <- readTVar tvar
114-
check tmout
115-
toCancel = Ev.unregisterTimeout tmmgr key
116-
wait = atomically ((toWait >> return TimeoutTripped)
117-
<|> (evWait >> return MoreData))
118-
cancel = evCancel >> toCancel
119-
return (wait, cancel)
120-
teardown (_, cancel) = cancel
113+
-- millisecond to microsecond
114+
tmout = tmout0 * 1000
115+
setupTimeout tmmgr tvar =
116+
Ev.registerTimeout tmmgr tmout $ atomically $ writeTVar tvar True
117+
cancelTimeout = Ev.unregisterTimeout
118+
setupRead = waitAndCancelReadSocketSTM
119+
cancelRead (_,cancel) = cancel
121120
#endif

0 commit comments

Comments
 (0)