|
1 | 1 | {-# LANGUAGE CPP #-}
|
| 2 | +{-# LANGUAGE ScopedTypeVariables #-} |
2 | 3 |
|
3 | 4 | #include "HsNetDef.h"
|
4 | 5 |
|
@@ -59,7 +60,8 @@ gracefulClose s tmout0 = sendRecvFIN `E.finally` close s
|
59 | 60 | -- Sending TCP FIN.
|
60 | 61 | ex <- E.try $ shutdown s ShutdownSend
|
61 | 62 | case ex of
|
62 |
| - Left (E.SomeException _) -> return () |
| 63 | + -- Don't catch asynchronous exceptions |
| 64 | + Left (_ :: E.IOException) -> return () |
63 | 65 | Right () -> do
|
64 | 66 | -- Giving CPU time to other threads hoping that
|
65 | 67 | -- FIN arrives meanwhile.
|
@@ -93,29 +95,26 @@ recvEOFevent :: Socket -> Int -> Ptr Word8 -> IO ()
|
93 | 95 | recvEOFevent s tmout0 buf = do
|
94 | 96 | tmmgr <- Ev.getSystemTimerManager
|
95 | 97 | 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 |
106 | 112 | 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 |
121 | 120 | #endif
|
0 commit comments