[MLton] interrupted system call

Stephen Weeks MLton@mlton.org
Mon, 22 Mar 2004 20:59:03 -0800


> O.k., but why is the system call interrupted (and returning an error),
> rather than having the alrm signal raised (and handled)?

I believe this is a (known) bug in MLton.

> I don't know exactly what MLton does, but at the OS level, it depends on what
> the sa_flags of the struct sigaction is set to.  If you want system calls  to
> be  restarted  (after the signal handler is called) then you should set it to
> SA_RESTART.  If you don't then as I recall Linux is more system-V-ish,  which
> means that the system call fails with an errno as you see it.
> 
> The  notion  is that sometimes you want an interrupt to exit the system call,
> and if you use SA_RESTART, then that  won't  happen,  although  you  can  use
> setsetjmp and the like to get the effect (yuck).

We had a discussion about this back in July 2000

	http://www.mlton.org/pipermail/mlton/2000-July/

The discussion explains that we don't want to use SA_RESTART because
it will prevent the SML signal handler from running, and that's what
we ended up doing.  I also explained what we should do as a
consequence.

    I think this problem could be alleviated by having all system
    calls restarted at the ML level, within the basis library code.
    After every system call, the library code would then check errno,
    and if it's EINTR, would run the ML signal handler with a current
    thread that knows to restart the system call.

To this, Henry said

    Yes, I think that that (having the ML code manually doing the
    restart after the interrupt, is the way to go.  I'm slightly
    nervous about the EINTR thing since I seem to recall some versions
    of Unix returning other things.  For instance ERESTART.

and

    I'm pretty sure that only some system calls can get interrupted.
    I.e., I don't think that getpid() can set errno to this.  Still,
    it might be easier to always check.  Don't forget you can only
    check errno values if the system call returns failure in some way.
    Also I have seen some systems set errno to EAGAIN I think on that.
    Hm, maybe that was only with non-blocking file descriptors
    (although I would think that that would return EWOULDBLOCK).

Putting the checks for EINTR has been on my todo list since then, but
has never gotten done.  It still seems like the right thing to do.
It's a lot of work to go through the basis library and put these
wrappers around system calls.  If someone else wants to take a crack
at it, I'd love to see it.