
On Tue, Nov 11, 2003 at 09:39:05AM -0000, Simon Marlow wrote:
Hmm, there is clearly a choice between having a signal spawn a new thread or raise an asynchronous exception, and it's not at all clear which is best.
But, since we can implement either using the other one, it doesn't really matter too much which one is primitive.
How can the spawn-a-thread semantics be implemented using asynchronous exceptions? Doesn't the thread that the exception is thrown to unwind to the topmost handler? On 14.11.2003, at 16:21, David Roundy wrote:
In darcs, I really have no interest in dealing with signals, I just want to make sure my temporary files are cleaned up even if the user hits ^C. If the default signal handler uses exceptions, this will happen for free. Currently, my only choice for the former purpose is to use something like withSignal.
But the ^C signal itself is not, in general, sent to a specific thread; rather, it's sent to the whole process. So while it's reasonable to convert a SIGINT to an asynchronous exception thrown to a specific thread (as GHCi does), I don't see how that can be done generally. If you want bracket to clean up if the user hits ^C, you'd still have to hava a way of specifying which thread(s) get aborted using an exception on SIGINT. The default behaviour should lead to termination of the entire program; but in other situations (like GHCi for example), I'd probably want to catch the exception in one thread and have all other threads continue.
I guess the problem is that as far as I can tell, there is no way to implement a "correct" bracket along with the existing POSIX signal implementation, since there's no way to find out what the current handler is, which means bracket can't install its own handler without messing up the current handler.
A way to find out the current handler could probably be added, but it'd still be impossible to implement a SIGINT-aware bracket because signal handlers are per-process, not per-thread.
It still doesn't do what I'd really like, which is add default handlers for signals. I'd really like a
withSignalsAsExceptions :: IO a -> IO a
which would add an exception-throwing handler for *every* signal type (perhaps every asynchronous signal type...), and then run the default handler for any uncaught signals. Even better if main was automatically run in a withSignalsAsExceptions environment.
Wouldn't that render every signal that isn't intended to cause clean program shutdown next to useless? It seems perfect for SIGINT and SIGTERM, but I don't think that I'd want to handle SIGCONT or SIGCHLD as exceptions. Cheers, Wolfgang