mirror of
https://github.com/nodejs/node.git
synced 2026-10-14 10:26:26 -04:00
timer,domain: maintain order of timer callbacks
PR-URL: https://github.com/nodejs/node/pull/10522 Fixes: https://github.com/nodejs/node/issues/1271 Reviewed-By: Sam Roberts <vieuxtech@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Gibson Fahnestock <gibfahn@gmail.com> Reviewed-By: Jeremiah Senkpiel <fishrock123@rocketmail.com>
This commit is contained in:
1 parent
5a42cd1505
commit
9dac165160
2 files changed
+40
No files matched your search
@@ -156,12 +156,19 @@ function TimersList(msecs, unrefed) {
|
||||
this._timer = new TimerWrap();
|
||||
this._unrefed = unrefed;
|
||||
this.msecs = msecs;
|
||||
this.nextTick = false;
|
||||
}
|
||||
|
||||
function listOnTimeout() {
|
||||
var list = this._list;
|
||||
var msecs = list.msecs;
|
||||
|
||||
if (list.nextTick) {
|
||||
list.nextTick = false;
|
||||
process.nextTick(listOnTimeoutNT, list);
|
||||
return;
|
||||
}
|
||||
|
||||
debug('timeout callback %d', msecs);
|
||||
|
||||
var now = TimerWrap.now();
|
||||
@@ -239,6 +246,14 @@ function tryOnTimeout(timer, list) {
|
||||
} finally {
|
||||
if (!threw) return;
|
||||
|
||||
// Postpone all later list events to next tick. We need to do this
|
||||
// so that the events are called in the order they were created.
|
||||
const lists = list._unrefed === true ? unrefedLists : refedLists;
|
||||
for (var key in lists) {
|
||||
if (key > list.msecs) {
|
||||
lists[key].nextTick = true;
|
||||
}
|
||||
}
|
||||
// We need to continue processing after domain error handling
|
||||
// is complete, but not by using whatever domain was left over
|
||||
// when the timeout threw its exception.
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
'use strict';
|
||||
const common = require('../common');
|
||||
|
||||
// This test ensures that the timer callbacks are called in the order in which
|
||||
// they were created in the event of an unhandled exception in the domain.
|
||||
|
||||
const domain = require('domain').create();
|
||||
const assert = require('assert');
|
||||
|
||||
let first = false;
|
||||
|
||||
domain.run(function() {
|
||||
setTimeout(() => { throw new Error('FAIL'); }, 1);
|
||||
setTimeout(() => { first = true; }, 1);
|
||||
setTimeout(() => { assert.strictEqual(first, true); }, 2);
|
||||
|
||||
// Ensure that 2 ms have really passed
|
||||
let i = 1e6;
|
||||
while (i--);
|
||||
});
|
||||
|
||||
domain.once('error', common.mustCall((err) => {
|
||||
assert(err);
|
||||
assert.strictEqual(err.message, 'FAIL');
|
||||
}));
|
||||
Reference in new issue
Block a user