Skip to content

readRawBufferPtr cannot be interrupted by exception on Windows with -threaded

On Windows, in a program compiled with -threaded, if a thread receives from a Handle created by the network package (e.g. with hGetLine), it cannot be interrupted by an asynchronous exception.

I've traced it down to readRawBufferPtr, which is used by Network.Socket.recv. Although I haven't tested readRawBufferPtr directly, my test case (attached) tests Network.Socket.recv.

For Windows, base 4.4.1.0 implements it as:

readRawBufferPtr :: String -> FD -> Ptr Word8 -> Int -> CSize -> IO CInt
readRawBufferPtr loc !fd buf off len
  | threaded  = blockingReadRawBufferPtr loc fd buf off len
  | otherwise = asyncReadRawBufferPtr    loc fd buf off len

...

blockingReadRawBufferPtr :: String -> FD -> Ptr Word8 -> Int -> CSize -> IO CInt
blockingReadRawBufferPtr loc fd buf off len
  = fmap fromIntegral $ throwErrnoIfMinus1Retry loc $
        if fdIsSocket fd
           then c_safe_recv (fdFD fd) (buf `plusPtr` off) len 0
           else c_safe_read (fdFD fd) (buf `plusPtr` off) len

...

-- NOTE: "safe" versions of the read/write calls for use by the threaded RTS.
-- These calls may block, but that's ok.

foreign import stdcall safe "recv"
   c_safe_recv :: CInt -> Ptr Word8 -> CSize -> CInt{-flags-} -> IO CSsize

foreign import stdcall safe "send"
   c_safe_send :: CInt -> Ptr Word8 -> CSize -> CInt{-flags-} -> IO CSsize

If I understand correctly, safe foreign calls cannot be interrupted by asynchronous exceptions.

Is this a bug in readRawBufferPtr, or a bug in the network package? Can a caller expect readRawBufferPtr to be interruptible by an exception?

Trac metadata
Trac field Value
Version 7.2.2
Type Bug
TypeOfFailure OtherFailure
Priority normal
Resolution Unresolved
Component libraries/base
Test case
Differential revisions
BlockedBy
Related
Blocking
CC
Operating system
Architecture
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information