summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Marlow <simonmar@microsoft.com>2007-05-11 09:07:19 +0000
committerSimon Marlow <simonmar@microsoft.com>2007-05-11 09:07:19 +0000
commit485b80f9c422e49a441ec0b175c39799630171da (patch)
tree87f5060d885b30756b91c9135e83a40230f993f1
parent4da439a6b1e343fc5216d5c6bb51858c6d9aacd6 (diff)
downloadhaskell-485b80f9c422e49a441ec0b175c39799630171da.tar.gz
improve :abandon, it wasn't properly terminating the computation (see comments)
-rw-r--r--compiler/main/InteractiveEval.hs22
1 files changed, 19 insertions, 3 deletions
diff --git a/compiler/main/InteractiveEval.hs b/compiler/main/InteractiveEval.hs
index 26d251d912..42f0922370 100644
--- a/compiler/main/InteractiveEval.hs
+++ b/compiler/main/InteractiveEval.hs
@@ -522,8 +522,9 @@ abandon (Session ref) = do
resume = ic_resume ic
case resume of
[] -> return False
- _:rs -> do
+ r:rs -> do
writeIORef ref hsc_env{ hsc_IC = ic { ic_resume = rs } }
+ abandon_ r
return True
abandonAll :: Session -> IO Bool
@@ -532,11 +533,26 @@ abandonAll (Session ref) = do
let ic = hsc_IC hsc_env
resume = ic_resume ic
case resume of
- [] -> return False
- _:rs -> do
+ [] -> return False
+ rs -> do
writeIORef ref hsc_env{ hsc_IC = ic { ic_resume = [] } }
+ mapM_ abandon_ rs
return True
+-- when abandoning a computation we have to
+-- (a) kill the thread with an async exception, so that the
+-- computation itself is stopped, and
+-- (b) fill in the MVar. This step is necessary because any
+-- thunks that were under evaluation will now be updated
+-- with the partial computation, which still ends in takeMVar,
+-- so any attempt to evaluate one of these thunks will block
+-- unless we fill in the MVar.
+-- See test break010.
+abandon_ :: Resume -> IO ()
+abandon_ r = do
+ killThread (resumeThreadId r)
+ putMVar (resumeBreakMVar r) ()
+
-- -----------------------------------------------------------------------------
-- Bounded list, optimised for repeated cons