[network] #9: Race/Async Exception issue in Network.Socket.connect
network
libraries at haskell.org
Tue May 12 15:05:58 EDT 2009
#9: Race/Async Exception issue in Network.Socket.connect
---------------------+------------------------------------------------------
Reporter: sclv | Owner:
Type: defect | Status: new
Priority: major | Milestone:
Component: network | Version:
Keywords: |
---------------------+------------------------------------------------------
Submitted here as well: http://hackage.haskell.org/trac/ghc/ticket/3225
{{{
import Control.Concurrent
import Control.Monad
import Network.Socket
import Control.Exception as C
import System.Timeout
import Network.BSD(hostAddresses, getHostByName)
import System.IO.Error
import Data.Maybe
-- someHostName should be replaced by a real host that gives
-- "connection refused" errors on connection to ports in the range.
-- The latter ip is a junk one that should cause connections to
-- hang indefinitely.
-- More hostnames with either characteristic can be added to taste
-- if that helps to reproduce the bug.
servers = [ "someHostName", "126.255.255.255"]
ports = [9001..9099] :: [Int]
conns = [(h,p) | h <- servers, p <- ports]
connectSock :: Integral a => String -> a -> IO Socket
connectSock host port = do
hn <- maybe (ioError . mkIOError doesNotExistErrorType "No Host
Address" Nothing $ Just host) return . listToMaybe . hostAddresses =<<
getHostByName host
sk <- socket AF_INET Stream 6
connect sk (SockAddrInet (fromIntegral port) hn) `C.onException` sClose
sk
return sk
pMapM f xs = mapM (\x -> forkIO $ f x) xs
mapM' f xs = mapM (\x -> (C.try :: IO a -> IO (Either C.SomeException a))
(f x)) xs
main = do
-- This is the canary thread in the bugmine
forkIO $ forever $ putStrLn "chirp" >> threadDelay 100000
-- This is the bug thread
forever $ pMapM (\(h,p) -> timeout 1000000 (connectSock h p) >> return
()) conns >> threadDelay 2000000
}}}
The above code, compiled with the threaded runtime, causes a race
condition. After roughly one to two cycles of the bug thread, the canary
thread stops running, indicating that the program has become somehow
trashed. (The bug thread stops running as well).
In experiments, this race condition is best triggered with at least two
servers, one of which yields "connection refused" on connection, and the
other of which simply hangs -- the nonsense ip address provided above
works for the latter.
If the pMapM is replaced by mapM' (i.e. we switch from parallel to serial
connection) then the bug does not appear to be triggered.
Wrapping the call to sClose in a mutex didn't seem to help, so it seems
the race condition is in the connect call.
--
Ticket URL: <http://trac.haskell.org/network/ticket/9>
network <http://projects.haskell.org/network/>
Networking-related facilities
More information about the Libraries
mailing list