Ticket #31 (new enhancement)

Opened 4 years ago

Last modified 3 years ago

doc on setSocketOption and getSocketOption

Reported by: kazu-yamamoto Owned by:
Priority: trivial Milestone:
Component: network Version:
Keywords: Cc:

Description

Since setSocketOption and getSocketOption can handle only Int-type options, what about removing options other than Int-type that cannot be used anyway.

Moreover, please add "Use System.Timeout.timeout if you need functionality of SO_SNDTIMEO and SO_RCVTIMEO" in the document.

Change History

in reply to: ↑ description   Changed 3 years ago by joeyadams

Replying to kazu-yamamoto:

Moreover, please add "Use System.Timeout.timeout if you need functionality of SO_SNDTIMEO and SO_RCVTIMEO" in the document.

This is not true on Windows with -threaded. Since I/O is done using FFI calls, it cannot be interrupted with System.Timeout.timeout. Worse, in GHC < 7.2.2, asynchronous exceptions will be discarded entirely (see GHC ticket #5611).

You can use an async wrapper to work around the problem:

wrappedRecv :: Socket -> Int -> IO String
wrappedRecv sock len = do
    mv <- newEmptyMVar
    bracket (forkIO $ recv sock len >>= putMVar mv)
            (forkIO . killThread)
            (\_ -> takeMVar mv)

wrappedRecv can be interrupted by an asynchronous exception. When interrupted, it will kill the receiving thread. Since killThread blocks until the exception has been delivered, wrappedRecv forks a thread to call killThread so killThread won't hold up the program.

The problem is, if the recv hangs indefinitely on an FFI call, it leaks an OS thread. You only get about 1000 of those before the program runs out of address space (on Windows 32-bit with default settings).

Thus, the only way (I'm aware of) to prevent a network operation from hanging indefinitely, without leaking OS threads, is to set SO_SNDTIMEO and SO_RCVTIMEO.

One more problem, though: SO_SNDTIMEO and SO_RCVTIMEO do not seem to affect connect. On my test machine, connect always times out after 20 seconds. As long as it does eventually time out, this shouldn't be too much of a problem, as long as connect is a safe FFI call (which it currently isn't; see #44).

Note: See TracTickets for help on using tickets.