summaryrefslogtreecommitdiff
path: root/ghc/compiler/utils
diff options
context:
space:
mode:
authorsimonmar <unknown>2006-01-12 16:16:28 +0000
committersimonmar <unknown>2006-01-12 16:16:28 +0000
commit44713ec1fa30bab4b6e087d017ca8524f9792b34 (patch)
tree56ad2884a412711925520630678cbb5b200c990a /ghc/compiler/utils
parentde910f06ebec544c71cd5c41dbb11937812c7a1a (diff)
downloadhaskell-44713ec1fa30bab4b6e087d017ca8524f9792b34.tar.gz
[project @ 2006-01-12 16:16:28 by simonmar]
GHC.runStmt: run the statement in a new thread to insulate the environment from bad things that the user code might do, such as fork a thread to send an exception back at a later time. In order to do this, we had to keep track of which thread the ^C exception should go to in a global variable. Also, bullet-proof the top-level exception handler in GHCi a bit; there was a small window where an exception could get through, so if you lean on ^C for a while then press enter you could cause GHCi to exit.
Diffstat (limited to 'ghc/compiler/utils')
-rw-r--r--ghc/compiler/utils/Panic.lhs21
1 files changed, 15 insertions, 6 deletions
diff --git a/ghc/compiler/utils/Panic.lhs b/ghc/compiler/utils/Panic.lhs
index 3d5cf1707c..cdfc9628b9 100644
--- a/ghc/compiler/utils/Panic.lhs
+++ b/ghc/compiler/utils/Panic.lhs
@@ -19,7 +19,7 @@ module Panic
Exception.Exception(..), showException, try, tryJust, tryMost, tryUser,
catchJust, ioErrors, throwTo,
- installSignalHandlers,
+ installSignalHandlers, interruptTargetThread
) where
#include "HsVersions.h"
@@ -49,7 +49,7 @@ import EXCEPTION ( throwTo )
import EXCEPTION ( catchJust, tryJust, ioErrors )
#endif
-import CONCURRENT ( myThreadId )
+import CONCURRENT ( myThreadId, MVar, ThreadId, withMVar, newEmptyMVar )
import DYNAMIC
import qualified EXCEPTION as Exception
import TRACE ( trace )
@@ -209,16 +209,21 @@ throwTo = Exception.raiseInThread
\end{code}
Standard signal handlers for catching ^C, which just throw an
-exception in the main thread. NOTE: must be called from the main
-thread.
+exception in the target thread. The current target thread is
+the thread at the head of the list in the MVar passed to
+installSignalHandlers.
\begin{code}
installSignalHandlers :: IO ()
installSignalHandlers = do
- main_thread <- myThreadId
let
interrupt_exn = Exception.DynException (toDyn Interrupted)
- interrupt = throwTo main_thread interrupt_exn
+
+ interrupt = do
+ withMVar interruptTargetThread $ \targets ->
+ case targets of
+ [] -> return ()
+ (thread:_) -> throwTo thread interrupt_exn
--
#if !defined(mingw32_HOST_OS)
installHandler sigQUIT (Catch interrupt) Nothing
@@ -239,4 +244,8 @@ installSignalHandlers = do
#else
return () -- nothing
#endif
+
+{-# NOINLINE interruptTargetThread #-}
+interruptTargetThread :: MVar [ThreadId]
+interruptTargetThread = unsafePerformIO newEmptyMVar
\end{code}