Fix trashing of the masking state in STM (#5238)
authorSimon Marlow <marlowsd@gmail.com>
Wed, 16 Nov 2011 14:21:49 +0000 (14:21 +0000)
committerSimon Marlow <marlowsd@gmail.com>
Wed, 16 Nov 2011 15:51:59 +0000 (15:51 +0000)
rts/Exception.cmm

index 586086e..1192db7 100644 (file)
@@ -543,13 +543,32 @@ retry_pop_stack:
      */
     W_ frame;
     frame = Sp;
      */
     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;
       }
       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);
       W_ trec, outer;
       trec = StgTSO_trec(CurrentTSO);
       outer  = StgTRecHeader_enclosing_trec(trec);
@@ -559,22 +578,6 @@ retry_pop_stack:
       Sp = Sp + SIZEOF_StgCatchSTMFrame;
     }
 
       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.
      */
     /* Call the handler, passing the exception value and a realworld
      * token as arguments.
      */