async_hooks: consistent internal naming
PR-URL: https://github.com/nodejs/node/pull/15569 Reviewed-By: Refael Ackermann <refack@gmail.com> Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de> Reviewed-By: James M Snell <jasnell@gmail.com>
This commit is contained in:
parent
f9e5709ea0
commit
3a69ef55e0
@ -6,20 +6,21 @@ const errors = require('internal/errors');
|
|||||||
* Environment::AsyncHooks::fields_[]. Each index tracks the number of active
|
* Environment::AsyncHooks::fields_[]. Each index tracks the number of active
|
||||||
* hooks for each type.
|
* hooks for each type.
|
||||||
*
|
*
|
||||||
* async_uid_fields is a Float64Array wrapping the double array of
|
* async_id_fields is a Float64Array wrapping the double array of
|
||||||
* Environment::AsyncHooks::uid_fields_[]. Each index contains the ids for the
|
* Environment::AsyncHooks::uid_fields_[]. Each index contains the ids for the
|
||||||
* various asynchronous states of the application. These are:
|
* various asynchronous states of the application. These are:
|
||||||
* kCurrentAsyncId: The async_id assigned to the resource responsible for the
|
* kExecutionAsyncId: The async_id assigned to the resource responsible for the
|
||||||
* current execution stack.
|
* current execution stack.
|
||||||
* kCurrentTriggerId: The trigger_async_id of the resource responsible for the
|
* kTriggerAsyncId: The trigger_async_id of the resource responsible for
|
||||||
* current execution stack.
|
* the current execution stack.
|
||||||
* kAsyncUidCntr: Incremental counter tracking the next assigned async_id.
|
* kAsyncIdCounter: Incremental counter tracking the next assigned async_id.
|
||||||
* kInitTriggerId: Written immediately before a resource's constructor that
|
* kInitTriggerAsyncId: Written immediately before a resource's constructor
|
||||||
* sets the value of the init()'s triggerAsyncId. The order of retrieving
|
* that sets the value of the init()'s triggerAsyncId. The order of
|
||||||
* the triggerAsyncId value is passing directly to the constructor -> value
|
* retrieving the triggerAsyncId value is passing directly to the
|
||||||
* set in kInitTriggerId -> executionAsyncId of the current resource.
|
* constructor -> value set in kInitTriggerAsyncId -> executionAsyncId of
|
||||||
|
* the current resource.
|
||||||
*/
|
*/
|
||||||
const { async_hook_fields, async_uid_fields } = async_wrap;
|
const { async_hook_fields, async_id_fields } = async_wrap;
|
||||||
// Store the pair executionAsyncId and triggerAsyncId in a std::stack on
|
// Store the pair executionAsyncId and triggerAsyncId in a std::stack on
|
||||||
// Environment::AsyncHooks::ids_stack_ tracks the resource responsible for the
|
// Environment::AsyncHooks::ids_stack_ tracks the resource responsible for the
|
||||||
// current execution stack. This is unwound as each resource exits. In the case
|
// current execution stack. This is unwound as each resource exits. In the case
|
||||||
@ -58,14 +59,14 @@ const active_hooks = {
|
|||||||
// Each constant tracks how many callbacks there are for any given step of
|
// Each constant tracks how many callbacks there are for any given step of
|
||||||
// async execution. These are tracked so if the user didn't include callbacks
|
// async execution. These are tracked so if the user didn't include callbacks
|
||||||
// for a given step, that step can bail out early.
|
// for a given step, that step can bail out early.
|
||||||
const { kInit, kBefore, kAfter, kDestroy, kPromiseResolve, kTotals,
|
const { kInit, kBefore, kAfter, kDestroy, kTotals, kPromiseResolve,
|
||||||
kCurrentAsyncId, kCurrentTriggerId, kAsyncUidCntr,
|
kExecutionAsyncId, kTriggerAsyncId, kAsyncIdCounter,
|
||||||
kInitTriggerId } = async_wrap.constants;
|
kInitTriggerAsyncId } = async_wrap.constants;
|
||||||
|
|
||||||
// Symbols used to store the respective ids on both AsyncResource instances and
|
// Symbols used to store the respective ids on both AsyncResource instances and
|
||||||
// internal resources. They will also be assigned to arbitrary objects passed
|
// internal resources. They will also be assigned to arbitrary objects passed
|
||||||
// in by the user that take place of internally constructed objects.
|
// in by the user that take place of internally constructed objects.
|
||||||
const { async_id_symbol, trigger_id_symbol } = async_wrap;
|
const { async_id_symbol, trigger_async_id_symbol } = async_wrap;
|
||||||
|
|
||||||
// Used in AsyncHook and AsyncResource.
|
// Used in AsyncHook and AsyncResource.
|
||||||
const init_symbol = Symbol('init');
|
const init_symbol = Symbol('init');
|
||||||
@ -234,12 +235,12 @@ function createHook(fns) {
|
|||||||
|
|
||||||
|
|
||||||
function executionAsyncId() {
|
function executionAsyncId() {
|
||||||
return async_uid_fields[kCurrentAsyncId];
|
return async_id_fields[kExecutionAsyncId];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function triggerAsyncId() {
|
function triggerAsyncId() {
|
||||||
return async_uid_fields[kCurrentTriggerId];
|
return async_id_fields[kTriggerAsyncId];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -258,14 +259,16 @@ class AsyncResource {
|
|||||||
triggerAsyncId);
|
triggerAsyncId);
|
||||||
}
|
}
|
||||||
|
|
||||||
this[async_id_symbol] = ++async_uid_fields[kAsyncUidCntr];
|
this[async_id_symbol] = ++async_id_fields[kAsyncIdCounter];
|
||||||
this[trigger_id_symbol] = triggerAsyncId;
|
this[trigger_async_id_symbol] = triggerAsyncId;
|
||||||
|
|
||||||
emitInitScript(this[async_id_symbol], type, this[trigger_id_symbol], this);
|
emitInitScript(
|
||||||
|
this[async_id_symbol], type, this[trigger_async_id_symbol], this
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
emitBefore() {
|
emitBefore() {
|
||||||
emitBeforeScript(this[async_id_symbol], this[trigger_id_symbol]);
|
emitBeforeScript(this[async_id_symbol], this[trigger_async_id_symbol]);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -284,7 +287,7 @@ class AsyncResource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
triggerAsyncId() {
|
triggerAsyncId() {
|
||||||
return this[trigger_id_symbol];
|
return this[trigger_async_id_symbol];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -308,7 +311,7 @@ function runInAsyncIdScope(asyncId, cb) {
|
|||||||
// counter increment first. Since it's done the same way in
|
// counter increment first. Since it's done the same way in
|
||||||
// Environment::new_async_uid()
|
// Environment::new_async_uid()
|
||||||
function newUid() {
|
function newUid() {
|
||||||
return ++async_uid_fields[kAsyncUidCntr];
|
return ++async_id_fields[kAsyncIdCounter];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -316,20 +319,20 @@ function newUid() {
|
|||||||
// the user to safeguard this call and make sure it's zero'd out when the
|
// the user to safeguard this call and make sure it's zero'd out when the
|
||||||
// constructor is complete.
|
// constructor is complete.
|
||||||
function initTriggerId() {
|
function initTriggerId() {
|
||||||
var tId = async_uid_fields[kInitTriggerId];
|
var triggerAsyncId = async_id_fields[kInitTriggerAsyncId];
|
||||||
// Reset value after it's been called so the next constructor doesn't
|
// Reset value after it's been called so the next constructor doesn't
|
||||||
// inherit it by accident.
|
// inherit it by accident.
|
||||||
async_uid_fields[kInitTriggerId] = 0;
|
async_id_fields[kInitTriggerAsyncId] = 0;
|
||||||
if (tId <= 0)
|
if (triggerAsyncId <= 0)
|
||||||
tId = async_uid_fields[kCurrentAsyncId];
|
triggerAsyncId = async_id_fields[kExecutionAsyncId];
|
||||||
return tId;
|
return triggerAsyncId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function setInitTriggerId(triggerAsyncId) {
|
function setInitTriggerId(triggerAsyncId) {
|
||||||
// CHECK(Number.isSafeInteger(triggerAsyncId))
|
// CHECK(Number.isSafeInteger(triggerAsyncId))
|
||||||
// CHECK(triggerAsyncId > 0)
|
// CHECK(triggerAsyncId > 0)
|
||||||
async_uid_fields[kInitTriggerId] = triggerAsyncId;
|
async_id_fields[kInitTriggerAsyncId] = triggerAsyncId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -346,8 +349,9 @@ function emitInitScript(asyncId, type, triggerAsyncId, resource) {
|
|||||||
if (triggerAsyncId === null) {
|
if (triggerAsyncId === null) {
|
||||||
triggerAsyncId = initTriggerId();
|
triggerAsyncId = initTriggerId();
|
||||||
} else {
|
} else {
|
||||||
// If a triggerAsyncId was passed, any kInitTriggerId still must be null'd.
|
// If a triggerAsyncId was passed, any kInitTriggerAsyncId still must be
|
||||||
async_uid_fields[kInitTriggerId] = 0;
|
// null'd.
|
||||||
|
async_id_fields[kInitTriggerAsyncId] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Number.isSafeInteger(asyncId) || asyncId < -1) {
|
if (!Number.isSafeInteger(asyncId) || asyncId < -1) {
|
||||||
@ -446,7 +450,7 @@ function emitDestroyScript(asyncId) {
|
|||||||
// Return early if there are no destroy callbacks, or invalid asyncId.
|
// Return early if there are no destroy callbacks, or invalid asyncId.
|
||||||
if (async_hook_fields[kDestroy] === 0 || asyncId <= 0)
|
if (async_hook_fields[kDestroy] === 0 || asyncId <= 0)
|
||||||
return;
|
return;
|
||||||
async_wrap.addIdToDestroyList(asyncId);
|
async_wrap.queueDestroyAsyncId(asyncId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
17
lib/internal/bootstrap_node.js
vendored
17
lib/internal/bootstrap_node.js
vendored
@ -354,17 +354,18 @@
|
|||||||
function setupProcessFatal() {
|
function setupProcessFatal() {
|
||||||
const async_wrap = process.binding('async_wrap');
|
const async_wrap = process.binding('async_wrap');
|
||||||
// Arrays containing hook flags and ids for async_hook calls.
|
// Arrays containing hook flags and ids for async_hook calls.
|
||||||
const { async_hook_fields, async_uid_fields } = async_wrap;
|
const { async_hook_fields, async_id_fields } = async_wrap;
|
||||||
// Internal functions needed to manipulate the stack.
|
// Internal functions needed to manipulate the stack.
|
||||||
const { clearIdStack, asyncIdStackSize } = async_wrap;
|
const { clearAsyncIdStack, asyncIdStackSize } = async_wrap;
|
||||||
const { kAfter, kCurrentAsyncId, kInitTriggerId } = async_wrap.constants;
|
const { kAfter, kExecutionAsyncId,
|
||||||
|
kInitTriggerAsyncId } = async_wrap.constants;
|
||||||
|
|
||||||
process._fatalException = function(er) {
|
process._fatalException = function(er) {
|
||||||
var caught;
|
var caught;
|
||||||
|
|
||||||
// It's possible that kInitTriggerId was set for a constructor call that
|
// It's possible that kInitTriggerAsyncId was set for a constructor call
|
||||||
// threw and was never cleared. So clear it now.
|
// that threw and was never cleared. So clear it now.
|
||||||
async_uid_fields[kInitTriggerId] = 0;
|
async_id_fields[kInitTriggerAsyncId] = 0;
|
||||||
|
|
||||||
if (process.domain && process.domain._errorHandler)
|
if (process.domain && process.domain._errorHandler)
|
||||||
caught = process.domain._errorHandler(er);
|
caught = process.domain._errorHandler(er);
|
||||||
@ -392,11 +393,11 @@
|
|||||||
if (async_hook_fields[kAfter] > 0) {
|
if (async_hook_fields[kAfter] > 0) {
|
||||||
do {
|
do {
|
||||||
NativeModule.require('async_hooks').emitAfter(
|
NativeModule.require('async_hooks').emitAfter(
|
||||||
async_uid_fields[kCurrentAsyncId]);
|
async_id_fields[kExecutionAsyncId]);
|
||||||
} while (asyncIdStackSize() > 0);
|
} while (asyncIdStackSize() > 0);
|
||||||
// Or completely empty the id stack.
|
// Or completely empty the id stack.
|
||||||
} else {
|
} else {
|
||||||
clearIdStack();
|
clearAsyncIdStack();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,12 +54,12 @@ function setupNextTick() {
|
|||||||
const emitPendingUnhandledRejections = promises.setup(scheduleMicrotasks);
|
const emitPendingUnhandledRejections = promises.setup(scheduleMicrotasks);
|
||||||
const initTriggerId = async_hooks.initTriggerId;
|
const initTriggerId = async_hooks.initTriggerId;
|
||||||
// Two arrays that share state between C++ and JS.
|
// Two arrays that share state between C++ and JS.
|
||||||
const { async_hook_fields, async_uid_fields } = async_wrap;
|
const { async_hook_fields, async_id_fields } = async_wrap;
|
||||||
// Used to change the state of the async id stack.
|
// Used to change the state of the async id stack.
|
||||||
const { emitInit, emitBefore, emitAfter, emitDestroy } = async_hooks;
|
const { emitInit, emitBefore, emitAfter, emitDestroy } = async_hooks;
|
||||||
// Grab the constants necessary for working with internal arrays.
|
// Grab the constants necessary for working with internal arrays.
|
||||||
const { kInit, kDestroy, kAsyncUidCntr } = async_wrap.constants;
|
const { kInit, kDestroy, kAsyncIdCounter } = async_wrap.constants;
|
||||||
const { async_id_symbol, trigger_id_symbol } = async_wrap;
|
const { async_id_symbol, trigger_async_id_symbol } = async_wrap;
|
||||||
var nextTickQueue = new NextTickQueue();
|
var nextTickQueue = new NextTickQueue();
|
||||||
var microtasksScheduled = false;
|
var microtasksScheduled = false;
|
||||||
|
|
||||||
@ -102,7 +102,7 @@ function setupNextTick() {
|
|||||||
args: undefined,
|
args: undefined,
|
||||||
domain: null,
|
domain: null,
|
||||||
[async_id_symbol]: 0,
|
[async_id_symbol]: 0,
|
||||||
[trigger_id_symbol]: 0
|
[trigger_async_id_symbol]: 0
|
||||||
};
|
};
|
||||||
function scheduleMicrotasks() {
|
function scheduleMicrotasks() {
|
||||||
if (microtasksScheduled)
|
if (microtasksScheduled)
|
||||||
@ -158,10 +158,10 @@ function setupNextTick() {
|
|||||||
|
|
||||||
// CHECK(Number.isSafeInteger(tock[async_id_symbol]))
|
// CHECK(Number.isSafeInteger(tock[async_id_symbol]))
|
||||||
// CHECK(tock[async_id_symbol] > 0)
|
// CHECK(tock[async_id_symbol] > 0)
|
||||||
// CHECK(Number.isSafeInteger(tock[trigger_id_symbol]))
|
// CHECK(Number.isSafeInteger(tock[trigger_async_id_symbol]))
|
||||||
// CHECK(tock[trigger_id_symbol] > 0)
|
// CHECK(tock[trigger_async_id_symbol] > 0)
|
||||||
|
|
||||||
emitBefore(tock[async_id_symbol], tock[trigger_id_symbol]);
|
emitBefore(tock[async_id_symbol], tock[trigger_async_id_symbol]);
|
||||||
// emitDestroy() places the async_id_symbol into an asynchronous queue
|
// emitDestroy() places the async_id_symbol into an asynchronous queue
|
||||||
// that calls the destroy callback in the future. It's called before
|
// that calls the destroy callback in the future. It's called before
|
||||||
// calling tock.callback so destroy will be called even if the callback
|
// calling tock.callback so destroy will be called even if the callback
|
||||||
@ -203,10 +203,10 @@ function setupNextTick() {
|
|||||||
|
|
||||||
// CHECK(Number.isSafeInteger(tock[async_id_symbol]))
|
// CHECK(Number.isSafeInteger(tock[async_id_symbol]))
|
||||||
// CHECK(tock[async_id_symbol] > 0)
|
// CHECK(tock[async_id_symbol] > 0)
|
||||||
// CHECK(Number.isSafeInteger(tock[trigger_id_symbol]))
|
// CHECK(Number.isSafeInteger(tock[trigger_async_id_symbol]))
|
||||||
// CHECK(tock[trigger_id_symbol] > 0)
|
// CHECK(tock[trigger_async_id_symbol] > 0)
|
||||||
|
|
||||||
emitBefore(tock[async_id_symbol], tock[trigger_id_symbol]);
|
emitBefore(tock[async_id_symbol], tock[trigger_async_id_symbol]);
|
||||||
// TODO(trevnorris): See comment in _tickCallback() as to why this
|
// TODO(trevnorris): See comment in _tickCallback() as to why this
|
||||||
// isn't a good solution.
|
// isn't a good solution.
|
||||||
if (async_hook_fields[kDestroy] > 0)
|
if (async_hook_fields[kDestroy] > 0)
|
||||||
@ -236,7 +236,7 @@ function setupNextTick() {
|
|||||||
this.args = args;
|
this.args = args;
|
||||||
this.domain = process.domain || null;
|
this.domain = process.domain || null;
|
||||||
this[async_id_symbol] = asyncId;
|
this[async_id_symbol] = asyncId;
|
||||||
this[trigger_id_symbol] = triggerAsyncId;
|
this[trigger_async_id_symbol] = triggerAsyncId;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -261,7 +261,7 @@ function setupNextTick() {
|
|||||||
args[i - 1] = arguments[i];
|
args[i - 1] = arguments[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
const asyncId = ++async_uid_fields[kAsyncUidCntr];
|
const asyncId = ++async_id_fields[kAsyncIdCounter];
|
||||||
const triggerAsyncId = initTriggerId();
|
const triggerAsyncId = initTriggerId();
|
||||||
const obj = new TickObject(callback, args, asyncId, triggerAsyncId);
|
const obj = new TickObject(callback, args, asyncId, triggerAsyncId);
|
||||||
nextTickQueue.push(obj);
|
nextTickQueue.push(obj);
|
||||||
@ -297,7 +297,7 @@ function setupNextTick() {
|
|||||||
args[i - 2] = arguments[i];
|
args[i - 2] = arguments[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
const asyncId = ++async_uid_fields[kAsyncUidCntr];
|
const asyncId = ++async_id_fields[kAsyncIdCounter];
|
||||||
const obj = new TickObject(callback, args, asyncId, triggerAsyncId);
|
const obj = new TickObject(callback, args, asyncId, triggerAsyncId);
|
||||||
nextTickQueue.push(obj);
|
nextTickQueue.push(obj);
|
||||||
++tickInfo[kLength];
|
++tickInfo[kLength];
|
||||||
|
@ -34,14 +34,14 @@ const debug = util.debuglog('timer');
|
|||||||
const kOnTimeout = TimerWrap.kOnTimeout | 0;
|
const kOnTimeout = TimerWrap.kOnTimeout | 0;
|
||||||
const initTriggerId = async_hooks.initTriggerId;
|
const initTriggerId = async_hooks.initTriggerId;
|
||||||
// Two arrays that share state between C++ and JS.
|
// Two arrays that share state between C++ and JS.
|
||||||
const { async_hook_fields, async_uid_fields } = async_wrap;
|
const { async_hook_fields, async_id_fields } = async_wrap;
|
||||||
// The needed emit*() functions.
|
// The needed emit*() functions.
|
||||||
const { emitInit, emitBefore, emitAfter, emitDestroy } = async_hooks;
|
const { emitInit, emitBefore, emitAfter, emitDestroy } = async_hooks;
|
||||||
// Grab the constants necessary for working with internal arrays.
|
// Grab the constants necessary for working with internal arrays.
|
||||||
const { kInit, kDestroy, kAsyncUidCntr } = async_wrap.constants;
|
const { kInit, kDestroy, kAsyncIdCounter } = async_wrap.constants;
|
||||||
// Symbols for storing async id state.
|
// Symbols for storing async id state.
|
||||||
const async_id_symbol = Symbol('asyncId');
|
const async_id_symbol = Symbol('asyncId');
|
||||||
const trigger_id_symbol = Symbol('triggerAsyncId');
|
const trigger_async_id_symbol = Symbol('triggerAsyncId');
|
||||||
|
|
||||||
// Timeout values > TIMEOUT_MAX are set to 1.
|
// Timeout values > TIMEOUT_MAX are set to 1.
|
||||||
const TIMEOUT_MAX = 2147483647; // 2^31-1
|
const TIMEOUT_MAX = 2147483647; // 2^31-1
|
||||||
@ -169,10 +169,12 @@ function insert(item, unrefed) {
|
|||||||
|
|
||||||
if (!item[async_id_symbol] || item._destroyed) {
|
if (!item[async_id_symbol] || item._destroyed) {
|
||||||
item._destroyed = false;
|
item._destroyed = false;
|
||||||
item[async_id_symbol] = ++async_uid_fields[kAsyncUidCntr];
|
item[async_id_symbol] = ++async_id_fields[kAsyncIdCounter];
|
||||||
item[trigger_id_symbol] = initTriggerId();
|
item[trigger_async_id_symbol] = initTriggerId();
|
||||||
if (async_hook_fields[kInit] > 0)
|
if (async_hook_fields[kInit] > 0)
|
||||||
emitInit(item[async_id_symbol], 'Timeout', item[trigger_id_symbol], item);
|
emitInit(
|
||||||
|
item[async_id_symbol], 'Timeout', item[trigger_async_id_symbol], item
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
L.append(list, item);
|
L.append(list, item);
|
||||||
@ -291,7 +293,7 @@ function tryOnTimeout(timer, list) {
|
|||||||
timer[async_id_symbol] : null;
|
timer[async_id_symbol] : null;
|
||||||
var threw = true;
|
var threw = true;
|
||||||
if (timerAsyncId !== null)
|
if (timerAsyncId !== null)
|
||||||
emitBefore(timerAsyncId, timer[trigger_id_symbol]);
|
emitBefore(timerAsyncId, timer[trigger_async_id_symbol]);
|
||||||
try {
|
try {
|
||||||
ontimeout(timer);
|
ontimeout(timer);
|
||||||
threw = false;
|
threw = false;
|
||||||
@ -560,10 +562,12 @@ function Timeout(after, callback, args) {
|
|||||||
this._timerArgs = args;
|
this._timerArgs = args;
|
||||||
this._repeat = null;
|
this._repeat = null;
|
||||||
this._destroyed = false;
|
this._destroyed = false;
|
||||||
this[async_id_symbol] = ++async_uid_fields[kAsyncUidCntr];
|
this[async_id_symbol] = ++async_id_fields[kAsyncIdCounter];
|
||||||
this[trigger_id_symbol] = initTriggerId();
|
this[trigger_async_id_symbol] = initTriggerId();
|
||||||
if (async_hook_fields[kInit] > 0)
|
if (async_hook_fields[kInit] > 0)
|
||||||
emitInit(this[async_id_symbol], 'Timeout', this[trigger_id_symbol], this);
|
emitInit(
|
||||||
|
this[async_id_symbol], 'Timeout', this[trigger_async_id_symbol], this
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -733,7 +737,7 @@ function processImmediate() {
|
|||||||
// 4.7) what is in this smaller function.
|
// 4.7) what is in this smaller function.
|
||||||
function tryOnImmediate(immediate, oldTail) {
|
function tryOnImmediate(immediate, oldTail) {
|
||||||
var threw = true;
|
var threw = true;
|
||||||
emitBefore(immediate[async_id_symbol], immediate[trigger_id_symbol]);
|
emitBefore(immediate[async_id_symbol], immediate[trigger_async_id_symbol]);
|
||||||
try {
|
try {
|
||||||
// make the actual call outside the try/finally to allow it to be optimized
|
// make the actual call outside the try/finally to allow it to be optimized
|
||||||
runCallback(immediate);
|
runCallback(immediate);
|
||||||
@ -798,10 +802,12 @@ function Immediate() {
|
|||||||
this._onImmediate = null;
|
this._onImmediate = null;
|
||||||
this._destroyed = false;
|
this._destroyed = false;
|
||||||
this.domain = process.domain;
|
this.domain = process.domain;
|
||||||
this[async_id_symbol] = ++async_uid_fields[kAsyncUidCntr];
|
this[async_id_symbol] = ++async_id_fields[kAsyncIdCounter];
|
||||||
this[trigger_id_symbol] = initTriggerId();
|
this[trigger_async_id_symbol] = initTriggerId();
|
||||||
if (async_hook_fields[kInit] > 0)
|
if (async_hook_fields[kInit] > 0)
|
||||||
emitInit(this[async_id_symbol], 'Immediate', this[trigger_id_symbol], this);
|
emitInit(
|
||||||
|
this[async_id_symbol], 'Immediate', this[trigger_async_id_symbol], this
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function setImmediate(callback, arg1, arg2, arg3) {
|
function setImmediate(callback, arg1, arg2, arg3) {
|
||||||
|
@ -36,13 +36,13 @@ inline AsyncWrap::ProviderType AsyncWrap::provider_type() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
inline double AsyncWrap::get_id() const {
|
inline double AsyncWrap::get_async_id() const {
|
||||||
return async_id_;
|
return async_id_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
inline double AsyncWrap::get_trigger_id() const {
|
inline double AsyncWrap::get_trigger_async_id() const {
|
||||||
return trigger_id_;
|
return trigger_async_id_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -140,8 +140,8 @@ RetainedObjectInfo* WrapperInfo(uint16_t class_id, Local<Value> wrapper) {
|
|||||||
// end RetainedAsyncInfo
|
// end RetainedAsyncInfo
|
||||||
|
|
||||||
|
|
||||||
static void DestroyIdsCb(uv_timer_t* handle) {
|
static void DestroyAsyncIdsCallback(uv_timer_t* handle) {
|
||||||
Environment* env = Environment::from_destroy_ids_timer_handle(handle);
|
Environment* env = Environment::from_destroy_async_ids_timer_handle(handle);
|
||||||
|
|
||||||
HandleScope handle_scope(env->isolate());
|
HandleScope handle_scope(env->isolate());
|
||||||
Context::Scope context_scope(env->context());
|
Context::Scope context_scope(env->context());
|
||||||
@ -150,15 +150,15 @@ static void DestroyIdsCb(uv_timer_t* handle) {
|
|||||||
TryCatch try_catch(env->isolate());
|
TryCatch try_catch(env->isolate());
|
||||||
|
|
||||||
do {
|
do {
|
||||||
std::vector<double> destroy_ids_list;
|
std::vector<double> destroy_async_id_list;
|
||||||
destroy_ids_list.swap(*env->destroy_ids_list());
|
destroy_async_id_list.swap(*env->destroy_async_id_list());
|
||||||
for (auto current_id : destroy_ids_list) {
|
for (auto async_id : destroy_async_id_list) {
|
||||||
// Want each callback to be cleaned up after itself, instead of cleaning
|
// Want each callback to be cleaned up after itself, instead of cleaning
|
||||||
// them all up after the while() loop completes.
|
// them all up after the while() loop completes.
|
||||||
HandleScope scope(env->isolate());
|
HandleScope scope(env->isolate());
|
||||||
Local<Value> argv = Number::New(env->isolate(), current_id);
|
Local<Value> async_id_value = Number::New(env->isolate(), async_id);
|
||||||
MaybeLocal<Value> ret = fn->Call(
|
MaybeLocal<Value> ret = fn->Call(
|
||||||
env->context(), Undefined(env->isolate()), 1, &argv);
|
env->context(), Undefined(env->isolate()), 1, &async_id_value);
|
||||||
|
|
||||||
if (ret.IsEmpty()) {
|
if (ret.IsEmpty()) {
|
||||||
ClearFatalExceptionHandlers(env);
|
ClearFatalExceptionHandlers(env);
|
||||||
@ -166,18 +166,19 @@ static void DestroyIdsCb(uv_timer_t* handle) {
|
|||||||
UNREACHABLE();
|
UNREACHABLE();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} while (!env->destroy_ids_list()->empty());
|
} while (!env->destroy_async_id_list()->empty());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void PushBackDestroyId(Environment* env, double id) {
|
static void PushBackDestroyAsyncId(Environment* env, double id) {
|
||||||
if (env->async_hooks()->fields()[AsyncHooks::kDestroy] == 0)
|
if (env->async_hooks()->fields()[AsyncHooks::kDestroy] == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (env->destroy_ids_list()->empty())
|
if (env->destroy_async_id_list()->empty())
|
||||||
uv_timer_start(env->destroy_ids_timer_handle(), DestroyIdsCb, 0, 0);
|
uv_timer_start(env->destroy_async_ids_timer_handle(),
|
||||||
|
DestroyAsyncIdsCallback, 0, 0);
|
||||||
|
|
||||||
env->destroy_ids_list()->push_back(id);
|
env->destroy_async_id_list()->push_back(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -187,11 +188,11 @@ void AsyncWrap::EmitPromiseResolve(Environment* env, double async_id) {
|
|||||||
if (async_hooks->fields()[AsyncHooks::kPromiseResolve] == 0)
|
if (async_hooks->fields()[AsyncHooks::kPromiseResolve] == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Local<Value> uid = Number::New(env->isolate(), async_id);
|
Local<Value> async_id_value = Number::New(env->isolate(), async_id);
|
||||||
Local<Function> fn = env->async_hooks_promise_resolve_function();
|
Local<Function> fn = env->async_hooks_promise_resolve_function();
|
||||||
TryCatch try_catch(env->isolate());
|
TryCatch try_catch(env->isolate());
|
||||||
MaybeLocal<Value> ar = fn->Call(
|
MaybeLocal<Value> ar = fn->Call(
|
||||||
env->context(), Undefined(env->isolate()), 1, &uid);
|
env->context(), Undefined(env->isolate()), 1, &async_id_value);
|
||||||
if (ar.IsEmpty()) {
|
if (ar.IsEmpty()) {
|
||||||
ClearFatalExceptionHandlers(env);
|
ClearFatalExceptionHandlers(env);
|
||||||
FatalException(env->isolate(), try_catch);
|
FatalException(env->isolate(), try_catch);
|
||||||
@ -206,11 +207,11 @@ void AsyncWrap::EmitBefore(Environment* env, double async_id) {
|
|||||||
if (async_hooks->fields()[AsyncHooks::kBefore] == 0)
|
if (async_hooks->fields()[AsyncHooks::kBefore] == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Local<Value> uid = Number::New(env->isolate(), async_id);
|
Local<Value> async_id_value = Number::New(env->isolate(), async_id);
|
||||||
Local<Function> fn = env->async_hooks_before_function();
|
Local<Function> fn = env->async_hooks_before_function();
|
||||||
TryCatch try_catch(env->isolate());
|
TryCatch try_catch(env->isolate());
|
||||||
MaybeLocal<Value> ar = fn->Call(
|
MaybeLocal<Value> ar = fn->Call(
|
||||||
env->context(), Undefined(env->isolate()), 1, &uid);
|
env->context(), Undefined(env->isolate()), 1, &async_id_value);
|
||||||
if (ar.IsEmpty()) {
|
if (ar.IsEmpty()) {
|
||||||
ClearFatalExceptionHandlers(env);
|
ClearFatalExceptionHandlers(env);
|
||||||
FatalException(env->isolate(), try_catch);
|
FatalException(env->isolate(), try_catch);
|
||||||
@ -227,11 +228,11 @@ void AsyncWrap::EmitAfter(Environment* env, double async_id) {
|
|||||||
|
|
||||||
// If the user's callback failed then the after() hooks will be called at the
|
// If the user's callback failed then the after() hooks will be called at the
|
||||||
// end of _fatalException().
|
// end of _fatalException().
|
||||||
Local<Value> uid = Number::New(env->isolate(), async_id);
|
Local<Value> async_id_value = Number::New(env->isolate(), async_id);
|
||||||
Local<Function> fn = env->async_hooks_after_function();
|
Local<Function> fn = env->async_hooks_after_function();
|
||||||
TryCatch try_catch(env->isolate());
|
TryCatch try_catch(env->isolate());
|
||||||
MaybeLocal<Value> ar = fn->Call(
|
MaybeLocal<Value> ar = fn->Call(
|
||||||
env->context(), Undefined(env->isolate()), 1, &uid);
|
env->context(), Undefined(env->isolate()), 1, &async_id_value);
|
||||||
if (ar.IsEmpty()) {
|
if (ar.IsEmpty()) {
|
||||||
ClearFatalExceptionHandlers(env);
|
ClearFatalExceptionHandlers(env);
|
||||||
FatalException(env->isolate(), try_catch);
|
FatalException(env->isolate(), try_catch);
|
||||||
@ -248,7 +249,7 @@ class PromiseWrap : public AsyncWrap {
|
|||||||
size_t self_size() const override { return sizeof(*this); }
|
size_t self_size() const override { return sizeof(*this); }
|
||||||
|
|
||||||
static constexpr int kPromiseField = 1;
|
static constexpr int kPromiseField = 1;
|
||||||
static constexpr int kParentIdField = 2;
|
static constexpr int kParentAsyncIdField = 2;
|
||||||
static constexpr int kInternalFieldCount = 3;
|
static constexpr int kInternalFieldCount = 3;
|
||||||
|
|
||||||
static PromiseWrap* New(Environment* env,
|
static PromiseWrap* New(Environment* env,
|
||||||
@ -257,7 +258,7 @@ class PromiseWrap : public AsyncWrap {
|
|||||||
bool silent);
|
bool silent);
|
||||||
static void GetPromise(Local<String> property,
|
static void GetPromise(Local<String> property,
|
||||||
const PropertyCallbackInfo<Value>& info);
|
const PropertyCallbackInfo<Value>& info);
|
||||||
static void GetParentId(Local<String> property,
|
static void getParentAsyncId(Local<String> property,
|
||||||
const PropertyCallbackInfo<Value>& info);
|
const PropertyCallbackInfo<Value>& info);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -269,9 +270,9 @@ PromiseWrap* PromiseWrap::New(Environment* env,
|
|||||||
->NewInstance(env->context()).ToLocalChecked();
|
->NewInstance(env->context()).ToLocalChecked();
|
||||||
object->SetInternalField(PromiseWrap::kPromiseField, promise);
|
object->SetInternalField(PromiseWrap::kPromiseField, promise);
|
||||||
if (parent_wrap != nullptr) {
|
if (parent_wrap != nullptr) {
|
||||||
object->SetInternalField(PromiseWrap::kParentIdField,
|
object->SetInternalField(PromiseWrap::kParentAsyncIdField,
|
||||||
Number::New(env->isolate(),
|
Number::New(env->isolate(),
|
||||||
parent_wrap->get_id()));
|
parent_wrap->get_async_id()));
|
||||||
}
|
}
|
||||||
CHECK_EQ(promise->GetAlignedPointerFromInternalField(0), nullptr);
|
CHECK_EQ(promise->GetAlignedPointerFromInternalField(0), nullptr);
|
||||||
promise->SetInternalField(0, object);
|
promise->SetInternalField(0, object);
|
||||||
@ -283,9 +284,10 @@ void PromiseWrap::GetPromise(Local<String> property,
|
|||||||
info.GetReturnValue().Set(info.Holder()->GetInternalField(kPromiseField));
|
info.GetReturnValue().Set(info.Holder()->GetInternalField(kPromiseField));
|
||||||
}
|
}
|
||||||
|
|
||||||
void PromiseWrap::GetParentId(Local<String> property,
|
void PromiseWrap::getParentAsyncId(Local<String> property,
|
||||||
const PropertyCallbackInfo<Value>& info) {
|
const PropertyCallbackInfo<Value>& info) {
|
||||||
info.GetReturnValue().Set(info.Holder()->GetInternalField(kParentIdField));
|
info.GetReturnValue().Set(
|
||||||
|
info.Holder()->GetInternalField(kParentAsyncIdField));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void PromiseHook(PromiseHookType type, Local<Promise> promise,
|
static void PromiseHook(PromiseHookType type, Local<Promise> promise,
|
||||||
@ -317,8 +319,8 @@ static void PromiseHook(PromiseHookType type, Local<Promise> promise,
|
|||||||
parent_wrap = PromiseWrap::New(env, parent_promise, nullptr, true);
|
parent_wrap = PromiseWrap::New(env, parent_promise, nullptr, true);
|
||||||
}
|
}
|
||||||
// get id from parentWrap
|
// get id from parentWrap
|
||||||
double trigger_id = parent_wrap->get_id();
|
double trigger_async_id = parent_wrap->get_async_id();
|
||||||
env->set_init_trigger_id(trigger_id);
|
env->set_init_trigger_async_id(trigger_async_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
wrap = PromiseWrap::New(env, promise, parent_wrap, silent);
|
wrap = PromiseWrap::New(env, promise, parent_wrap, silent);
|
||||||
@ -326,20 +328,21 @@ static void PromiseHook(PromiseHookType type, Local<Promise> promise,
|
|||||||
|
|
||||||
CHECK_NE(wrap, nullptr);
|
CHECK_NE(wrap, nullptr);
|
||||||
if (type == PromiseHookType::kBefore) {
|
if (type == PromiseHookType::kBefore) {
|
||||||
env->async_hooks()->push_ids(wrap->get_id(), wrap->get_trigger_id());
|
env->async_hooks()->push_async_ids(
|
||||||
AsyncWrap::EmitBefore(wrap->env(), wrap->get_id());
|
wrap->get_async_id(), wrap->get_trigger_async_id());
|
||||||
|
AsyncWrap::EmitBefore(wrap->env(), wrap->get_async_id());
|
||||||
} else if (type == PromiseHookType::kAfter) {
|
} else if (type == PromiseHookType::kAfter) {
|
||||||
AsyncWrap::EmitAfter(wrap->env(), wrap->get_id());
|
AsyncWrap::EmitAfter(wrap->env(), wrap->get_async_id());
|
||||||
if (env->current_async_id() == wrap->get_id()) {
|
if (env->execution_async_id() == wrap->get_async_id()) {
|
||||||
// This condition might not be true if async_hooks was enabled during
|
// This condition might not be true if async_hooks was enabled during
|
||||||
// the promise callback execution.
|
// the promise callback execution.
|
||||||
// Popping it off the stack can be skipped in that case, because is is
|
// Popping it off the stack can be skipped in that case, because is is
|
||||||
// known that it would correspond to exactly one call with
|
// known that it would correspond to exactly one call with
|
||||||
// PromiseHookType::kBefore that was not witnessed by the PromiseHook.
|
// PromiseHookType::kBefore that was not witnessed by the PromiseHook.
|
||||||
env->async_hooks()->pop_ids(wrap->get_id());
|
env->async_hooks()->pop_async_id(wrap->get_async_id());
|
||||||
}
|
}
|
||||||
} else if (type == PromiseHookType::kResolve) {
|
} else if (type == PromiseHookType::kResolve) {
|
||||||
AsyncWrap::EmitPromiseResolve(wrap->env(), wrap->get_id());
|
AsyncWrap::EmitPromiseResolve(wrap->env(), wrap->get_async_id());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -383,7 +386,7 @@ static void SetupHooks(const FunctionCallbackInfo<Value>& args) {
|
|||||||
PromiseWrap::GetPromise);
|
PromiseWrap::GetPromise);
|
||||||
promise_wrap_template->SetAccessor(
|
promise_wrap_template->SetAccessor(
|
||||||
FIXED_ONE_BYTE_STRING(env->isolate(), "parentId"),
|
FIXED_ONE_BYTE_STRING(env->isolate(), "parentId"),
|
||||||
PromiseWrap::GetParentId);
|
PromiseWrap::getParentAsyncId);
|
||||||
env->set_promise_wrap_template(promise_wrap_template);
|
env->set_promise_wrap_template(promise_wrap_template);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -411,24 +414,24 @@ void AsyncWrap::GetAsyncId(const FunctionCallbackInfo<Value>& args) {
|
|||||||
AsyncWrap* wrap;
|
AsyncWrap* wrap;
|
||||||
args.GetReturnValue().Set(-1);
|
args.GetReturnValue().Set(-1);
|
||||||
ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder());
|
ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder());
|
||||||
args.GetReturnValue().Set(wrap->get_id());
|
args.GetReturnValue().Set(wrap->get_async_id());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void AsyncWrap::PushAsyncIds(const FunctionCallbackInfo<Value>& args) {
|
void AsyncWrap::PushAsyncIds(const FunctionCallbackInfo<Value>& args) {
|
||||||
Environment* env = Environment::GetCurrent(args);
|
Environment* env = Environment::GetCurrent(args);
|
||||||
// No need for CHECK(IsNumber()) on args because if FromJust() doesn't fail
|
// No need for CHECK(IsNumber()) on args because if FromJust() doesn't fail
|
||||||
// then the checks in push_ids() and pop_ids() will.
|
// then the checks in push_async_ids() and pop_async_id() will.
|
||||||
double async_id = args[0]->NumberValue(env->context()).FromJust();
|
double async_id = args[0]->NumberValue(env->context()).FromJust();
|
||||||
double trigger_id = args[1]->NumberValue(env->context()).FromJust();
|
double trigger_async_id = args[1]->NumberValue(env->context()).FromJust();
|
||||||
env->async_hooks()->push_ids(async_id, trigger_id);
|
env->async_hooks()->push_async_ids(async_id, trigger_async_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void AsyncWrap::PopAsyncIds(const FunctionCallbackInfo<Value>& args) {
|
void AsyncWrap::PopAsyncIds(const FunctionCallbackInfo<Value>& args) {
|
||||||
Environment* env = Environment::GetCurrent(args);
|
Environment* env = Environment::GetCurrent(args);
|
||||||
double async_id = args[0]->NumberValue(env->context()).FromJust();
|
double async_id = args[0]->NumberValue(env->context()).FromJust();
|
||||||
args.GetReturnValue().Set(env->async_hooks()->pop_ids(async_id));
|
args.GetReturnValue().Set(env->async_hooks()->pop_async_id(async_id));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -439,9 +442,9 @@ void AsyncWrap::AsyncIdStackSize(const FunctionCallbackInfo<Value>& args) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void AsyncWrap::ClearIdStack(const FunctionCallbackInfo<Value>& args) {
|
void AsyncWrap::ClearAsyncIdStack(const FunctionCallbackInfo<Value>& args) {
|
||||||
Environment* env = Environment::GetCurrent(args);
|
Environment* env = Environment::GetCurrent(args);
|
||||||
env->async_hooks()->clear_id_stack();
|
env->async_hooks()->clear_async_id_stack();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -452,9 +455,9 @@ void AsyncWrap::AsyncReset(const FunctionCallbackInfo<Value>& args) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void AsyncWrap::QueueDestroyId(const FunctionCallbackInfo<Value>& args) {
|
void AsyncWrap::QueueDestroyAsyncId(const FunctionCallbackInfo<Value>& args) {
|
||||||
CHECK(args[0]->IsNumber());
|
CHECK(args[0]->IsNumber());
|
||||||
PushBackDestroyId(Environment::GetCurrent(args), args[0]->NumberValue());
|
PushBackDestroyAsyncId(Environment::GetCurrent(args), args[0]->NumberValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
void AsyncWrap::AddWrapMethods(Environment* env,
|
void AsyncWrap::AddWrapMethods(Environment* env,
|
||||||
@ -476,8 +479,8 @@ void AsyncWrap::Initialize(Local<Object> target,
|
|||||||
env->SetMethod(target, "pushAsyncIds", PushAsyncIds);
|
env->SetMethod(target, "pushAsyncIds", PushAsyncIds);
|
||||||
env->SetMethod(target, "popAsyncIds", PopAsyncIds);
|
env->SetMethod(target, "popAsyncIds", PopAsyncIds);
|
||||||
env->SetMethod(target, "asyncIdStackSize", AsyncIdStackSize);
|
env->SetMethod(target, "asyncIdStackSize", AsyncIdStackSize);
|
||||||
env->SetMethod(target, "clearIdStack", ClearIdStack);
|
env->SetMethod(target, "clearAsyncIdStack", ClearAsyncIdStack);
|
||||||
env->SetMethod(target, "addIdToDestroyList", QueueDestroyId);
|
env->SetMethod(target, "queueDestroyAsyncId", QueueDestroyAsyncId);
|
||||||
env->SetMethod(target, "enablePromiseHook", EnablePromiseHook);
|
env->SetMethod(target, "enablePromiseHook", EnablePromiseHook);
|
||||||
env->SetMethod(target, "disablePromiseHook", DisablePromiseHook);
|
env->SetMethod(target, "disablePromiseHook", DisablePromiseHook);
|
||||||
|
|
||||||
@ -504,12 +507,12 @@ void AsyncWrap::Initialize(Local<Object> target,
|
|||||||
//
|
//
|
||||||
// kAsyncUid: Maintains the state of the next unique id to be assigned.
|
// kAsyncUid: Maintains the state of the next unique id to be assigned.
|
||||||
//
|
//
|
||||||
// kInitTriggerId: Write the id of the resource responsible for a handle's
|
// kInitTriggerAsyncId: Write the id of the resource responsible for a
|
||||||
// creation just before calling the new handle's constructor. After the new
|
// handle's creation just before calling the new handle's constructor.
|
||||||
// handle is constructed kInitTriggerId is set back to 0.
|
// After the new handle is constructed kInitTriggerAsyncId is set back to 0.
|
||||||
FORCE_SET_TARGET_FIELD(target,
|
FORCE_SET_TARGET_FIELD(target,
|
||||||
"async_uid_fields",
|
"async_id_fields",
|
||||||
env->async_hooks()->uid_fields().GetJSArray());
|
env->async_hooks()->async_id_fields().GetJSArray());
|
||||||
|
|
||||||
Local<Object> constants = Object::New(isolate);
|
Local<Object> constants = Object::New(isolate);
|
||||||
#define SET_HOOKS_CONSTANT(name) \
|
#define SET_HOOKS_CONSTANT(name) \
|
||||||
@ -522,10 +525,10 @@ void AsyncWrap::Initialize(Local<Object> target,
|
|||||||
SET_HOOKS_CONSTANT(kDestroy);
|
SET_HOOKS_CONSTANT(kDestroy);
|
||||||
SET_HOOKS_CONSTANT(kPromiseResolve);
|
SET_HOOKS_CONSTANT(kPromiseResolve);
|
||||||
SET_HOOKS_CONSTANT(kTotals);
|
SET_HOOKS_CONSTANT(kTotals);
|
||||||
SET_HOOKS_CONSTANT(kCurrentAsyncId);
|
SET_HOOKS_CONSTANT(kExecutionAsyncId);
|
||||||
SET_HOOKS_CONSTANT(kCurrentTriggerId);
|
SET_HOOKS_CONSTANT(kTriggerAsyncId);
|
||||||
SET_HOOKS_CONSTANT(kAsyncUidCntr);
|
SET_HOOKS_CONSTANT(kAsyncIdCounter);
|
||||||
SET_HOOKS_CONSTANT(kInitTriggerId);
|
SET_HOOKS_CONSTANT(kInitTriggerAsyncId);
|
||||||
#undef SET_HOOKS_CONSTANT
|
#undef SET_HOOKS_CONSTANT
|
||||||
FORCE_SET_TARGET_FIELD(target, "constants", constants);
|
FORCE_SET_TARGET_FIELD(target, "constants", constants);
|
||||||
|
|
||||||
@ -545,8 +548,8 @@ void AsyncWrap::Initialize(Local<Object> target,
|
|||||||
Symbol::New(isolate, FIXED_ONE_BYTE_STRING(isolate, "asyncId")));
|
Symbol::New(isolate, FIXED_ONE_BYTE_STRING(isolate, "asyncId")));
|
||||||
FORCE_SET_TARGET_FIELD(
|
FORCE_SET_TARGET_FIELD(
|
||||||
target,
|
target,
|
||||||
"trigger_id_symbol",
|
"trigger_async_id_symbol",
|
||||||
Symbol::New(isolate, FIXED_ONE_BYTE_STRING(isolate, "triggerId")));
|
Symbol::New(isolate, FIXED_ONE_BYTE_STRING(isolate, "triggerAsyncId")));
|
||||||
|
|
||||||
#undef FORCE_SET_TARGET_FIELD
|
#undef FORCE_SET_TARGET_FIELD
|
||||||
|
|
||||||
@ -586,7 +589,7 @@ AsyncWrap::AsyncWrap(Environment* env,
|
|||||||
|
|
||||||
|
|
||||||
AsyncWrap::~AsyncWrap() {
|
AsyncWrap::~AsyncWrap() {
|
||||||
PushBackDestroyId(env(), get_id());
|
PushBackDestroyAsyncId(env(), get_async_id());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -595,13 +598,13 @@ AsyncWrap::~AsyncWrap() {
|
|||||||
// the resource is pulled out of the pool and put back into use.
|
// the resource is pulled out of the pool and put back into use.
|
||||||
void AsyncWrap::AsyncReset(bool silent) {
|
void AsyncWrap::AsyncReset(bool silent) {
|
||||||
async_id_ = env()->new_async_id();
|
async_id_ = env()->new_async_id();
|
||||||
trigger_id_ = env()->get_init_trigger_id();
|
trigger_async_id_ = env()->get_init_trigger_async_id();
|
||||||
|
|
||||||
if (silent) return;
|
if (silent) return;
|
||||||
|
|
||||||
EmitAsyncInit(env(), object(),
|
EmitAsyncInit(env(), object(),
|
||||||
env()->async_hooks()->provider_string(provider_type()),
|
env()->async_hooks()->provider_string(provider_type()),
|
||||||
async_id_, trigger_id_);
|
async_id_, trigger_async_id_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -609,7 +612,7 @@ void AsyncWrap::EmitAsyncInit(Environment* env,
|
|||||||
Local<Object> object,
|
Local<Object> object,
|
||||||
Local<String> type,
|
Local<String> type,
|
||||||
double async_id,
|
double async_id,
|
||||||
double trigger_id) {
|
double trigger_async_id) {
|
||||||
CHECK(!object.IsEmpty());
|
CHECK(!object.IsEmpty());
|
||||||
CHECK(!type.IsEmpty());
|
CHECK(!type.IsEmpty());
|
||||||
AsyncHooks* async_hooks = env->async_hooks();
|
AsyncHooks* async_hooks = env->async_hooks();
|
||||||
@ -625,7 +628,7 @@ void AsyncWrap::EmitAsyncInit(Environment* env,
|
|||||||
Local<Value> argv[] = {
|
Local<Value> argv[] = {
|
||||||
Number::New(env->isolate(), async_id),
|
Number::New(env->isolate(), async_id),
|
||||||
type,
|
type,
|
||||||
Number::New(env->isolate(), trigger_id),
|
Number::New(env->isolate(), trigger_async_id),
|
||||||
object,
|
object,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -643,7 +646,7 @@ void AsyncWrap::EmitAsyncInit(Environment* env,
|
|||||||
MaybeLocal<Value> AsyncWrap::MakeCallback(const Local<Function> cb,
|
MaybeLocal<Value> AsyncWrap::MakeCallback(const Local<Function> cb,
|
||||||
int argc,
|
int argc,
|
||||||
Local<Value>* argv) {
|
Local<Value>* argv) {
|
||||||
async_context context { get_id(), get_trigger_id() };
|
async_context context { get_async_id(), get_trigger_async_id() };
|
||||||
return InternalMakeCallback(env(), object(), cb, argc, argv, context);
|
return InternalMakeCallback(env(), object(), cb, argc, argv, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -652,12 +655,12 @@ MaybeLocal<Value> AsyncWrap::MakeCallback(const Local<Function> cb,
|
|||||||
|
|
||||||
|
|
||||||
async_id AsyncHooksGetExecutionAsyncId(Isolate* isolate) {
|
async_id AsyncHooksGetExecutionAsyncId(Isolate* isolate) {
|
||||||
return Environment::GetCurrent(isolate)->current_async_id();
|
return Environment::GetCurrent(isolate)->execution_async_id();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
async_id AsyncHooksGetTriggerAsyncId(Isolate* isolate) {
|
async_id AsyncHooksGetTriggerAsyncId(Isolate* isolate) {
|
||||||
return Environment::GetCurrent(isolate)->trigger_id();
|
return Environment::GetCurrent(isolate)->trigger_async_id();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -679,7 +682,7 @@ async_context EmitAsyncInit(Isolate* isolate,
|
|||||||
|
|
||||||
// Initialize async context struct
|
// Initialize async context struct
|
||||||
if (trigger_async_id == -1)
|
if (trigger_async_id == -1)
|
||||||
trigger_async_id = env->get_init_trigger_id();
|
trigger_async_id = env->get_init_trigger_async_id();
|
||||||
|
|
||||||
async_context context = {
|
async_context context = {
|
||||||
env->new_async_id(), // async_id_
|
env->new_async_id(), // async_id_
|
||||||
@ -694,7 +697,8 @@ async_context EmitAsyncInit(Isolate* isolate,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void EmitAsyncDestroy(Isolate* isolate, async_context asyncContext) {
|
void EmitAsyncDestroy(Isolate* isolate, async_context asyncContext) {
|
||||||
PushBackDestroyId(Environment::GetCurrent(isolate), asyncContext.async_id);
|
PushBackDestroyAsyncId(Environment::GetCurrent(isolate),
|
||||||
|
asyncContext.async_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace node
|
} // namespace node
|
||||||
|
@ -111,15 +111,17 @@ class AsyncWrap : public BaseObject {
|
|||||||
static void PushAsyncIds(const v8::FunctionCallbackInfo<v8::Value>& args);
|
static void PushAsyncIds(const v8::FunctionCallbackInfo<v8::Value>& args);
|
||||||
static void PopAsyncIds(const v8::FunctionCallbackInfo<v8::Value>& args);
|
static void PopAsyncIds(const v8::FunctionCallbackInfo<v8::Value>& args);
|
||||||
static void AsyncIdStackSize(const v8::FunctionCallbackInfo<v8::Value>& args);
|
static void AsyncIdStackSize(const v8::FunctionCallbackInfo<v8::Value>& args);
|
||||||
static void ClearIdStack(const v8::FunctionCallbackInfo<v8::Value>& args);
|
static void ClearAsyncIdStack(
|
||||||
|
const v8::FunctionCallbackInfo<v8::Value>& args);
|
||||||
static void AsyncReset(const v8::FunctionCallbackInfo<v8::Value>& args);
|
static void AsyncReset(const v8::FunctionCallbackInfo<v8::Value>& args);
|
||||||
static void QueueDestroyId(const v8::FunctionCallbackInfo<v8::Value>& args);
|
static void QueueDestroyAsyncId(
|
||||||
|
const v8::FunctionCallbackInfo<v8::Value>& args);
|
||||||
|
|
||||||
static void EmitAsyncInit(Environment* env,
|
static void EmitAsyncInit(Environment* env,
|
||||||
v8::Local<v8::Object> object,
|
v8::Local<v8::Object> object,
|
||||||
v8::Local<v8::String> type,
|
v8::Local<v8::String> type,
|
||||||
double id,
|
double id,
|
||||||
double trigger_id);
|
double trigger_async_id);
|
||||||
|
|
||||||
static void EmitBefore(Environment* env, double id);
|
static void EmitBefore(Environment* env, double id);
|
||||||
static void EmitAfter(Environment* env, double id);
|
static void EmitAfter(Environment* env, double id);
|
||||||
@ -127,9 +129,9 @@ class AsyncWrap : public BaseObject {
|
|||||||
|
|
||||||
inline ProviderType provider_type() const;
|
inline ProviderType provider_type() const;
|
||||||
|
|
||||||
inline double get_id() const;
|
inline double get_async_id() const;
|
||||||
|
|
||||||
inline double get_trigger_id() const;
|
inline double get_trigger_async_id() const;
|
||||||
|
|
||||||
void AsyncReset(bool silent = false);
|
void AsyncReset(bool silent = false);
|
||||||
|
|
||||||
@ -152,7 +154,7 @@ class AsyncWrap : public BaseObject {
|
|||||||
const ProviderType provider_type_;
|
const ProviderType provider_type_;
|
||||||
// Because the values may be Reset(), cannot be made const.
|
// Because the values may be Reset(), cannot be made const.
|
||||||
double async_id_;
|
double async_id_;
|
||||||
double trigger_id_;
|
double trigger_async_id_;
|
||||||
};
|
};
|
||||||
|
|
||||||
void LoadAsyncWrapperInfo(Environment* env);
|
void LoadAsyncWrapperInfo(Environment* env);
|
||||||
|
@ -51,7 +51,7 @@ void ConnectionWrap<WrapType, UVType>::OnConnection(uv_stream_t* handle,
|
|||||||
};
|
};
|
||||||
|
|
||||||
if (status == 0) {
|
if (status == 0) {
|
||||||
env->set_init_trigger_id(wrap_data->get_id());
|
env->set_init_trigger_async_id(wrap_data->get_async_id());
|
||||||
// Instantiate the client javascript object and handle.
|
// Instantiate the client javascript object and handle.
|
||||||
Local<Object> client_obj = WrapType::Instantiate(env, wrap_data);
|
Local<Object> client_obj = WrapType::Instantiate(env, wrap_data);
|
||||||
|
|
||||||
|
114
src/env-inl.h
114
src/env-inl.h
@ -85,12 +85,12 @@ inline uint32_t* IsolateData::zero_fill_field() const {
|
|||||||
inline Environment::AsyncHooks::AsyncHooks(v8::Isolate* isolate)
|
inline Environment::AsyncHooks::AsyncHooks(v8::Isolate* isolate)
|
||||||
: isolate_(isolate),
|
: isolate_(isolate),
|
||||||
fields_(isolate, kFieldsCount),
|
fields_(isolate, kFieldsCount),
|
||||||
uid_fields_(isolate, kUidFieldsCount) {
|
async_id_fields_(isolate, kUidFieldsCount) {
|
||||||
v8::HandleScope handle_scope(isolate_);
|
v8::HandleScope handle_scope(isolate_);
|
||||||
|
|
||||||
// kAsyncUidCntr should start at 1 because that'll be the id the execution
|
// kAsyncIdCounter should start at 1 because that'll be the id the execution
|
||||||
// context during bootstrap (code that runs before entering uv_run()).
|
// context during bootstrap (code that runs before entering uv_run()).
|
||||||
uid_fields_[AsyncHooks::kAsyncUidCntr] = 1;
|
async_id_fields_[AsyncHooks::kAsyncIdCounter] = 1;
|
||||||
|
|
||||||
// Create all the provider strings that will be passed to JS. Place them in
|
// Create all the provider strings that will be passed to JS. Place them in
|
||||||
// an array so the array index matches the PROVIDER id offset. This way the
|
// an array so the array index matches the PROVIDER id offset. This way the
|
||||||
@ -117,11 +117,11 @@ inline int Environment::AsyncHooks::fields_count() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline AliasedBuffer<double, v8::Float64Array>&
|
inline AliasedBuffer<double, v8::Float64Array>&
|
||||||
Environment::AsyncHooks::uid_fields() {
|
Environment::AsyncHooks::async_id_fields() {
|
||||||
return uid_fields_;
|
return async_id_fields_;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline int Environment::AsyncHooks::uid_fields_count() const {
|
inline int Environment::AsyncHooks::async_id_fields_count() const {
|
||||||
return kUidFieldsCount;
|
return kUidFieldsCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -129,29 +129,29 @@ inline v8::Local<v8::String> Environment::AsyncHooks::provider_string(int idx) {
|
|||||||
return providers_[idx].Get(isolate_);
|
return providers_[idx].Get(isolate_);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void Environment::AsyncHooks::push_ids(double async_id,
|
inline void Environment::AsyncHooks::push_async_ids(double async_id,
|
||||||
double trigger_id) {
|
double trigger_async_id) {
|
||||||
CHECK_GE(async_id, -1);
|
CHECK_GE(async_id, -1);
|
||||||
CHECK_GE(trigger_id, -1);
|
CHECK_GE(trigger_async_id, -1);
|
||||||
|
|
||||||
ids_stack_.push({ uid_fields_[kCurrentAsyncId],
|
async_ids_stack_.push({ async_id_fields_[kExecutionAsyncId],
|
||||||
uid_fields_[kCurrentTriggerId] });
|
async_id_fields_[kTriggerAsyncId] });
|
||||||
uid_fields_[kCurrentAsyncId] = async_id;
|
async_id_fields_[kExecutionAsyncId] = async_id;
|
||||||
uid_fields_[kCurrentTriggerId] = trigger_id;
|
async_id_fields_[kTriggerAsyncId] = trigger_async_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool Environment::AsyncHooks::pop_ids(double async_id) {
|
inline bool Environment::AsyncHooks::pop_async_id(double async_id) {
|
||||||
// In case of an exception then this may have already been reset, if the
|
// In case of an exception then this may have already been reset, if the
|
||||||
// stack was multiple MakeCallback()'s deep.
|
// stack was multiple MakeCallback()'s deep.
|
||||||
if (ids_stack_.empty()) return false;
|
if (async_ids_stack_.empty()) return false;
|
||||||
|
|
||||||
// Ask for the async_id to be restored as a sanity check that the stack
|
// Ask for the async_id to be restored as a sanity check that the stack
|
||||||
// hasn't been corrupted.
|
// hasn't been corrupted.
|
||||||
if (uid_fields_[kCurrentAsyncId] != async_id) {
|
if (async_id_fields_[kExecutionAsyncId] != async_id) {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"Error: async hook stack has become corrupted ("
|
"Error: async hook stack has become corrupted ("
|
||||||
"actual: %.f, expected: %.f)\n",
|
"actual: %.f, expected: %.f)\n",
|
||||||
uid_fields_.GetValue(kCurrentAsyncId),
|
async_id_fields_.GetValue(kExecutionAsyncId),
|
||||||
async_id);
|
async_id);
|
||||||
Environment* env = Environment::GetCurrent(isolate_);
|
Environment* env = Environment::GetCurrent(isolate_);
|
||||||
DumpBacktrace(stderr);
|
DumpBacktrace(stderr);
|
||||||
@ -163,35 +163,37 @@ inline bool Environment::AsyncHooks::pop_ids(double async_id) {
|
|||||||
ABORT_NO_BACKTRACE();
|
ABORT_NO_BACKTRACE();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto ids = ids_stack_.top();
|
auto async_ids = async_ids_stack_.top();
|
||||||
ids_stack_.pop();
|
async_ids_stack_.pop();
|
||||||
uid_fields_[kCurrentAsyncId] = ids.async_id;
|
async_id_fields_[kExecutionAsyncId] = async_ids.async_id;
|
||||||
uid_fields_[kCurrentTriggerId] = ids.trigger_id;
|
async_id_fields_[kTriggerAsyncId] = async_ids.trigger_async_id;
|
||||||
return !ids_stack_.empty();
|
return !async_ids_stack_.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline size_t Environment::AsyncHooks::stack_size() {
|
inline size_t Environment::AsyncHooks::stack_size() {
|
||||||
return ids_stack_.size();
|
return async_ids_stack_.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void Environment::AsyncHooks::clear_id_stack() {
|
inline void Environment::AsyncHooks::clear_async_id_stack() {
|
||||||
while (!ids_stack_.empty())
|
while (!async_ids_stack_.empty())
|
||||||
ids_stack_.pop();
|
async_ids_stack_.pop();
|
||||||
uid_fields_[kCurrentAsyncId] = 0;
|
async_id_fields_[kExecutionAsyncId] = 0;
|
||||||
uid_fields_[kCurrentTriggerId] = 0;
|
async_id_fields_[kTriggerAsyncId] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline Environment::AsyncHooks::InitScope::InitScope(
|
inline Environment::AsyncHooks::InitScope::InitScope(
|
||||||
Environment* env, double init_trigger_id)
|
Environment* env, double init_trigger_async_id)
|
||||||
: env_(env),
|
: env_(env),
|
||||||
uid_fields_ref_(env->async_hooks()->uid_fields()) {
|
async_id_fields_ref_(env->async_hooks()->async_id_fields()) {
|
||||||
CHECK_GE(init_trigger_id, -1);
|
CHECK_GE(init_trigger_async_id, -1);
|
||||||
env->async_hooks()->push_ids(uid_fields_ref_[AsyncHooks::kCurrentAsyncId],
|
env->async_hooks()->push_async_ids(
|
||||||
init_trigger_id);
|
async_id_fields_ref_[AsyncHooks::kExecutionAsyncId],
|
||||||
|
init_trigger_async_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline Environment::AsyncHooks::InitScope::~InitScope() {
|
inline Environment::AsyncHooks::InitScope::~InitScope() {
|
||||||
env_->async_hooks()->pop_ids(uid_fields_ref_[AsyncHooks::kCurrentAsyncId]);
|
env_->async_hooks()->pop_async_id(
|
||||||
|
async_id_fields_ref_[AsyncHooks::kExecutionAsyncId]);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline Environment::AsyncCallbackScope::AsyncCallbackScope(Environment* env)
|
inline Environment::AsyncCallbackScope::AsyncCallbackScope(Environment* env)
|
||||||
@ -306,7 +308,7 @@ inline Environment::Environment(IsolateData* isolate_data,
|
|||||||
|
|
||||||
AssignToContext(context);
|
AssignToContext(context);
|
||||||
|
|
||||||
destroy_ids_list_.reserve(512);
|
destroy_async_id_list_.reserve(512);
|
||||||
performance_state_ = Calloc<performance::performance_state>(1);
|
performance_state_ = Calloc<performance::performance_state>(1);
|
||||||
performance_state_->milestones[
|
performance_state_->milestones[
|
||||||
performance::NODE_PERFORMANCE_MILESTONE_ENVIRONMENT] =
|
performance::NODE_PERFORMANCE_MILESTONE_ENVIRONMENT] =
|
||||||
@ -358,13 +360,13 @@ inline uv_idle_t* Environment::immediate_idle_handle() {
|
|||||||
return &immediate_idle_handle_;
|
return &immediate_idle_handle_;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline Environment* Environment::from_destroy_ids_timer_handle(
|
inline Environment* Environment::from_destroy_async_ids_timer_handle(
|
||||||
uv_timer_t* handle) {
|
uv_timer_t* handle) {
|
||||||
return ContainerOf(&Environment::destroy_ids_timer_handle_, handle);
|
return ContainerOf(&Environment::destroy_async_ids_timer_handle_, handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline uv_timer_t* Environment::destroy_ids_timer_handle() {
|
inline uv_timer_t* Environment::destroy_async_ids_timer_handle() {
|
||||||
return &destroy_ids_timer_handle_;
|
return &destroy_async_ids_timer_handle_;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void Environment::RegisterHandleCleanup(uv_handle_t* handle,
|
inline void Environment::RegisterHandleCleanup(uv_handle_t* handle,
|
||||||
@ -425,35 +427,35 @@ inline void Environment::set_abort_on_uncaught_exception(bool value) {
|
|||||||
abort_on_uncaught_exception_ = value;
|
abort_on_uncaught_exception_ = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::vector<double>* Environment::destroy_ids_list() {
|
inline std::vector<double>* Environment::destroy_async_id_list() {
|
||||||
return &destroy_ids_list_;
|
return &destroy_async_id_list_;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline double Environment::new_async_id() {
|
inline double Environment::new_async_id() {
|
||||||
async_hooks()->uid_fields()[AsyncHooks::kAsyncUidCntr] =
|
async_hooks()->async_id_fields()[AsyncHooks::kAsyncIdCounter] =
|
||||||
async_hooks()->uid_fields()[AsyncHooks::kAsyncUidCntr] + 1;
|
async_hooks()->async_id_fields()[AsyncHooks::kAsyncIdCounter] + 1;
|
||||||
return async_hooks()->uid_fields()[AsyncHooks::kAsyncUidCntr];
|
return async_hooks()->async_id_fields()[AsyncHooks::kAsyncIdCounter];
|
||||||
}
|
}
|
||||||
|
|
||||||
inline double Environment::current_async_id() {
|
inline double Environment::execution_async_id() {
|
||||||
return async_hooks()->uid_fields()[AsyncHooks::kCurrentAsyncId];
|
return async_hooks()->async_id_fields()[AsyncHooks::kExecutionAsyncId];
|
||||||
}
|
}
|
||||||
|
|
||||||
inline double Environment::trigger_id() {
|
inline double Environment::trigger_async_id() {
|
||||||
return async_hooks()->uid_fields()[AsyncHooks::kCurrentTriggerId];
|
return async_hooks()->async_id_fields()[AsyncHooks::kTriggerAsyncId];
|
||||||
}
|
}
|
||||||
|
|
||||||
inline double Environment::get_init_trigger_id() {
|
inline double Environment::get_init_trigger_async_id() {
|
||||||
AliasedBuffer<double, v8::Float64Array>& uid_fields =
|
AliasedBuffer<double, v8::Float64Array>& async_id_fields =
|
||||||
async_hooks()->uid_fields();
|
async_hooks()->async_id_fields();
|
||||||
double tid = uid_fields[AsyncHooks::kInitTriggerId];
|
double tid = async_id_fields[AsyncHooks::kInitTriggerAsyncId];
|
||||||
uid_fields[AsyncHooks::kInitTriggerId] = 0;
|
async_id_fields[AsyncHooks::kInitTriggerAsyncId] = 0;
|
||||||
if (tid <= 0) tid = current_async_id();
|
if (tid <= 0) tid = execution_async_id();
|
||||||
return tid;
|
return tid;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void Environment::set_init_trigger_id(const double id) {
|
inline void Environment::set_init_trigger_async_id(const double id) {
|
||||||
async_hooks()->uid_fields()[AsyncHooks::kInitTriggerId] = id;
|
async_hooks()->async_id_fields()[AsyncHooks::kInitTriggerAsyncId] = id;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline double* Environment::heap_statistics_buffer() const {
|
inline double* Environment::heap_statistics_buffer() const {
|
||||||
|
@ -48,7 +48,7 @@ void Environment::Start(int argc,
|
|||||||
uv_unref(reinterpret_cast<uv_handle_t*>(&idle_prepare_handle_));
|
uv_unref(reinterpret_cast<uv_handle_t*>(&idle_prepare_handle_));
|
||||||
uv_unref(reinterpret_cast<uv_handle_t*>(&idle_check_handle_));
|
uv_unref(reinterpret_cast<uv_handle_t*>(&idle_check_handle_));
|
||||||
|
|
||||||
uv_timer_init(event_loop(), destroy_ids_timer_handle());
|
uv_timer_init(event_loop(), destroy_async_ids_timer_handle());
|
||||||
|
|
||||||
auto close_and_finish = [](Environment* env, uv_handle_t* handle, void* arg) {
|
auto close_and_finish = [](Environment* env, uv_handle_t* handle, void* arg) {
|
||||||
handle->data = env;
|
handle->data = env;
|
||||||
@ -75,7 +75,7 @@ void Environment::Start(int argc,
|
|||||||
close_and_finish,
|
close_and_finish,
|
||||||
nullptr);
|
nullptr);
|
||||||
RegisterHandleCleanup(
|
RegisterHandleCleanup(
|
||||||
reinterpret_cast<uv_handle_t*>(&destroy_ids_timer_handle_),
|
reinterpret_cast<uv_handle_t*>(&destroy_async_ids_timer_handle_),
|
||||||
close_and_finish,
|
close_and_finish,
|
||||||
nullptr);
|
nullptr);
|
||||||
|
|
||||||
|
53
src/env.h
53
src/env.h
@ -332,7 +332,7 @@ class Environment;
|
|||||||
|
|
||||||
struct node_async_ids {
|
struct node_async_ids {
|
||||||
double async_id;
|
double async_id;
|
||||||
double trigger_id;
|
double trigger_async_id;
|
||||||
};
|
};
|
||||||
|
|
||||||
class IsolateData {
|
class IsolateData {
|
||||||
@ -388,10 +388,10 @@ class Environment {
|
|||||||
};
|
};
|
||||||
|
|
||||||
enum UidFields {
|
enum UidFields {
|
||||||
kCurrentAsyncId,
|
kExecutionAsyncId,
|
||||||
kCurrentTriggerId,
|
kTriggerAsyncId,
|
||||||
kAsyncUidCntr,
|
kAsyncIdCounter,
|
||||||
kInitTriggerId,
|
kInitTriggerAsyncId,
|
||||||
kUidFieldsCount,
|
kUidFieldsCount,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -400,28 +400,28 @@ class Environment {
|
|||||||
inline AliasedBuffer<uint32_t, v8::Uint32Array>& fields();
|
inline AliasedBuffer<uint32_t, v8::Uint32Array>& fields();
|
||||||
inline int fields_count() const;
|
inline int fields_count() const;
|
||||||
|
|
||||||
inline AliasedBuffer<double, v8::Float64Array>& uid_fields();
|
inline AliasedBuffer<double, v8::Float64Array>& async_id_fields();
|
||||||
inline int uid_fields_count() const;
|
inline int async_id_fields_count() const;
|
||||||
|
|
||||||
inline v8::Local<v8::String> provider_string(int idx);
|
inline v8::Local<v8::String> provider_string(int idx);
|
||||||
|
|
||||||
inline void push_ids(double async_id, double trigger_id);
|
inline void push_async_ids(double async_id, double trigger_async_id);
|
||||||
inline bool pop_ids(double async_id);
|
inline bool pop_async_id(double async_id);
|
||||||
inline size_t stack_size();
|
inline size_t stack_size();
|
||||||
inline void clear_id_stack(); // Used in fatal exceptions.
|
inline void clear_async_id_stack(); // Used in fatal exceptions.
|
||||||
|
|
||||||
// Used to propagate the trigger_id to the constructor of any newly created
|
// Used to propagate the trigger_async_id to the constructor of any newly
|
||||||
// resources using RAII. Instead of needing to pass the trigger_id along
|
// created resources using RAII. Instead of needing to pass the
|
||||||
// with other constructor arguments.
|
// trigger_async_id along with other constructor arguments.
|
||||||
class InitScope {
|
class InitScope {
|
||||||
public:
|
public:
|
||||||
InitScope() = delete;
|
InitScope() = delete;
|
||||||
explicit InitScope(Environment* env, double init_trigger_id);
|
explicit InitScope(Environment* env, double init_trigger_async_id);
|
||||||
~InitScope();
|
~InitScope();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Environment* env_;
|
Environment* env_;
|
||||||
AliasedBuffer<double, v8::Float64Array> uid_fields_ref_;
|
AliasedBuffer<double, v8::Float64Array> async_id_fields_ref_;
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(InitScope);
|
DISALLOW_COPY_AND_ASSIGN(InitScope);
|
||||||
};
|
};
|
||||||
@ -434,12 +434,12 @@ class Environment {
|
|||||||
// Used by provider_string().
|
// Used by provider_string().
|
||||||
v8::Isolate* isolate_;
|
v8::Isolate* isolate_;
|
||||||
// Stores the ids of the current execution context stack.
|
// Stores the ids of the current execution context stack.
|
||||||
std::stack<struct node_async_ids> ids_stack_;
|
std::stack<struct node_async_ids> async_ids_stack_;
|
||||||
// Attached to a Uint32Array that tracks the number of active hooks for
|
// Attached to a Uint32Array that tracks the number of active hooks for
|
||||||
// each type.
|
// each type.
|
||||||
AliasedBuffer<uint32_t, v8::Uint32Array> fields_;
|
AliasedBuffer<uint32_t, v8::Uint32Array> fields_;
|
||||||
// Attached to a Float64Array that tracks the state of async resources.
|
// Attached to a Float64Array that tracks the state of async resources.
|
||||||
AliasedBuffer<double, v8::Float64Array> uid_fields_;
|
AliasedBuffer<double, v8::Float64Array> async_id_fields_;
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(AsyncHooks);
|
DISALLOW_COPY_AND_ASSIGN(AsyncHooks);
|
||||||
};
|
};
|
||||||
@ -549,10 +549,11 @@ class Environment {
|
|||||||
inline uint32_t watched_providers() const;
|
inline uint32_t watched_providers() const;
|
||||||
|
|
||||||
static inline Environment* from_immediate_check_handle(uv_check_t* handle);
|
static inline Environment* from_immediate_check_handle(uv_check_t* handle);
|
||||||
static inline Environment* from_destroy_ids_timer_handle(uv_timer_t* handle);
|
static inline Environment* from_destroy_async_ids_timer_handle(
|
||||||
|
uv_timer_t* handle);
|
||||||
inline uv_check_t* immediate_check_handle();
|
inline uv_check_t* immediate_check_handle();
|
||||||
inline uv_idle_t* immediate_idle_handle();
|
inline uv_idle_t* immediate_idle_handle();
|
||||||
inline uv_timer_t* destroy_ids_timer_handle();
|
inline uv_timer_t* destroy_async_ids_timer_handle();
|
||||||
|
|
||||||
// Register clean-up cb to be called on environment destruction.
|
// Register clean-up cb to be called on environment destruction.
|
||||||
inline void RegisterHandleCleanup(uv_handle_t* handle,
|
inline void RegisterHandleCleanup(uv_handle_t* handle,
|
||||||
@ -581,13 +582,13 @@ class Environment {
|
|||||||
|
|
||||||
// The necessary API for async_hooks.
|
// The necessary API for async_hooks.
|
||||||
inline double new_async_id();
|
inline double new_async_id();
|
||||||
inline double current_async_id();
|
inline double execution_async_id();
|
||||||
inline double trigger_id();
|
inline double trigger_async_id();
|
||||||
inline double get_init_trigger_id();
|
inline double get_init_trigger_async_id();
|
||||||
inline void set_init_trigger_id(const double id);
|
inline void set_init_trigger_async_id(const double id);
|
||||||
|
|
||||||
// List of id's that have been destroyed and need the destroy() cb called.
|
// List of id's that have been destroyed and need the destroy() cb called.
|
||||||
inline std::vector<double>* destroy_ids_list();
|
inline std::vector<double>* destroy_async_id_list();
|
||||||
|
|
||||||
std::unordered_multimap<int, loader::ModuleWrap*> module_map;
|
std::unordered_multimap<int, loader::ModuleWrap*> module_map;
|
||||||
|
|
||||||
@ -686,7 +687,7 @@ class Environment {
|
|||||||
IsolateData* const isolate_data_;
|
IsolateData* const isolate_data_;
|
||||||
uv_check_t immediate_check_handle_;
|
uv_check_t immediate_check_handle_;
|
||||||
uv_idle_t immediate_idle_handle_;
|
uv_idle_t immediate_idle_handle_;
|
||||||
uv_timer_t destroy_ids_timer_handle_;
|
uv_timer_t destroy_async_ids_timer_handle_;
|
||||||
uv_prepare_t idle_prepare_handle_;
|
uv_prepare_t idle_prepare_handle_;
|
||||||
uv_check_t idle_check_handle_;
|
uv_check_t idle_check_handle_;
|
||||||
|
|
||||||
@ -700,7 +701,7 @@ class Environment {
|
|||||||
bool abort_on_uncaught_exception_;
|
bool abort_on_uncaught_exception_;
|
||||||
bool emit_napi_warning_;
|
bool emit_napi_warning_;
|
||||||
size_t makecallback_cntr_;
|
size_t makecallback_cntr_;
|
||||||
std::vector<double> destroy_ids_list_;
|
std::vector<double> destroy_async_id_list_;
|
||||||
|
|
||||||
performance::performance_state* performance_state_ = nullptr;
|
performance::performance_state* performance_state_ = nullptr;
|
||||||
std::map<std::string, uint64_t> performance_marks_;
|
std::map<std::string, uint64_t> performance_marks_;
|
||||||
|
16
src/node.cc
16
src/node.cc
@ -1381,7 +1381,7 @@ InternalCallbackScope::InternalCallbackScope(Environment* env,
|
|||||||
AsyncWrap::EmitBefore(env, asyncContext.async_id);
|
AsyncWrap::EmitBefore(env, asyncContext.async_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
env->async_hooks()->push_ids(async_context_.async_id,
|
env->async_hooks()->push_async_ids(async_context_.async_id,
|
||||||
async_context_.trigger_async_id);
|
async_context_.trigger_async_id);
|
||||||
pushed_ids_ = true;
|
pushed_ids_ = true;
|
||||||
}
|
}
|
||||||
@ -1396,7 +1396,7 @@ void InternalCallbackScope::Close() {
|
|||||||
HandleScope handle_scope(env_->isolate());
|
HandleScope handle_scope(env_->isolate());
|
||||||
|
|
||||||
if (pushed_ids_)
|
if (pushed_ids_)
|
||||||
env_->async_hooks()->pop_ids(async_context_.async_id);
|
env_->async_hooks()->pop_async_id(async_context_.async_id);
|
||||||
|
|
||||||
if (failed_) return;
|
if (failed_) return;
|
||||||
|
|
||||||
@ -1420,8 +1420,8 @@ void InternalCallbackScope::Close() {
|
|||||||
|
|
||||||
// Make sure the stack unwound properly. If there are nested MakeCallback's
|
// Make sure the stack unwound properly. If there are nested MakeCallback's
|
||||||
// then it should return early and not reach this code.
|
// then it should return early and not reach this code.
|
||||||
CHECK_EQ(env_->current_async_id(), 0);
|
CHECK_EQ(env_->execution_async_id(), 0);
|
||||||
CHECK_EQ(env_->trigger_id(), 0);
|
CHECK_EQ(env_->trigger_async_id(), 0);
|
||||||
|
|
||||||
Local<Object> process = env_->process_object();
|
Local<Object> process = env_->process_object();
|
||||||
|
|
||||||
@ -1430,8 +1430,8 @@ void InternalCallbackScope::Close() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
CHECK_EQ(env_->current_async_id(), 0);
|
CHECK_EQ(env_->execution_async_id(), 0);
|
||||||
CHECK_EQ(env_->trigger_id(), 0);
|
CHECK_EQ(env_->trigger_async_id(), 0);
|
||||||
|
|
||||||
if (env_->tick_callback_function()->Call(process, 0, nullptr).IsEmpty()) {
|
if (env_->tick_callback_function()->Call(process, 0, nullptr).IsEmpty()) {
|
||||||
failed_ = true;
|
failed_ = true;
|
||||||
@ -4695,9 +4695,9 @@ inline int Start(Isolate* isolate, IsolateData* isolate_data,
|
|||||||
|
|
||||||
{
|
{
|
||||||
Environment::AsyncCallbackScope callback_scope(&env);
|
Environment::AsyncCallbackScope callback_scope(&env);
|
||||||
env.async_hooks()->push_ids(1, 0);
|
env.async_hooks()->push_async_ids(1, 0);
|
||||||
LoadEnvironment(&env);
|
LoadEnvironment(&env);
|
||||||
env.async_hooks()->pop_ids(1);
|
env.async_hooks()->pop_async_id(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
env.set_trace_sync_io(trace_sync_io);
|
env.set_trace_sync_io(trace_sync_io);
|
||||||
|
@ -556,7 +556,7 @@ NODE_EXTERN async_id AsyncHooksGetTriggerAsyncId(v8::Isolate* isolate);
|
|||||||
|
|
||||||
/* If the native API doesn't inherit from the helper class then the callbacks
|
/* If the native API doesn't inherit from the helper class then the callbacks
|
||||||
* must be triggered manually. This triggers the init() callback. The return
|
* must be triggered manually. This triggers the init() callback. The return
|
||||||
* value is the uid assigned to the resource.
|
* value is the async id assigned to the resource.
|
||||||
*
|
*
|
||||||
* The `trigger_async_id` parameter should correspond to the resource which is
|
* The `trigger_async_id` parameter should correspond to the resource which is
|
||||||
* creating the new resource, which will usually be the return value of
|
* creating the new resource, which will usually be the return value of
|
||||||
|
@ -479,7 +479,7 @@ class Parser : public AsyncWrap {
|
|||||||
ASSIGN_OR_RETURN_UNWRAP(&parser, args.Holder());
|
ASSIGN_OR_RETURN_UNWRAP(&parser, args.Holder());
|
||||||
// Should always be called from the same context.
|
// Should always be called from the same context.
|
||||||
CHECK_EQ(env, parser->env());
|
CHECK_EQ(env, parser->env());
|
||||||
// The parser is being reused. Reset the uid and call init() callbacks.
|
// The parser is being reused. Reset the async id and call init() callbacks.
|
||||||
parser->AsyncReset();
|
parser->AsyncReset();
|
||||||
parser->Init(type);
|
parser->Init(type);
|
||||||
}
|
}
|
||||||
|
@ -52,7 +52,7 @@ using AsyncHooks = Environment::AsyncHooks;
|
|||||||
|
|
||||||
Local<Object> PipeWrap::Instantiate(Environment* env, AsyncWrap* parent) {
|
Local<Object> PipeWrap::Instantiate(Environment* env, AsyncWrap* parent) {
|
||||||
EscapableHandleScope handle_scope(env->isolate());
|
EscapableHandleScope handle_scope(env->isolate());
|
||||||
AsyncHooks::InitScope init_scope(env, parent->get_id());
|
AsyncHooks::InitScope init_scope(env, parent->get_async_id());
|
||||||
CHECK_EQ(false, env->pipe_constructor_template().IsEmpty());
|
CHECK_EQ(false, env->pipe_constructor_template().IsEmpty());
|
||||||
Local<Function> constructor = env->pipe_constructor_template()->GetFunction();
|
Local<Function> constructor = env->pipe_constructor_template()->GetFunction();
|
||||||
CHECK_EQ(false, constructor.IsEmpty());
|
CHECK_EQ(false, constructor.IsEmpty());
|
||||||
|
@ -136,7 +136,7 @@ void StreamBase::JSMethod(const FunctionCallbackInfo<Value>& args) {
|
|||||||
if (!wrap->IsAlive())
|
if (!wrap->IsAlive())
|
||||||
return args.GetReturnValue().Set(UV_EINVAL);
|
return args.GetReturnValue().Set(UV_EINVAL);
|
||||||
|
|
||||||
AsyncHooks::InitScope init_scope(handle->env(), handle->get_id());
|
AsyncHooks::InitScope init_scope(handle->env(), handle->get_async_id());
|
||||||
args.GetReturnValue().Set((wrap->*Method)(args));
|
args.GetReturnValue().Set((wrap->*Method)(args));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,7 +55,7 @@ int StreamBase::Shutdown(const FunctionCallbackInfo<Value>& args) {
|
|||||||
|
|
||||||
AsyncWrap* wrap = GetAsyncWrap();
|
AsyncWrap* wrap = GetAsyncWrap();
|
||||||
CHECK_NE(wrap, nullptr);
|
CHECK_NE(wrap, nullptr);
|
||||||
env->set_init_trigger_id(wrap->get_id());
|
env->set_init_trigger_async_id(wrap->get_async_id());
|
||||||
ShutdownWrap* req_wrap = new ShutdownWrap(env,
|
ShutdownWrap* req_wrap = new ShutdownWrap(env,
|
||||||
req_wrap_obj,
|
req_wrap_obj,
|
||||||
this,
|
this,
|
||||||
@ -160,7 +160,7 @@ int StreamBase::Writev(const FunctionCallbackInfo<Value>& args) {
|
|||||||
|
|
||||||
wrap = GetAsyncWrap();
|
wrap = GetAsyncWrap();
|
||||||
CHECK_NE(wrap, nullptr);
|
CHECK_NE(wrap, nullptr);
|
||||||
env->set_init_trigger_id(wrap->get_id());
|
env->set_init_trigger_async_id(wrap->get_async_id());
|
||||||
req_wrap = WriteWrap::New(env, req_wrap_obj, this, AfterWrite, storage_size);
|
req_wrap = WriteWrap::New(env, req_wrap_obj, this, AfterWrite, storage_size);
|
||||||
|
|
||||||
offset = 0;
|
offset = 0;
|
||||||
@ -249,7 +249,7 @@ int StreamBase::WriteBuffer(const FunctionCallbackInfo<Value>& args) {
|
|||||||
|
|
||||||
wrap = GetAsyncWrap();
|
wrap = GetAsyncWrap();
|
||||||
if (wrap != nullptr)
|
if (wrap != nullptr)
|
||||||
env->set_init_trigger_id(wrap->get_id());
|
env->set_init_trigger_async_id(wrap->get_async_id());
|
||||||
// Allocate, or write rest
|
// Allocate, or write rest
|
||||||
req_wrap = WriteWrap::New(env, req_wrap_obj, this, AfterWrite);
|
req_wrap = WriteWrap::New(env, req_wrap_obj, this, AfterWrite);
|
||||||
|
|
||||||
@ -334,7 +334,7 @@ int StreamBase::WriteString(const FunctionCallbackInfo<Value>& args) {
|
|||||||
|
|
||||||
wrap = GetAsyncWrap();
|
wrap = GetAsyncWrap();
|
||||||
if (wrap != nullptr)
|
if (wrap != nullptr)
|
||||||
env->set_init_trigger_id(wrap->get_id());
|
env->set_init_trigger_async_id(wrap->get_async_id());
|
||||||
req_wrap = WriteWrap::New(env, req_wrap_obj, this, AfterWrite, storage_size);
|
req_wrap = WriteWrap::New(env, req_wrap_obj, this, AfterWrite, storage_size);
|
||||||
|
|
||||||
data = req_wrap->Extra();
|
data = req_wrap->Extra();
|
||||||
|
@ -55,7 +55,7 @@ using AsyncHooks = Environment::AsyncHooks;
|
|||||||
|
|
||||||
Local<Object> TCPWrap::Instantiate(Environment* env, AsyncWrap* parent) {
|
Local<Object> TCPWrap::Instantiate(Environment* env, AsyncWrap* parent) {
|
||||||
EscapableHandleScope handle_scope(env->isolate());
|
EscapableHandleScope handle_scope(env->isolate());
|
||||||
AsyncHooks::InitScope init_scope(env, parent->get_id());
|
AsyncHooks::InitScope init_scope(env, parent->get_async_id());
|
||||||
CHECK_EQ(env->tcp_constructor_template().IsEmpty(), false);
|
CHECK_EQ(env->tcp_constructor_template().IsEmpty(), false);
|
||||||
Local<Function> constructor = env->tcp_constructor_template()->GetFunction();
|
Local<Function> constructor = env->tcp_constructor_template()->GetFunction();
|
||||||
CHECK_EQ(constructor.IsEmpty(), false);
|
CHECK_EQ(constructor.IsEmpty(), false);
|
||||||
@ -268,7 +268,7 @@ void TCPWrap::Connect(const FunctionCallbackInfo<Value>& args) {
|
|||||||
int err = uv_ip4_addr(*ip_address, port, &addr);
|
int err = uv_ip4_addr(*ip_address, port, &addr);
|
||||||
|
|
||||||
if (err == 0) {
|
if (err == 0) {
|
||||||
env->set_init_trigger_id(wrap->get_id());
|
env->set_init_trigger_async_id(wrap->get_async_id());
|
||||||
ConnectWrap* req_wrap =
|
ConnectWrap* req_wrap =
|
||||||
new ConnectWrap(env, req_wrap_obj, AsyncWrap::PROVIDER_TCPCONNECTWRAP);
|
new ConnectWrap(env, req_wrap_obj, AsyncWrap::PROVIDER_TCPCONNECTWRAP);
|
||||||
err = uv_tcp_connect(req_wrap->req(),
|
err = uv_tcp_connect(req_wrap->req(),
|
||||||
@ -304,7 +304,7 @@ void TCPWrap::Connect6(const FunctionCallbackInfo<Value>& args) {
|
|||||||
int err = uv_ip6_addr(*ip_address, port, &addr);
|
int err = uv_ip6_addr(*ip_address, port, &addr);
|
||||||
|
|
||||||
if (err == 0) {
|
if (err == 0) {
|
||||||
env->set_init_trigger_id(wrap->get_id());
|
env->set_init_trigger_async_id(wrap->get_async_id());
|
||||||
ConnectWrap* req_wrap =
|
ConnectWrap* req_wrap =
|
||||||
new ConnectWrap(env, req_wrap_obj, AsyncWrap::PROVIDER_TCPCONNECTWRAP);
|
new ConnectWrap(env, req_wrap_obj, AsyncWrap::PROVIDER_TCPCONNECTWRAP);
|
||||||
err = uv_tcp_connect(req_wrap->req(),
|
err = uv_tcp_connect(req_wrap->req(),
|
||||||
|
@ -350,7 +350,7 @@ void UDPWrap::DoSend(const FunctionCallbackInfo<Value>& args, int family) {
|
|||||||
node::Utf8Value address(env->isolate(), args[4]);
|
node::Utf8Value address(env->isolate(), args[4]);
|
||||||
const bool have_callback = args[5]->IsTrue();
|
const bool have_callback = args[5]->IsTrue();
|
||||||
|
|
||||||
env->set_init_trigger_id(wrap->get_id());
|
env->set_init_trigger_async_id(wrap->get_async_id());
|
||||||
SendWrap* req_wrap = new SendWrap(env, req_wrap_obj, have_callback);
|
SendWrap* req_wrap = new SendWrap(env, req_wrap_obj, have_callback);
|
||||||
size_t msg_size = 0;
|
size_t msg_size = 0;
|
||||||
|
|
||||||
@ -498,7 +498,7 @@ void UDPWrap::OnRecv(uv_udp_t* handle,
|
|||||||
|
|
||||||
Local<Object> UDPWrap::Instantiate(Environment* env, AsyncWrap* parent) {
|
Local<Object> UDPWrap::Instantiate(Environment* env, AsyncWrap* parent) {
|
||||||
EscapableHandleScope scope(env->isolate());
|
EscapableHandleScope scope(env->isolate());
|
||||||
AsyncHooks::InitScope init_scope(env, parent->get_id());
|
AsyncHooks::InitScope init_scope(env, parent->get_async_id());
|
||||||
// If this assert fires then Initialize hasn't been called yet.
|
// If this assert fires then Initialize hasn't been called yet.
|
||||||
CHECK_EQ(env->udp_constructor_function().IsEmpty(), false);
|
CHECK_EQ(env->udp_constructor_function().IsEmpty(), false);
|
||||||
Local<Object> instance = env->udp_constructor_function()
|
Local<Object> instance = env->udp_constructor_function()
|
||||||
|
@ -74,15 +74,15 @@ if (process.env.NODE_TEST_WITH_ASYNC_HOOKS) {
|
|||||||
util.inspect(initHandles[k]);
|
util.inspect(initHandles[k]);
|
||||||
});
|
});
|
||||||
|
|
||||||
const _addIdToDestroyList = async_wrap.addIdToDestroyList;
|
const _queueDestroyAsyncId = async_wrap.queueDestroyAsyncId;
|
||||||
async_wrap.addIdToDestroyList = function addIdToDestroyList(id) {
|
async_wrap.queueDestroyAsyncId = function queueDestroyAsyncId(id) {
|
||||||
if (destroyListList[id] !== undefined) {
|
if (destroyListList[id] !== undefined) {
|
||||||
process._rawDebug(destroyListList[id]);
|
process._rawDebug(destroyListList[id]);
|
||||||
process._rawDebug();
|
process._rawDebug();
|
||||||
throw new Error(`same id added twice (${id})`);
|
throw new Error(`same id added twice (${id})`);
|
||||||
}
|
}
|
||||||
destroyListList[id] = new Error().stack;
|
destroyListList[id] = new Error().stack;
|
||||||
_addIdToDestroyList(id);
|
_queueDestroyAsyncId(id);
|
||||||
};
|
};
|
||||||
|
|
||||||
require('async_hooks').createHook({
|
require('async_hooks').createHook({
|
||||||
|
@ -32,6 +32,6 @@ hooks = async_hooks.createHook({
|
|||||||
if (n <= 0) return;
|
if (n <= 0) return;
|
||||||
|
|
||||||
test_id = (Math.random() * 1e9) >>> 0;
|
test_id = (Math.random() * 1e9) >>> 0;
|
||||||
async_wrap.addIdToDestroyList(test_id);
|
async_wrap.queueDestroyAsyncId(test_id);
|
||||||
setImmediate(common.mustCall(runner), n - 1);
|
setImmediate(common.mustCall(runner), n - 1);
|
||||||
})(RUNS);
|
})(RUNS);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user