Skip to content

Commit 29f4e61

Browse files
committed
making gracefulClose more graceful
200ms is too long. So, wait for 1ms first, then 2ms, 4ms, 8ms, etc.
1 parent e8310db commit 29f4e61

File tree

1 file changed

+6
-9
lines changed

1 file changed

+6
-9
lines changed

Network/Socket/Shutdown.hs

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ foreign import CALLCONV unsafe "shutdown"
4747
--
4848
-- Since: 3.1.1.0
4949
gracefulClose :: Socket -> Int -> IO ()
50-
gracefulClose s tmout = sendRecvFIN `E.finally` close s
50+
gracefulClose s tmout0 = sendRecvFIN `E.finally` close s
5151
where
5252
sendRecvFIN = do
5353
-- Sending TCP FIN.
@@ -57,21 +57,18 @@ gracefulClose s tmout = sendRecvFIN `E.finally` close s
5757
Right () -> do
5858
-- Waiting TCP FIN.
5959
E.bracket (mallocBytes bufSize) free recvEOFloop
60-
-- milliseconds. Taken from BSD fast clock value.
61-
clock = 200
62-
recvEOFloop buf = loop 0
60+
recvEOFloop buf = loop 1 0
6361
where
64-
loop delay = do
62+
loop delay tmout = do
6563
-- We don't check the (positive) length.
6664
-- In normal case, it's 0. That is, only FIN is received.
6765
-- In error cases, data is available. But there is no
6866
-- application which can read it. So, let's stop receiving
6967
-- to prevent attacks.
7068
r <- recvBufNoWait s buf bufSize
71-
let delay' = delay + clock
72-
when (r == -1 && delay' < tmout) $ do
73-
threadDelay (clock * 1000)
74-
loop delay'
69+
when (r == -1 && tmout < tmout0) $ do
70+
threadDelay (delay * 1000)
71+
loop (delay * 2) (tmout + delay)
7572
-- Don't use 4092 here. The GHC runtime takes the global lock
7673
-- if the length is over 3276 bytes in 32bit or 3272 bytes in 64bit.
7774
bufSize = 1024

0 commit comments

Comments
 (0)