[Haskell-cafe] createProcess interferes with sockets?
Evan Laforge
qdunkan at gmail.com
Sun Apr 21 14:27:00 CEST 2013
I've had a strange bug that's baffled me for a long time. I finally
got serious about tracking it down, and managed to reduce it to a
small program that exhibits the unexpected behaviour, namely that a
createProcess seems to block writing to and closing a socket.
Here's the example program:
---
import Control.Monad
import qualified Network
import qualified System.Environment as Environment
import qualified System.IO as IO
import qualified System.Process as Process
main :: IO ()
main = Network.withSocketsDo $ do
args <- Environment.getArgs
case args of
["server"] -> server
["client"] -> client
_ -> error $ show args
server :: IO ()
server = do
socket <- Network.listenOn port
forever $ do
putStrLn "accept"
(hdl, _host, _port) <- Network.accept socket
msg <- IO.hGetLine hdl
putStrLn $ "from client: " ++ show msg
sleep
putStrLn "send response"
IO.hPutStr hdl "response"
IO.hClose hdl
client :: IO ()
client = do
hdl <- Network.connectTo "localhost" port
IO.hPutStr hdl "hi from client\n"
IO.hFlush hdl
resp <- IO.hGetContents hdl
print resp
port = Network.UnixSocket "port"
sleep = Process.createProcess (Process.proc "sleep" ["5"])
---
You can test with:
% ghc --make Test.hs && rm -f port && ./Test server
then on another window:
% ./Test client
Since the createProcess is async (it doesn't wait on the pid), I
expect the response to come back to the client immediately. And the
server immediately says "send response" then "accept", so it doesn't
get stuck on the sleep. But the client waits 5 seconds before
displaying "response", so evidently even though the handle has already
been written to and closed from the server, the client waits until the
subprocess (of the server!) completes before getting the response.
Comment out the "sleep" line and everything is fast.
Can anyone else repro this? I'm guessing it has to do with the ghc IO
manager, and the fork implied by a createProcess is causing it the
socket close to block, but I haven't dug any deeper yet, in case this
is a know issue, or I'm just doing something wrong. This is OS X
10.8.3.
thanks!
More information about the Haskell-Cafe
mailing list