timers: fixing API refs to use safe internal refs
Added safe internal references for 'clearTimeout(..)', 'active(..)', and 'unenroll(..)'. Changed various API refs from 'export.*' to use these safe internal references. Now, overwriting the global API identifiers does not create potential breakage and/or race conditions. See Issue #2493. PR-URL: https://github.com/nodejs/node/pull/5882 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Jeremiah Senkpiel <fishrock123@rocketmail.com> Fixes: https://github.com/nodejs/node/issues/2493
This commit is contained in:
parent
a17200b520
commit
9fa25c8ca0
@ -100,7 +100,7 @@ const unrefedLists = {};
|
|||||||
|
|
||||||
// Schedule or re-schedule a timer.
|
// Schedule or re-schedule a timer.
|
||||||
// The item must have been enroll()'d first.
|
// The item must have been enroll()'d first.
|
||||||
exports.active = function(item) {
|
const active = exports.active = function(item) {
|
||||||
insert(item, false);
|
insert(item, false);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -351,19 +351,19 @@ exports.setTimeout = function(callback, after) {
|
|||||||
|
|
||||||
if (process.domain) timer.domain = process.domain;
|
if (process.domain) timer.domain = process.domain;
|
||||||
|
|
||||||
exports.active(timer);
|
active(timer);
|
||||||
|
|
||||||
return timer;
|
return timer;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
exports.clearTimeout = function(timer) {
|
const clearTimeout = exports.clearTimeout = function(timer) {
|
||||||
if (timer && (timer[kOnTimeout] || timer._onTimeout)) {
|
if (timer && (timer[kOnTimeout] || timer._onTimeout)) {
|
||||||
timer[kOnTimeout] = timer._onTimeout = null;
|
timer[kOnTimeout] = timer._onTimeout = null;
|
||||||
if (timer instanceof Timeout) {
|
if (timer instanceof Timeout) {
|
||||||
timer.close(); // for after === 0
|
timer.close(); // for after === 0
|
||||||
} else {
|
} else {
|
||||||
exports.unenroll(timer);
|
unenroll(timer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -409,7 +409,7 @@ exports.setInterval = function(callback, repeat) {
|
|||||||
timer._repeat = ontimeout;
|
timer._repeat = ontimeout;
|
||||||
|
|
||||||
if (process.domain) timer.domain = process.domain;
|
if (process.domain) timer.domain = process.domain;
|
||||||
exports.active(timer);
|
active(timer);
|
||||||
|
|
||||||
return timer;
|
return timer;
|
||||||
|
|
||||||
@ -425,7 +425,7 @@ exports.setInterval = function(callback, repeat) {
|
|||||||
this._handle.start(repeat, 0);
|
this._handle.start(repeat, 0);
|
||||||
} else {
|
} else {
|
||||||
timer._idleTimeout = repeat;
|
timer._idleTimeout = repeat;
|
||||||
exports.active(timer);
|
active(timer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -468,7 +468,7 @@ Timeout.prototype.unref = function() {
|
|||||||
|
|
||||||
// Prevent running cb again when unref() is called during the same cb
|
// Prevent running cb again when unref() is called during the same cb
|
||||||
if (this._called && !this._repeat) {
|
if (this._called && !this._repeat) {
|
||||||
exports.unenroll(this);
|
unenroll(this);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -496,7 +496,7 @@ Timeout.prototype.close = function() {
|
|||||||
this._handle[kOnTimeout] = null;
|
this._handle[kOnTimeout] = null;
|
||||||
this._handle.close();
|
this._handle.close();
|
||||||
} else {
|
} else {
|
||||||
exports.unenroll(this);
|
unenroll(this);
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
|
20
test/parallel/test-timers-api-refs.js
Normal file
20
test/parallel/test-timers-api-refs.js
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
'use strict';
|
||||||
|
const common = require('../common');
|
||||||
|
const assert = require('assert');
|
||||||
|
|
||||||
|
// don't verify the globals for this test
|
||||||
|
common.globalCheck = false;
|
||||||
|
|
||||||
|
// try overriding global APIs to make sure
|
||||||
|
// they're not relied on by the timers
|
||||||
|
global.clearTimeout = assert.fail;
|
||||||
|
|
||||||
|
// run timeouts/intervals through the paces
|
||||||
|
const intv = setInterval(function() {}, 1);
|
||||||
|
|
||||||
|
setTimeout(function() {
|
||||||
|
clearInterval(intv);
|
||||||
|
}, 100);
|
||||||
|
|
||||||
|
setTimeout(function() {}, 2);
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user