Signals + minimal proposal (was Re: asynchronous exceptions)

Simon Marlow simonmar at
Fri Apr 7 09:58:01 EDT 2006

On 07 April 2006 13:58, John Meacham wrote:

> all threads keep running while the exit handers are running, all
> blockExit would do is grab and release an MVar. exit itself takes
> that MVar on starting to get rid of races to exit as well as protect
> itsesf from 'blockExit' (but won't ever put the MVar back).

That sounds hard to program with - surely you want to stop the program
in order to clean up?  Otherwise the program is going to continue
working, generating more exit handlers, and we might never get to exit.

Of course you could implement some global flag to say that an exit is in
progress, but that implies explicit checking of the flag all over the
place, which is what asynchronous exceptions are designed to avoid.

When *do* we exit, in fact?  When all the exit handlers have finished?

>> Exceptions are the right way to handle releasing resources, and they
>> are the right way to register cleanup actions.  Therefore I believe
>> exceptions are the right way to handle cleaning up on exit, too.
> Well, We really need 'onExit' for other reasons as well, I think it
> should make it into the standard independently.

Sure, I'm happy with onExit.

> I think you have that backwards, releasing resources is the right
> thing 
> to do when you get an exception, but there are lots of other reasons
> you 
> want to release resources that have nothing to do with exceptions. you
> don't use 'throwTo' to close all your files :)

No, but you do use an exception handler, or something built using
exception handlers like 'finally'.  I don't want to have to use *both*
exception handlers and exit handlers.

>> Since async exceptions are no problem to implement in a coop system,
>> shouldn't we use them for exit too?
> but then only one thread gets to clean up after itself,

I think all threads should get the exit exception (I know GHC doesn't
currently do this).

> and you have
> the issue that you can't interrupt a foreign function by throwing to
> it. 

The situation is the same as in your proposal - the foreign call
continues running.  However, as soon as it returns, the Haskell thread
will receive an exception.

I propose this:

  When System.Exit.exitWith is called, all currently running
  threads are sent an exit exception as soon as possible.
  Exit handlers registered with onExit are started immediately.
  The system exits when (a) the main thread has stopped, and (b)
  all exit handlers have completed.  Subsequent calls to exitWith
  simply throw an exit exception in the current thread.


More information about the Haskell-prime mailing list