зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1646799 - setInterval(..., 0) is not clamped, unlike setTimeout(..., 0), r=peterv
Differential Revision: https://phabricator.services.mozilla.com/D84395
This commit is contained in:
Родитель
08df665966
Коммит
9d7df9a34d
|
@ -299,8 +299,7 @@ bool TimeoutManager::IsInvalidFiringId(uint32_t aFiringId) const {
|
|||
return !mFiringIdStack.Contains(aFiringId);
|
||||
}
|
||||
|
||||
// The number of nested timeouts before we start clamping. HTML5 says 1, WebKit
|
||||
// uses 5.
|
||||
// The number of nested timeouts before we start clamping. HTML says 5.
|
||||
#define DOM_CLAMP_TIMEOUT_NESTING_LEVEL 5u
|
||||
|
||||
TimeDuration TimeoutManager::CalculateDelay(Timeout* aTimeout) const {
|
||||
|
|
|
@ -5960,12 +5960,8 @@ bool nsGlobalWindowInner::RunTimeoutHandler(Timeout* aTimeout,
|
|||
// timeouts from repeatedly opening poups.
|
||||
timeout->mPopupState = PopupBlocker::openAbused;
|
||||
|
||||
bool trackNestingLevel = !timeout->mIsInterval;
|
||||
uint32_t nestingLevel;
|
||||
if (trackNestingLevel) {
|
||||
nestingLevel = TimeoutManager::GetNestingLevel();
|
||||
TimeoutManager::SetNestingLevel(timeout->mNestingLevel);
|
||||
}
|
||||
uint32_t nestingLevel = TimeoutManager::GetNestingLevel();
|
||||
TimeoutManager::SetNestingLevel(timeout->mNestingLevel);
|
||||
|
||||
const char* reason = GetTimeoutReasonString(timeout);
|
||||
|
||||
|
@ -6016,9 +6012,7 @@ bool nsGlobalWindowInner::RunTimeoutHandler(Timeout* aTimeout,
|
|||
// point anyway, and the script context should have already reported
|
||||
// the script error in the usual way - so we just drop it.
|
||||
|
||||
if (trackNestingLevel) {
|
||||
TimeoutManager::SetNestingLevel(nestingLevel);
|
||||
}
|
||||
TimeoutManager::SetNestingLevel(nestingLevel);
|
||||
|
||||
mTimeoutManager->EndRunningTimeout(last_running_timeout);
|
||||
timeout->mRunning = false;
|
||||
|
|
|
@ -56,6 +56,36 @@ function delayByInterval(iterations) {
|
|||
});
|
||||
}
|
||||
|
||||
function testNestedIntervals() {
|
||||
return new Promise(resolve => {
|
||||
const runCount = 100;
|
||||
let counter = 0;
|
||||
let intervalId = 0;
|
||||
let prevInitTime = performance.now();
|
||||
let totalTime = 0;
|
||||
function intervalCallback() {
|
||||
let now = performance.now();
|
||||
let delay = now - prevInitTime;
|
||||
totalTime += delay;
|
||||
prevInitTime = now;
|
||||
clearInterval(intervalId);
|
||||
if (++counter < runCount) {
|
||||
intervalId = setInterval(intervalCallback, 0);
|
||||
} else {
|
||||
// Delays should be clamped to 4ms after the initial calls, but allow
|
||||
// some fuzziness, so divide by 2.
|
||||
let expectedTime = runCount * 4 / 2;
|
||||
ok(totalTime > expectedTime, "Should not run callbacks too fast.");
|
||||
resolve();
|
||||
}
|
||||
}
|
||||
|
||||
// Use the timeout value defined in the spec, 4ms.
|
||||
SpecialPowers.pushPrefEnv({ 'set': [["dom.min_timeout_value", 4]]},
|
||||
intervalCallback);
|
||||
});
|
||||
}
|
||||
|
||||
// Use a very long clamp delay to make it easier to measure the change
|
||||
// in automation. Some of our test servers are very slow and noisy.
|
||||
const clampDelayMS = 10000;
|
||||
|
@ -92,7 +122,7 @@ async function runTests() {
|
|||
|
||||
await clearNestingLevel();
|
||||
|
||||
// Verfy a setTimeout() chain will continue to clamp past the first
|
||||
// Verify a setTimeout() chain will continue to clamp past the first
|
||||
// expected iteration.
|
||||
const expectedDelay = (1 + expectedClampIteration) * clampDelayMS;
|
||||
|
||||
|
@ -105,7 +135,7 @@ async function runTests() {
|
|||
|
||||
await clearNestingLevel();
|
||||
|
||||
// Verfy setInterval() will continue to clamp past the first expected
|
||||
// Verify setInterval() will continue to clamp past the first expected
|
||||
// iteration.
|
||||
start = performance.now();
|
||||
await delayByTimeoutChain(2 * expectedClampIteration);
|
||||
|
@ -114,6 +144,8 @@ async function runTests() {
|
|||
|
||||
ok(delta >= expectedDelay, "setInterval() continued to clamp: " + stop + " - " + start + " = " + delta);
|
||||
|
||||
await testNestedIntervals();
|
||||
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче