Signals + minimal proposal (was Re: asynchronous exceptions)

Simon Marlow simonmar at microsoft.com
Fri Apr 7 07:36:11 EDT 2006


On 06 April 2006 23:20, John Meacham wrote:

>> I'm not proposing that we ignore signals, just that we should clearly
>> delimit the platform-specific bits, perhaps by putting signal support
>> into an addendum.
> 
> yeah, I was thinking a separate environment addendum should be in the
> report, which takes behavior that is undefined in the language
> standard, 
> and defines it for various platforms. it wouldn't extend the
> functionality or scope of the standard, just define what couldn't be
> defined in the standard.
> 
> like the standard might say "the set of signals is undefined" while
> the 
> UNIX addendum will say "the set of signals will include at least
> SIGINT,SIGHUP,etc..."

There's the question of whether ^C should look the same on both Windows
and Unix.  Windows doesn't have signals as such, but some things like ^C
can be made to look like signals.  We might consider specifying as part
of the portable part of the API that there is at least an "interrupt"
signal that corresponds to a user interrupt, and in the
platform-specific part of the documentation we say what it actually maps
to on each platform (SIGINT on Unix, CTRL_BREAK_EVENT on Windows, etc.).

>> GHC has no support for these right now.  They're pretty tricky to
>> handle, because the OS thread that caused the signal to be raised is
>> stopped at some arbitrary instruction, and it would require some
>> serious acrobatics to munge that OS thread into a state where it is
>> possible to raise the (Haskell) exception.  I do vaguely recall that
>> people have achieved this in the past, in order to use page faults
>> for write barriers, that sort of thing.
> 
> how does ghc handle things like divide by zero then?

By checking before trying to divide :-)

>>> signal an asynchronous exceptional event
>>> - the user should be able to choose the threads on which they wish
>>>   to catch these, those that need to clean up after themselves.
>>> 
>>> inform the app of an event it might want to take note of
>>> - these should run on their own thread, concurrently to all other
>>>   threads
>> 
>> GHC directly support the latter version, and you can implement the
>> former with a little extra code and a global variable.  I think it
>> would be nice to do as you suggest and provide a way to have the
>> async signals turn directly into exceptions.
>> 
>> One problem, though, is that because we can't interrupt a foreign
>> call with an async exception, ^C can be rather unresponsive. 
>> Perhaps I should look into this and see whether it would be possible
>> in GHC for a concurrent foreign call to be interruptible; it would
>> involve terminating the foreign call somehow (pthread_cancel?)
>> before raising the exception.  We can't do this in a bound thread,
>> however. 
> 
> You should be able to handle the SIGINT imediatly no matter whether
> foregin code is running if your handler is in its own thread right?

Yes, but if the signal handler wants to send an exception to the main
thread, as it often does, and the main thread is in a foreign call, ^C
appears to not do anything.

> just have the C signal handler write a byte to a pipe, your haskell
> signal handler thread is in a
> 
> repeatM $ do
>         readExactlyOneByte
>         signalHandler
> 
> loop.

Yes, this is exactly what GHC does.


> = minimal proposal =
> 
> I think a good minimal solution will be the following, it neatly
> avoids 
> turning signals into exceptions, which may be problematic, but
> provides 
> for the common cases of signal usages while being compatible with both
> cooperative and SMP systems.
> 
> == catching signals ==
> 
> implementations provide a way of catching signals such that the
> handler 
> runs as if in its own thread. something like the following
> 
> data SigInfo = ...
> data HandlerType = SigOneShot | SigReset | SigIdempotent
> 
> data SigAction = SigAction {
>         signalType :: HandlerType,
>         signalAction :: SigInfo -> IO ()
>         }  | SigDefault | SigIgnore | SigExit (SigInfo -> ExitStatus)
> 
> installHandler :: Signal -> SigAction -> IO SigAction
> installHandler = ...
>
> the action runs in its own thread.

Yes, looks quite reasonable.
 
> == on exit ==

I'll address this in a separate thread.

Cheers,
	Simon


More information about the Haskell-prime mailing list