
On Thu, Apr 06, 2006 at 03:19:30PM -0700, John Meacham wrote:
= 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.
I must admit that I don't understand the problem with turning signals into exceptions, but I really prefer the picture of signals as exceptions, as it seems to me to be much simpler. Both simpler to use, and simpler to describe in the standard. Rather than having to enumerate (or leave vague) a list of signals, and describe an API for handling these things that may or may not exist on a given platform, the standard could just state that any "OS events that would normally lead to the application quitting" generate asynchronous exceptions. This is suitably vague, and has the result that when coding you can simply assume that bracket will catch everything that could be caught and lead to nicely cleaning up. The catch to this [no pun intended] is that when the main thread exits all other threads are silently terminated, without the chance to clean up... I'd prefer they get a special exception first, to give them a chance to clean up. But at least with a single-threaded app, you could then work under the assumption that catching exceptions catches is "complete" (or at least as complete as the compiler was able to implement--I don't think you can catch sigKILL, but that's an OS limitation).
== on exit ==
implementations also provide an onExit functionality, for registering handlers that can be run when the program exits, as this is the most common use of signals as exceptions, to clean up after oneself.
-- | temporarily register an exit handler for the duration of the action argument withExitHandler :: IO () -> IO a -> IO a withExitHandler = ....
This would work, but seems overly-complex, and leads to interesting questions. What happens if the action argument throws an exception? How do I implement a "really_bracket" using this? really_bracket init clean job = bracket init clean job' where job' a = withExitHandler (do {clean a;return ()}) job Is this as clean a solution as bracket? It seems to me that in either case there is a window in which clean won't get called either in the case of a signal or an exception, although I'm not sure. I'm also not sure whether you'd run into danger of clean being called twice when an exit is never caught, once by the bracket and once by the exit handler. If signals don't generate exceptions, I'd at least like some sort of really_bracket to make it into the standard, as this is probably the most troublesome aspect of existing Haskell. -- David Roundy http://www.darcs.net