diff options
author | Simon Marlow <marlowsd@gmail.com> | 2011-08-31 22:45:01 +0100 |
---|---|---|
committer | Simon Marlow <marlowsd@gmail.com> | 2011-09-01 11:14:38 +0100 |
commit | fa71e6c795489ec267e0d048395c2c52bea6a164 (patch) | |
tree | 5ce4ab12c347e28f51a6100395311bdbdadc42a2 /rts/Exception.cmm | |
parent | c27df60d69ad54a69723510c57e238f31a59c532 (diff) | |
download | haskell-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.cmm | 16 |
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 |