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 |