734417
From 13716dc35cd0869b98bd30cebbdeb8d48ab07a8b Mon Sep 17 00:00:00 2001
734417
From: Nicholas Clark <nick@ccl4.org>
734417
Date: Sat, 14 Apr 2012 15:51:33 +0200
734417
Subject: [PATCH] Remove PERL_ASYNC_CHECK() from Perl_leave_scope().
734417
734417
PERL_ASYNC_CHECK() was added to Perl_leave_scope() as part of commit
734417
f410a2119920dd04, which moved signal dispatch from the runloop to
734417
control flow ops, to mitigate nearly all of the speed cost of safe
734417
signals.
734417
734417
The assumption was that scope exit was a safe place to dispatch signals.
734417
However, this is not true, as parts of the regex engine call
734417
leave_scope(), the regex engine stores some state in per-interpreter
734417
variables, and code called within signal handlers can change these
734417
values.
734417
734417
Hence remove the call to PERL_ASYNC_CHECK() from Perl_leave_scope(), and
734417
add it explicitly in the various OPs which were relying on their call to
734417
leave_scope() to dispatch any pending signals. Also add a
734417
PERL_ASYNC_CHECK() to the exit of the runloop, which ensures signals
734417
still dispatch from S_sortcv() and S_sortcv_stacked(), as well as
734417
addressing one of the concerns in the commit message of
734417
f410a2119920dd04:
734417
734417
    Subtle bugs might remain - there might be constructions that enter
734417
    the runloop (where signals used to be dispatched) but don't contain
734417
    any PERL_ASYNC_CHECK() calls themselves.
734417
734417
Finally, move the PERL_ASYNC_CHECK(); added by that commit to pp_goto to
734417
the end of the function, to be consistent with the positioning of all
734417
other PERL_ASYNC_CHECK() calls - at the beginning or end of OP
734417
functions, hence just before the return to or just after the call from
734417
the runloop, and hence effectively at the same point as the previous
734417
location of PERL_ASYNC_CHECK() in the runloop.
734417
---
734417
 dump.c   |  1 +
734417
 pp_ctl.c | 11 ++++++++++-
734417
 run.c    |  1 +
734417
 scope.c  |  2 --
734417
 4 files changed, 12 insertions(+), 3 deletions(-)
734417
734417
diff --git a/dump.c b/dump.c
734417
index b238ee0..d770a65 100644
734417
--- a/dump.c
734417
+++ b/dump.c
734417
@@ -2118,6 +2118,7 @@ Perl_runops_debug(pTHX)
734417
 	}
734417
     } while ((PL_op = PL_op->op_ppaddr(aTHX)));
734417
     DEBUG_l(Perl_deb(aTHX_ "leaving RUNOPS level\n"));
734417
+    PERL_ASYNC_CHECK();
734417
 
734417
     TAINT_NOT;
734417
     return 0;
734417
diff --git a/pp_ctl.c b/pp_ctl.c
734417
index fd92efa..6206a25 100644
734417
--- a/pp_ctl.c
734417
+++ b/pp_ctl.c
734417
@@ -377,6 +377,7 @@ PP(pp_substcont)
734417
 	    TAINT_NOT;
734417
 	    LEAVE_SCOPE(cx->sb_oldsave);
734417
 	    POPSUBST(cx);
734417
+	    PERL_ASYNC_CHECK();
734417
 	    RETURNOP(pm->op_next);
734417
 	    /* NOTREACHED */
734417
 	}
734417
@@ -2732,6 +2733,7 @@ PP(pp_next)
734417
     if (PL_scopestack_ix < inner)
734417
 	leave_scope(PL_scopestack[PL_scopestack_ix]);
734417
     PL_curcop = cx->blk_oldcop;
734417
+    PERL_ASYNC_CHECK();
734417
     return (cx)->blk_loop.my_op->op_nextop;
734417
 }
734417
 
734417
@@ -2774,6 +2776,7 @@ PP(pp_redo)
734417
     LEAVE_SCOPE(oldsave);
734417
     FREETMPS;
734417
     PL_curcop = cx->blk_oldcop;
734417
+    PERL_ASYNC_CHECK();
734417
     return redo_op;
734417
 }
734417
 
734417
@@ -2978,6 +2981,7 @@ PP(pp_goto)
734417
 		PUTBACK;
734417
 		(void)(*CvXSUB(cv))(aTHX_ cv);
734417
 		LEAVE;
734417
+		PERL_ASYNC_CHECK();
734417
 		return retop;
734417
 	    }
734417
 	    else {
734417
@@ -3049,6 +3053,7 @@ PP(pp_goto)
734417
 			}
734417
 		    }
734417
 		}
734417
+		PERL_ASYNC_CHECK();
734417
 		RETURNOP(CvSTART(cv));
734417
 	    }
734417
 	}
734417
@@ -3209,6 +3214,7 @@ PP(pp_goto)
734417
 	PL_do_undump = FALSE;
734417
     }
734417
 
734417
+    PERL_ASYNC_CHECK();
734417
     RETURNOP(retop);
734417
 }
734417
 
734417
@@ -5129,10 +5135,13 @@ PP(pp_leavewhen)
734417
 	    leave_scope(PL_scopestack[PL_scopestack_ix]);
734417
 	PL_curcop = cx->blk_oldcop;
734417
 
734417
+	PERL_ASYNC_CHECK();
734417
 	return cx->blk_loop.my_op->op_nextop;
734417
     }
734417
-    else
734417
+    else {
734417
+	PERL_ASYNC_CHECK();
734417
 	RETURNOP(cx->blk_givwhen.leave_op);
734417
+    }
734417
 }
734417
 
734417
 PP(pp_continue)
734417
diff --git a/run.c b/run.c
734417
index 7c1d0aa..774852d 100644
734417
--- a/run.c
734417
+++ b/run.c
734417
@@ -40,6 +40,7 @@ Perl_runops_standard(pTHX)
734417
     register OP *op = PL_op;
734417
     while ((PL_op = op = op->op_ppaddr(aTHX))) {
734417
     }
734417
+    PERL_ASYNC_CHECK();
734417
 
734417
     TAINT_NOT;
734417
     return 0;
734417
diff --git a/scope.c b/scope.c
734417
index ffd0552..121d1f7 100644
734417
--- a/scope.c
734417
+++ b/scope.c
734417
@@ -1168,8 +1168,6 @@ Perl_leave_scope(pTHX_ I32 base)
734417
     }
734417
 
734417
     PL_tainted = was;
734417
-
734417
-    PERL_ASYNC_CHECK();
734417
 }
734417
 
734417
 void
734417
-- 
734417
1.8.1.4
734417