summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicholas Clark <nick@ccl4.org>2012-04-14 15:51:33 +0200
committerTony Cook <tony@develop-help.com>2013-07-23 10:57:34 +1000
commitfd430c957778442c853fd86b2357454f503f9168 (patch)
tree0a6928039028154208d886d8e6340177fc83b68c
parent33ae92800c7109b9839b913dad685cefdf6c38ff (diff)
downloadperl-fd430c957778442c853fd86b2357454f503f9168.tar.gz
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. Conflicts: scope.c
-rw-r--r--dump.c1
-rw-r--r--pp_ctl.c11
-rw-r--r--run.c1
-rw-r--r--scope.c2
4 files changed, 12 insertions, 3 deletions
diff --git a/dump.c b/dump.c
index b238ee0cb1..d770a6541c 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 7a8c79760a..dd4027893d 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);
}
@@ -5128,10 +5134,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 7c1d0aa8cc..774852d4c0 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 ffd0552ac3..121d1f7343 100644
--- a/scope.c
+++ b/scope.c
@@ -1168,8 +1168,6 @@ Perl_leave_scope(pTHX_ I32 base)
}
PL_tainted = was;
-
- PERL_ASYNC_CHECK();
}
void