mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1162013. Process the Promise queue between adjacent setTimeout callback invocations when we're going through the callback list without returning to the event loop. r=smaug
This commit is contained in:
parent
8622ce8c8b
commit
1faf3d6765
@ -12447,6 +12447,11 @@ nsGlobalWindow::RunTimeoutHandler(nsTimeout* aTimeout,
|
||||
|
||||
mRunningTimeout = last_running_timeout;
|
||||
timeout->mRunning = false;
|
||||
|
||||
// Since we might be processing more timeouts, go ahead and flush the promise
|
||||
// queue now before we do that.
|
||||
Promise::PerformMicroTaskCheckpoint();
|
||||
|
||||
return timeout->mCleared;
|
||||
}
|
||||
|
||||
@ -12566,14 +12571,17 @@ nsGlobalWindow::RunTimeout(nsTimeout *aTimeout)
|
||||
deadline = now;
|
||||
}
|
||||
|
||||
// The timeout list is kept in deadline order. Discover the latest
|
||||
// timeout whose deadline has expired. On some platforms, native
|
||||
// timeout events fire "early", so we need to test the timer as well
|
||||
// as the deadline.
|
||||
// The timeout list is kept in deadline order. Discover the latest timeout
|
||||
// whose deadline has expired. On some platforms, native timeout events fire
|
||||
// "early", but we handled that above by setting deadline to aTimeout->mWhen
|
||||
// if the timer fired early. So we can stop walking if we get to timeouts
|
||||
// whose mWhen is greater than deadline, since once that happens we know
|
||||
// nothing past that point is expired.
|
||||
last_expired_timeout = nullptr;
|
||||
for (nsTimeout *timeout = mTimeouts.getFirst(); timeout; timeout = timeout->getNext()) {
|
||||
if (((timeout == aTimeout) || (timeout->mWhen <= deadline)) &&
|
||||
(timeout->mFiringDepth == 0)) {
|
||||
for (nsTimeout *timeout = mTimeouts.getFirst();
|
||||
timeout && timeout->mWhen <= deadline;
|
||||
timeout = timeout->getNext()) {
|
||||
if (timeout->mFiringDepth == 0) {
|
||||
// Mark any timeouts that are on the list to be fired with the
|
||||
// firing depth so that we can reentrantly run timeouts
|
||||
timeout->mFiringDepth = firingDepth;
|
||||
|
18
dom/promise/tests/file_promise_and_timeout_ordering.js
Normal file
18
dom/promise/tests/file_promise_and_timeout_ordering.js
Normal file
@ -0,0 +1,18 @@
|
||||
var log = [];
|
||||
var resolvedPromise = Promise.resolve(null);
|
||||
function schedulePromiseTask(f) {
|
||||
resolvedPromise.then(f);
|
||||
}
|
||||
|
||||
setTimeout(function() {
|
||||
log.push('t1start');
|
||||
schedulePromiseTask(function() {
|
||||
log.push('promise');
|
||||
});
|
||||
log.push('t1end');
|
||||
}, 10);
|
||||
|
||||
setTimeout(function() {
|
||||
log.push('t2');
|
||||
postMessage(log.join(', '));
|
||||
}, 10);
|
@ -7,3 +7,7 @@
|
||||
[test_resolve.html]
|
||||
[test_resolver_return_value.html]
|
||||
[test_thenable_vs_promise_ordering.html]
|
||||
[test_promise_and_timeout_ordering.html]
|
||||
support-files = file_promise_and_timeout_ordering.js
|
||||
[test_promise_and_timeout_ordering_workers.html]
|
||||
support-files = file_promise_and_timeout_ordering.js
|
||||
|
15
dom/promise/tests/test_promise_and_timeout_ordering.html
Normal file
15
dom/promise/tests/test_promise_and_timeout_ordering.html
Normal file
@ -0,0 +1,15 @@
|
||||
<!DOCTYPE html>
|
||||
<meta charset=utf-8>
|
||||
<title>Test for promise and timeout ordering</title>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<div id="log"></div>
|
||||
<script>
|
||||
var t = async_test("Promise callbacks should run immediately after the setTimeout handler that enqueues them");
|
||||
var origPostMessage = window.postMessage;
|
||||
window.postMessage = function(msg) { origPostMessage.call(window, msg, "*"); }
|
||||
window.onmessage = t.step_func_done(function(e) {
|
||||
assert_equals(e.data, "t1start, t1end, promise, t2");
|
||||
});
|
||||
</script>
|
||||
<script src="file_promise_and_timeout_ordering.js"></script>
|
@ -0,0 +1,13 @@
|
||||
<!DOCTYPE html>
|
||||
<meta charset=utf-8>
|
||||
<title>Test for promise and timeout ordering in workers</title>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<div id="log"></div>
|
||||
<script>
|
||||
var t = async_test("Promise callbacks in workers should run immediately after the setTimeout handler that enqueues them");
|
||||
var w = new Worker("file_promise_and_timeout_ordering.js");
|
||||
w.onmessage = t.step_func_done(function(e) {
|
||||
assert_equals(e.data, "t1start, t1end, promise, t2");
|
||||
});
|
||||
</script>
|
@ -6745,6 +6745,10 @@ WorkerPrivate::RunExpiredTimeouts(JSContext* aCx)
|
||||
}
|
||||
}
|
||||
|
||||
// Since we might be processing more timeouts, go ahead and flush
|
||||
// the promise queue now before we do that.
|
||||
Promise::PerformMicroTaskCheckpoint();
|
||||
|
||||
NS_ASSERTION(mRunningExpiredTimeouts, "Someone changed this!");
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user