@@ -13,7 +13,7 @@ import Foreign.Marshal.Alloc (mallocBytes, free)
13
13
14
14
import Control.Concurrent (threadDelay )
15
15
#if !defined(mingw32_HOST_OS)
16
- import Control.Concurrent (putMVar , takeMVar , newEmptyMVar )
16
+ import Control.Concurrent (tryPutMVar , takeMVar , newEmptyMVar )
17
17
import qualified GHC.Event as Ev
18
18
import System.Posix.Types (Fd (.. ))
19
19
#endif
@@ -62,19 +62,20 @@ gracefulClose s tmout = sendRecvFIN `E.finally` close s
62
62
-- Sending TCP FIN.
63
63
shutdown s ShutdownSend
64
64
-- Waiting TCP FIN.
65
+ E. bracket (mallocBytes bufSize) free $ \ buf -> do
65
66
#if defined(mingw32_HOST_OS)
66
- recvEOFloop
67
+ {-# SCC "" #-} recvEOFloop buf
67
68
#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
72
73
#endif
73
74
-- milliseconds. Taken from BSD fast clock value.
74
75
clock = 200
75
- recvEOFloop = E. bracket (mallocBytes bufSize) free $ loop 0
76
+ recvEOFloop buf = loop 0
76
77
where
77
- loop delay buf = do
78
+ loop delay = do
78
79
-- We don't check the (positive) length.
79
80
-- In normal case, it's 0. That is, only FIN is received.
80
81
-- In error cases, data is available. But there is no
@@ -84,29 +85,25 @@ gracefulClose s tmout = sendRecvFIN `E.finally` close s
84
85
let delay' = delay + clock
85
86
when (r == - 1 && delay' < tmout) $ do
86
87
threadDelay (clock * 1000 )
87
- loop delay' buf
88
+ loop delay'
88
89
#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
104
101
register evmgr tmmgr mvar = do
105
102
-- millisecond to microsecond
106
103
key1 <- Ev. registerTimeout tmmgr (tmout * 1000 ) $
107
- putMVar mvar TimeoutTripped
104
+ void $ tryPutMVar mvar TimeoutTripped
108
105
key2 <- withFdSocket s $ \ fd' -> do
109
- let callback _ _ = putMVar mvar MoreData
106
+ let callback _ _ = void $ tryPutMVar mvar MoreData
110
107
fd = Fd fd'
111
108
#if __GLASGOW_HASKELL__ < 709
112
109
Ev. registerFd evmgr callback fd Ev. evtRead
0 commit comments