diff options
author | Simon Marlow <marlowsd@gmail.com> | 2011-11-16 14:21:49 +0000 |
---|---|---|
committer | Simon Marlow <marlowsd@gmail.com> | 2011-11-16 15:51:59 +0000 |
commit | 66265ae0970b9d36b8847b75e176f0de4844690e (patch) | |
tree | c4a7c49df85a4f0b8c154ade82b974c9b120b4e8 /rts/Exception.cmm | |
parent | bea3992c71be47db7f2fc53f3e358212d1539706 (diff) | |
download | haskell-66265ae0970b9d36b8847b75e176f0de4844690e.tar.gz |
Fix trashing of the masking state in STM (#5238)
Diffstat (limited to 'rts/Exception.cmm')
-rw-r--r-- | rts/Exception.cmm | 39 |
1 files changed, 21 insertions, 18 deletions
diff --git a/rts/Exception.cmm b/rts/Exception.cmm index 586086ebf3..1192db732c 100644 --- a/rts/Exception.cmm +++ b/rts/Exception.cmm @@ -543,13 +543,32 @@ retry_pop_stack: */ W_ frame; frame = Sp; - if (frame_type == CATCH_FRAME) { + if (frame_type == CATCH_FRAME) + { Sp = Sp + SIZEOF_StgCatchFrame; if ((StgCatchFrame_exceptions_blocked(frame) & TSO_BLOCKEX) == 0) { Sp_adj(-1); Sp(0) = stg_unmaskAsyncExceptionszh_ret_info; } - } else { + + /* Ensure that async excpetions are blocked when running the handler. + */ + StgTSO_flags(CurrentTSO) = %lobits32( + 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 /* CATCH_STM_FRAME */ + { W_ trec, outer; trec = StgTSO_trec(CurrentTSO); outer = StgTRecHeader_enclosing_trec(trec); @@ -559,22 +578,6 @@ retry_pop_stack: Sp = Sp + SIZEOF_StgCatchSTMFrame; } - /* Ensure that async excpetions are blocked when running the handler. - */ - StgTSO_flags(CurrentTSO) = %lobits32( - 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); - } - /* Call the handler, passing the exception value and a realworld * token as arguments. */ |