From 63e2cde7a259256a0e4925611ae8184bc4da68a4 Mon Sep 17 00:00:00 2001
From: Simon Marlow <marlowsd@gmail.com>
Date: Wed, 31 Aug 2011 22:45:01 +0100
Subject: [PATCH] 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 file changed, 9 insertions(+), 7 deletions(-)

diff --git a/rts/Exception.cmm b/rts/Exception.cmm
index 24da1c690e50..591fa7ab9bc7 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
-- 
GitLab