Problems interrupting IO with -threaded

Simon Marlow marlowsd at
Wed Jun 11 00:43:33 EDT 2008

Judah Jacobson wrote:
> Hi all,
> I'm writing a program that reads input from the user but should also
> handle a ctrl-c.  My attempt is below; the program forks a thread to
> read one character of input, and kills that thread upon receiving a
> sigINT.  It works fine compiled without -threaded, but with -threaded
> it blocks forever after a ctrl-c.
> I know that in general, foreign calls are not interruptible; but the
> documentation for Control.Concurrent and System.Timeout suggests that
> I/O operations are a special case.  In particular, the documentation
> for System.Timeout.timeout says:
> "Standard I/O functions like hGetBuf, hPutBuf, Network.Socket.accept,
> or hWaitForInput appear to be blocking, but they really don't because
> the runtime system uses scheduling mechanisms like select(2) to
> perform asynchronous I/O, so it is possible to interrupt standard
> socket I/O or file I/O using this combinator."
> So is the behavior that I'm seeing correct?  If so, it seems odd to
> get better concurrency without the threaded runtime.  If not, I can
> file a bug for this.  I used ghc-6.8.2 and HEAD on OS X 10.5 (x86).

Ah, this is a consequence of the change we made to stdin/stdout/stderr 
so that they no longer use O_NONBLOCK, but with -threaded they use 
blocking foreign calls instead.  In your example, getChar is stuck in a 
blocking foreign call and can't be interrupted.

I don't see a good workaround.  One way is to add another thread: run 
the getChar in a subthread and the parent will be able to receive the 
signal.  Or perhaps you could cause the read() that getChar has called 
to return EINTR, but that might not be enough because the I/O library 
executes mostly inside Control.Exception.block.

Unix semantics just isn't the right thing when it comes to non-blocking 
I/O.  If only there were non-blocking read()/write() system calls, we'd 
be fine.


More information about the Glasgow-haskell-users mailing list