Skip to content

Commit f3da242

Browse files
committed
Using tryPutMVar in gracefulClose. (#438)
1 parent 7e98a6c commit f3da242

File tree

1 file changed

+23
-26
lines changed

1 file changed

+23
-26
lines changed

Network/Socket/Shutdown.hs

Lines changed: 23 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import Foreign.Marshal.Alloc (mallocBytes, free)
1313

1414
import Control.Concurrent (threadDelay)
1515
#if !defined(mingw32_HOST_OS)
16-
import Control.Concurrent (putMVar, takeMVar, newEmptyMVar)
16+
import Control.Concurrent (tryPutMVar, takeMVar, newEmptyMVar)
1717
import qualified GHC.Event as Ev
1818
import System.Posix.Types (Fd(..))
1919
#endif
@@ -62,19 +62,20 @@ gracefulClose s tmout = sendRecvFIN `E.finally` close s
6262
-- Sending TCP FIN.
6363
shutdown s ShutdownSend
6464
-- Waiting TCP FIN.
65+
E.bracket (mallocBytes bufSize) free $ \buf -> do
6566
#if defined(mingw32_HOST_OS)
66-
recvEOFloop
67+
{-# SCC "" #-} recvEOFloop buf
6768
#else
68-
mevmgr <- Ev.getSystemEventManager
69-
case mevmgr of
70-
Nothing -> recvEOFloop -- non-threaded RTS
71-
Just evmgr -> recvEOFev evmgr
69+
mevmgr <- Ev.getSystemEventManager
70+
case mevmgr of
71+
Nothing -> recvEOFloop buf -- non-threaded RTS
72+
Just evmgr -> recvEOFev evmgr buf
7273
#endif
7374
-- milliseconds. Taken from BSD fast clock value.
7475
clock = 200
75-
recvEOFloop = E.bracket (mallocBytes bufSize) free $ loop 0
76+
recvEOFloop buf = loop 0
7677
where
77-
loop delay buf = do
78+
loop delay = do
7879
-- We don't check the (positive) length.
7980
-- In normal case, it's 0. That is, only FIN is received.
8081
-- In error cases, data is available. But there is no
@@ -84,29 +85,25 @@ gracefulClose s tmout = sendRecvFIN `E.finally` close s
8485
let delay' = delay + clock
8586
when (r == -1 && delay' < tmout) $ do
8687
threadDelay (clock * 1000)
87-
loop delay' buf
88+
loop delay'
8889
#if !defined(mingw32_HOST_OS)
89-
recvEOFev evmgr = do
90-
tmmgr <- Ev.getSystemTimerManager
91-
mvar <- newEmptyMVar
92-
E.bracket (register evmgr tmmgr mvar) (unregister evmgr tmmgr) $ \_ -> do
93-
wait <- takeMVar mvar
94-
case wait of
95-
TimeoutTripped -> return ()
96-
-- We don't check the (positive) length.
97-
-- In normal case, it's 0. That is, only FIN is received.
98-
-- In error cases, data is available. But there is no
99-
-- application which can read it. So, let's stop receiving
100-
-- to prevent attacks.
101-
MoreData -> E.bracket (mallocBytes bufSize)
102-
free
103-
(\buf -> void $ recvBufNoWait s buf bufSize)
90+
recvEOFev evmgr buf = do
91+
-- Checking if FIN is already received.
92+
r <- recvBufNoWait s buf bufSize
93+
when (r == -1) $ do
94+
tmmgr <- Ev.getSystemTimerManager
95+
mvar <- newEmptyMVar
96+
E.bracket (register evmgr tmmgr mvar) (unregister evmgr tmmgr) $ \_ -> do
97+
wait <- takeMVar mvar
98+
case wait of
99+
TimeoutTripped -> return ()
100+
MoreData -> void $ recvBufNoWait s buf bufSize
104101
register evmgr tmmgr mvar = do
105102
-- millisecond to microsecond
106103
key1 <- Ev.registerTimeout tmmgr (tmout * 1000) $
107-
putMVar mvar TimeoutTripped
104+
void $ tryPutMVar mvar TimeoutTripped
108105
key2 <- withFdSocket s $ \fd' -> do
109-
let callback _ _ = putMVar mvar MoreData
106+
let callback _ _ = void $ tryPutMVar mvar MoreData
110107
fd = Fd fd'
111108
#if __GLASGOW_HASKELL__ < 709
112109
Ev.registerFd evmgr callback fd Ev.evtRead

0 commit comments

Comments
 (0)