Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

c_connect should not be an unsafe foreign import on Windows #61

Closed
joeyadams opened this Issue · 2 comments

2 participants

@joeyadams

This ticket fell by the wayside when the network package switched to github: http://trac.haskell.org/network/ticket/44


On Windows with -threaded, when Network.Socket.connect is called, it blocks the whole RTS until the connection attempt succeeds or fails.

This is because under the hood, it is calling c_connect, an unsafe foreign import:

foreign import CALLCONV unsafe "connect"
  c_connect :: CInt -> Ptr SockAddr -> CInt{-CSockLen???-} -> IO CInt

Unsafe foreign calls block the whole runtime system. Safe foreign calls block only the current thread (but cannot be interrupted by exceptions).

I tested it on Windows with network-2.3.0.8, and Network.Socket.connect does in fact block the whole program. When I changed unsafe to safe and recompiled, it did not block the whole program.

It seems clear that c_connect should be a safe foreign import, at least on Windows with -threaded. Are there any other foreign calls marked safe that could potentially block on Windows?

@tibbe
Owner

It seems clear that c_connect should be a safe foreign import, at least on Windows with -threaded. Are there any other foreign calls marked safe that could potentially block on Windows?

I'd have to double check but I believe all (?) calls are marked as unsafe on *nix (except perhaps address resolution), as we use the I/O manager to handle blocking.

I think we should define a SAFE_ON_WINDOWS #define and use that in the foreign import declarations. I don't have a Windows machine to test on, would you be able to prepare a patch that works on Windows and I'll test it on OS X/Linux?

@joeyadams

I think we should define a SAFE_ON_WINDOWS #define and use that in the foreign import declarations.

This is already done:

-- ----------------------------------------------------------------------------
-- On Windows, our sockets are not put in non-blocking mode (non-blocking
-- is not supported for regular file descriptors on Windows, and it would
-- be a pain to support it only for sockets).  So there are two cases:
...
##if defined(mingw32_HOST_OS)
##define SAFE_ON_WIN safe
##else
##define SAFE_ON_WIN unsafe
##endif

My commit changes only one line: import connect with SAFE_ON_WIN.

@tibbe tibbe closed this issue from a commit
@joeyadams joeyadams Network.Socket: Make connect a safe foreign import on Windows
We're using blocking FFI calls on Windows (unfortunately).  If the server is
unresponsive, connect() blocks for a while.  An unsafe FFI call blocks the
whole RTS, whereas a safe FFI call only blocks the current thread
(when -threaded is used).

Fixes #61
638858b
@tibbe tibbe closed this in 638858b
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.