
I would like to know if that will help to solve that "uncaught exception problem" when leaving HOpenGL programs.
A strictly conforming implementation shouldn't have that problem, see:
http://haskell.org/pipermail/ffi/2002-January/000436.html
I know that Simon "RTS" Marlow :-) is on this list,
what... who.. me? :-}
so perhaps he could answer the question when GHC is changed this way...
Ok, the problem as we all know is that System.exitWith now raises an exception rather than simply terminating the program. This is highly desirable behaviour especially in a concurrent system, and was essential in GHCi so that if the interpreted program calls System.exitWith we don't terminate GHCi itself. The problem is that this exception isn't propagated to the main thread automatically if it is raised in a child thread. Foreign-exported functions are run in child threads. Furthermore, it's not clear exactly how the exception should be propagated, because there isn't always a single main thread to send it to. Two workarounds spring to mind: firstly, you could wrap callbacks in a suitable exception handler. So instead of calling 'mkCallback e' where mkCallback is a foreign export dynamic, you would call 'mkCallback (Exception.catch e handler)' where handler is something like topHandler in fptools/ghc/lib/std/PrelTopHandler.lhs, but you probably want to discard all exceptions except ExitException. Perhaps GHC should do this wrapping automatically, I'm not sure. Alternatively you could call your own version of exitWith which does a real exit. Again, see PrelTopHandler.lhs for the function shutdownHaskellAndExit, which is our equivalent of hs_exit() (when we get around to catching up with the FFI spec, hs_exit() will probably be a synonym for shutdownHaskellAndExit()). Cheers, Simon

"Simon Marlow"
I would like to know if that will help to solve that "uncaught exception problem" when leaving HOpenGL programs.
A strictly conforming implementation shouldn't have that problem, see:
http://haskell.org/pipermail/ffi/2002-January/000436.html
I know that Simon "RTS" Marlow :-) is on this list,
what... who.. me? :-}
so perhaps he could answer the question when GHC is changed this way...
Ok, the problem as we all know is that System.exitWith now raises an exception rather than simply terminating the program. This is highly desirable behaviour especially in a concurrent system, and was essential in GHCi so that if the interpreted program calls System.exitWith we don't terminate GHCi itself.
The problem is that this exception isn't propagated to the main thread automatically if it is raised in a child thread. Foreign-exported functions are run in child threads. Furthermore, it's not clear exactly how the exception should be propagated, because there isn't always a single main thread to send it to.
Two workarounds spring to mind: firstly, you could wrap callbacks in a suitable exception handler. So instead of calling 'mkCallback e' where mkCallback is a foreign export dynamic, you would call 'mkCallback (Exception.catch e handler)' where handler is something like topHandler in fptools/ghc/lib/std/PrelTopHandler.lhs, but you probably want to discard all exceptions except ExitException. Perhaps GHC should do this wrapping automatically, I'm not sure.
That sounds like a good solution to me.
Alternatively you could call your own version of exitWith which does a real exit. Again, see PrelTopHandler.lhs for the function shutdownHaskellAndExit, which is our equivalent of hs_exit() (when we get around to catching up with the FFI spec, hs_exit() will probably be a synonym for shutdownHaskellAndExit()).
This one has the disadvantage that it would kill GHCi when this happens in interactive mode - the reason for making exitWith based on exceptions in the first place. (BTW, the hs_exit() bit I didn't do in my FFI commit. Mainly because this extra argument to the initialisation function seems to require some more thought.) Cheers, Manuel
participants (2)
-
Manuel M. T. Chakravarty
-
Simon Marlow