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