[commit: ghc] master: Fix #4988: we were wrongly running exception handlers in the (fa71e6c)

Simon Marlow marlowsd at gmail.com
Thu Sep 1 12:33:52 CEST 2011


Repository : ssh://darcs.haskell.org//srv/darcs/ghc

On branch  : master

http://hackage.haskell.org/trac/ghc/changeset/fa71e6c795489ec267e0d048395c2c52bea6a164

>---------------------------------------------------------------

commit fa71e6c795489ec267e0d048395c2c52bea6a164
Author: Simon Marlow <marlowsd at gmail.com>
Date:   Wed Aug 31 22:45:01 2011 +0100

    Fix #4988: we were wrongly running exception handlers in the
    maskUninterruptible state instead of ordinary mask, due to a
    misinterpretation of the way the TSO_INTERRUPTIBLE flag works.
    
    Remarkably this must have been broken for quite some time.  Indeed we
    even had a test that demonstrated the wrong behaviour (conc015a) but
    presumably I didn't look hard enough at the output to notice that it
    was wrong.

>---------------------------------------------------------------

 rts/Exception.cmm |   16 +++++++++-------
 1 files changed, 9 insertions(+), 7 deletions(-)

diff --git a/rts/Exception.cmm b/rts/Exception.cmm
index 24da1c6..591fa7a 100644
--- a/rts/Exception.cmm
+++ b/rts/Exception.cmm
@@ -556,17 +556,19 @@ retry_pop_stack:
     }
 
     /* Ensure that async excpetions are blocked when running the handler.
-     * The interruptible state is inherited from the context of the
-     * catch frame.
     */
     StgTSO_flags(CurrentTSO) = %lobits32(
-	TO_W_(StgTSO_flags(CurrentTSO)) | TSO_BLOCKEX);
-    if ((StgCatchFrame_exceptions_blocked(frame) & TSO_INTERRUPTIBLE) == 0) {
+        TO_W_(StgTSO_flags(CurrentTSO)) | TSO_BLOCKEX | TSO_INTERRUPTIBLE);
+
+    /* The interruptible state is inherited from the context of the
+     * catch frame, but note that TSO_INTERRUPTIBLE is only meaningful
+     * if TSO_BLOCKEX is set.  (we got this wrong earlier, and #4988
+     * was a symptom of the bug).
+     */
+    if ((StgCatchFrame_exceptions_blocked(frame) &
+         (TSO_BLOCKEX | TSO_INTERRUPTIBLE)) == TSO_BLOCKEX) {
         StgTSO_flags(CurrentTSO) = %lobits32(
             TO_W_(StgTSO_flags(CurrentTSO)) & ~TSO_INTERRUPTIBLE);
-    } else {
-        StgTSO_flags(CurrentTSO) = %lobits32(
-            TO_W_(StgTSO_flags(CurrentTSO)) | TSO_INTERRUPTIBLE);
     }
 
     /* Call the handler, passing the exception value and a realworld





More information about the Cvs-ghc mailing list