-
Notifications
You must be signed in to change notification settings - Fork 190
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
CLOSE_WAIT #590
Comments
One possibility is that we should not acquire two resources in one recvEOFevent :: Socket -> Int -> Ptr Word8 -> IO ()
recvEOFevent s tmout0 buf = do
tmmgr <- Ev.getSystemTimerManager
tvar <- newTVarIO False
E.bracket (setup tmmgr tvar) teardown $ \(wait, _) -> do
waitRes <- wait
case waitRes of
TimeoutTripped -> return ()
-- We don't check the (positive) length.
-- In normal case, it's 0. That is, only FIN is received.
-- In error cases, data is available. But there is no
-- application which can read it. So, let's stop receiving
-- to prevent attacks.
MoreData -> void $ recvBufNoWait s buf bufSize
where
setup tmmgr tvar = do
-- millisecond to microsecond
key <- Ev.registerTimeout tmmgr (tmout0 * 1000) $
atomically $ writeTVar tvar True
(evWait, evCancel) <- waitAndCancelReadSocketSTM s
let toWait = do
tmout <- readTVar tvar
check tmout
toCancel = Ev.unregisterTimeout tmmgr key
wait = atomically ((toWait >> return TimeoutTripped)
<|> (evWait >> return MoreData))
cancel = evCancel >> toCancel
return (wait, cancel)
teardown (_, cancel) = cancel Nested recvEOFevent :: Socket -> Int -> Ptr Word8 -> IO ()
recvEOFevent s tmout0 buf = do
tmmgr <- Ev.getSystemTimerManager
tvar <- newTVarIO False
E.bracket (setupTimeout tmmgr tvar) (cancelTimeout tmmgr) $ \_ -> do
E.bracket setupRead cancelRead $ \(evWait,_) -> do
let toWait = do
tmout <- readTVar tvar
check tmout
wait = atomically ((toWait >> return TimeoutTripped)
<|> (evWait >> return MoreData))
waitRes <- wait
case waitRes of
TimeoutTripped -> return ()
-- We don't check the (positive) length.
-- In normal case, it's 0. That is, only FIN is received.
-- In error cases, data is available. But there is no
-- application which can read it. So, let's stop receiving
-- to prevent attacks.
MoreData -> void $ recvBufNoWait s buf bufSize
where
-- millisecond to microsecond
setupTimeout tmmgr tvar =
Ev.registerTimeout tmmgr (tmout0 * 1000) $
atomically $ writeTVar tvar True
cancelTimeout = Ev.unregisterTimeout
setupRead = waitAndCancelReadSocketSTM s
cancelRead (_,cancel) = cancel |
Page 162 of Parallel and Concurrent Programming in Haskell says:
|
@kazu-yamamoto Does it say that somewhere in the docs as well? If not, it really should, because book-driven documentation is very bad. |
@kazu-yamamoto I think it would also be good if we can create a test for this |
I don't think so. |
The same thing happens to the nested version:
In the normal situation, IOManager should be in the |
The normal |
For the record,
|
Some of threads labeled with The server is not responding. The following thread is leaked:
EDIT: thread 24 is not leaking. It's working since all connections are not terminated yet. |
I cannot reproduce this by myself so far, sigh. |
It appeared that |
Registered a documentation issue to GHC: |
After preventing calling |
Closing. |
#589 changed
gracefullClose
as follows:timeout
is used.I'm testing the approach 1) on my server. Unfortunately,
CLOSE_WAIT
happened again.Since my server did not accept new connections, I'm sure that
CLOSE_WAIT
represents SYN packets in thelisten
queue.This means that IO manager is blocked.
I need to understand why
writeTVar
is blocked.The text was updated successfully, but these errors were encountered: