[GHC] #10380: "thread blocked indefinitely" exception while blocking on a socket
GHC
ghc-devs at haskell.org
Mon May 4 09:20:30 UTC 2015
#10380: "thread blocked indefinitely" exception while blocking on a socket
-------------------------------------+-------------------------------------
Reporter: akio | Owner:
Type: bug | Status: new
Priority: normal | Milestone:
Component: | Version: 7.10.1
libraries/base | Operating System: Linux
Keywords: | Type of failure: Incorrect result
Architecture: | at runtime
Unknown/Multiple | Blocked By:
Test Case: | Related Tickets:
Blocking: |
Differential Revisions: |
-------------------------------------+-------------------------------------
First start a TCP server, e.g. nc.
{{{
% nc localhost -l 1234 > /dev/null
}}}
On another shell, compile the following program and run it:
{{{
% ghc -threaded sock.hs
% ./sock localhost 1234
receiver: thread blocked indefinitely in an MVar operation
}}}
{{{#!hs
{-# LANGUAGE ViewPatterns #-}
import Control.Applicative -- GHC 7.8 compatibility
import Control.Concurrent
import qualified Control.Exception as Ex
import Control.Monad
import qualified Data.ByteString.Char8 as S
import Network.Socket
import qualified Network.Socket.ByteString as Sock
import Network.BSD (getHostByName, hostAddresses)
import System.Environment
import System.Mem
main :: IO ()
main = do
[host, read -> fromInteger -> port] <- getArgs
sock <- connectTo host port
forkVerbose "sender" $ forever $ do
_ <- Sock.send sock $ S.replicate 40000 '0'
return ()
forkVerbose "receiver" $ forever $ do
dat <- Sock.recv sock 2048
putStrLn $ "received: " ++ show dat
forever $ do
threadDelay 1000000
performGC
forkVerbose :: String -> IO () -> IO ()
forkVerbose name act = void $ forkIO $ do act; msg "exiting normally"
`Ex.catch` \e -> msg $ show (e :: Ex.SomeException)
where
msg s = putStrLn $ name ++ ": " ++ s
connectTo :: HostName -> PortNumber -> IO Socket
connectTo hostName port = do
addr <- SockAddrInet port <$> lookupHost hostName
sock <- socket AF_INET Stream 0
connect sock addr
return sock
lookupHost :: String -> IO HostAddress
lookupHost name = do
hostInfo <- getHostByName name
case hostAddresses hostInfo of
[] -> error ("Invalid host name: " ++ name)
(a:_) -> return a
}}}
GHC 7.8.3 doesn't have this problem.
I suspect that this is a regression in the event manager. When there is an
event, `GHC.Event.Manager.onFdEvent` seems to remove all callbacks
associated to the `fd`, whether or not they match the current event. In
the program above, the callback for `recv` may be removed permanently when
the socket becomes ready for `send`ing, causing the "receiver" thread to
deadlock.
--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/10380>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
More information about the ghc-tickets
mailing list