summaryrefslogtreecommitdiff
path: root/rts/Exception.cmm
diff options
context:
space:
mode:
authorSimon Marlow <marlowsd@gmail.com>2011-08-31 22:45:01 +0100
committerSimon Marlow <marlowsd@gmail.com>2011-09-01 11:14:38 +0100
commitfa71e6c795489ec267e0d048395c2c52bea6a164 (patch)
tree5ce4ab12c347e28f51a6100395311bdbdadc42a2 /rts/Exception.cmm
parentc27df60d69ad54a69723510c57e238f31a59c532 (diff)
downloadhaskell-fa71e6c795489ec267e0d048395c2c52bea6a164.tar.gz
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.
Diffstat (limited to 'rts/Exception.cmm')
-rw-r--r--rts/Exception.cmm16
1 files changed, 9 insertions, 7 deletions
diff --git a/rts/Exception.cmm b/rts/Exception.cmm
index 24da1c690e..591fa7ab9b 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