Skip to content

Commit a2e111e

Browse files
Merge pull request #580 from kazu-yamamoto/gracefully-graceful-shutdown
making gracefulClose more graceful
2 parents e8310db + 107486a commit a2e111e

File tree

1 file changed

+10
-10
lines changed

1 file changed

+10
-10
lines changed

Network/Socket/Shutdown.hs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ module Network.Socket.Shutdown (
1111
import qualified Control.Exception as E
1212
import Foreign.Marshal.Alloc (mallocBytes, free)
1313

14-
import Control.Concurrent (threadDelay)
14+
import Control.Concurrent (threadDelay, yield)
1515

1616
import Network.Socket.Buffer
1717
import Network.Socket.Imports
@@ -47,31 +47,31 @@ 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.
5454
ex <- E.try $ shutdown s ShutdownSend
5555
case ex of
5656
Left (E.SomeException _) -> return ()
5757
Right () -> do
58+
-- Giving CPU time to other threads hoping that
59+
-- FIN arrives meanwhile.
60+
yield
5861
-- Waiting TCP FIN.
5962
E.bracket (mallocBytes bufSize) free recvEOFloop
60-
-- milliseconds. Taken from BSD fast clock value.
61-
clock = 200
62-
recvEOFloop buf = loop 0
63+
recvEOFloop buf = loop 1 0
6364
where
64-
loop delay = do
65+
loop delay tmout = do
6566
-- We don't check the (positive) length.
6667
-- In normal case, it's 0. That is, only FIN is received.
6768
-- In error cases, data is available. But there is no
6869
-- application which can read it. So, let's stop receiving
6970
-- to prevent attacks.
7071
r <- recvBufNoWait s buf bufSize
71-
let delay' = delay + clock
72-
when (r == -1 && delay' < tmout) $ do
73-
threadDelay (clock * 1000)
74-
loop delay'
72+
when (r == -1 && tmout < tmout0) $ do
73+
threadDelay (delay * 1000)
74+
loop (delay * 2) (tmout + delay)
7575
-- Don't use 4092 here. The GHC runtime takes the global lock
7676
-- if the length is over 3276 bytes in 32bit or 3272 bytes in 64bit.
7777
bufSize = 1024

0 commit comments

Comments
 (0)