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
|
||||
* 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
|
||||
* 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.
|
||||
* kCurrentTriggerId: The trigger_async_id of the resource responsible for the
|
||||
* current execution stack.
|
||||
* kAsyncUidCntr: Incremental counter tracking the next assigned async_id.
|
||||
* kInitTriggerId: Written immediately before a resource's constructor that
|
||||
* sets the value of the init()'s triggerAsyncId. The order of retrieving
|
||||
* the triggerAsyncId value is passing directly to the constructor -> value
|
||||
* set in kInitTriggerId -> executionAsyncId of the current resource.
|
||||
* kTriggerAsyncId: The trigger_async_id of the resource responsible for
|
||||
* the current execution stack.
|
||||
* kAsyncIdCounter: Incremental counter tracking the next assigned async_id.
|
||||
* kInitTriggerAsyncId: Written immediately before a resource's constructor
|
||||
* that sets the value of the init()'s triggerAsyncId. The order of
|
||||
* retrieving the triggerAsyncId value is passing directly to the
|
||||
* 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
|
||||
// Environment::AsyncHooks::ids_stack_ tracks the resource responsible for the
|
||||
// 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
|
||||
// async execution. These are tracked so if the user didn't include callbacks
|
||||
// for a given step, that step can bail out early.
|
||||
const { kInit, kBefore, kAfter, kDestroy, kPromiseResolve, kTotals,
|
||||
kCurrentAsyncId, kCurrentTriggerId, kAsyncUidCntr,
|
||||
kInitTriggerId } = async_wrap.constants;
|
||||
const { kInit, kBefore, kAfter, kDestroy, kTotals, kPromiseResolve,
|
||||
kExecutionAsyncId, kTriggerAsyncId, kAsyncIdCounter,
|
||||
kInitTriggerAsyncId } = async_wrap.constants;
|
||||
|
||||
// Symbols used to store the respective ids on both AsyncResource instances and
|
||||
// internal resources. They will also be assigned to arbitrary objects passed
|
||||
// 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.
|
||||
const init_symbol = Symbol('init');
|
||||
@ -234,12 +235,12 @@ function createHook(fns) {
|
||||
|
||||
|
||||
function executionAsyncId() {
|
||||
return async_uid_fields[kCurrentAsyncId];
|
||||
return async_id_fields[kExecutionAsyncId];
|
||||
}
|
||||
|
||||
|
||||
function triggerAsyncId() {
|
||||
return async_uid_fields[kCurrentTriggerId];
|
||||
return async_id_fields[kTriggerAsyncId];
|
||||
}
|
||||
|
||||
|
||||
@ -258,14 +259,16 @@ class AsyncResource {
|
||||
triggerAsyncId);
|
||||
}
|
||||
|
||||
this[async_id_symbol] = ++async_uid_fields[kAsyncUidCntr];
|
||||
this[trigger_id_symbol] = triggerAsyncId;
|
||||
this[async_id_symbol] = ++async_id_fields[kAsyncIdCounter];
|
||||
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() {
|
||||
emitBeforeScript(this[async_id_symbol], this[trigger_id_symbol]);
|
||||
emitBeforeScript(this[async_id_symbol], this[trigger_async_id_symbol]);
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -284,7 +287,7 @@ class AsyncResource {
|
||||
}
|
||||
|
||||
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
|
||||
// Environment::new_async_uid()
|
||||
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
|
||||
// constructor is complete.
|
||||
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
|
||||
// inherit it by accident.
|
||||
async_uid_fields[kInitTriggerId] = 0;
|
||||
if (tId <= 0)
|
||||
tId = async_uid_fields[kCurrentAsyncId];
|
||||
return tId;
|
||||
async_id_fields[kInitTriggerAsyncId] = 0;
|
||||
if (triggerAsyncId <= 0)
|
||||
triggerAsyncId = async_id_fields[kExecutionAsyncId];
|
||||
return triggerAsyncId;
|
||||
}
|
||||
|
||||
|
||||
function setInitTriggerId(triggerAsyncId) {
|
||||
// CHECK(Number.isSafeInteger(triggerAsyncId))
|
||||
// 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) {
|
||||
triggerAsyncId = initTriggerId();
|
||||
} else {
|
||||
// If a triggerAsyncId was passed, any kInitTriggerId still must be null'd.
|
||||
async_uid_fields[kInitTriggerId] = 0;
|
||||
// If a triggerAsyncId was passed, any kInitTriggerAsyncId still must be
|
||||
// null'd.
|
||||
async_id_fields[kInitTriggerAsyncId] = 0;
|
||||
}
|
||||
|
||||
if (!Number.isSafeInteger(asyncId) || asyncId < -1) {
|
||||
@ -446,7 +450,7 @@ function emitDestroyScript(asyncId) {
|
||||
// Return early if there are no destroy callbacks, or invalid asyncId.
|
||||
if (async_hook_fields[kDestroy] === 0 || asyncId <= 0)
|
||||
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() {
|
||||
const async_wrap = process.binding('async_wrap');
|
||||
// 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.
|
||||
const { clearIdStack, asyncIdStackSize } = async_wrap;
|
||||
const { kAfter, kCurrentAsyncId, kInitTriggerId } = async_wrap.constants;
|
||||
const { clearAsyncIdStack, asyncIdStackSize } = async_wrap;
|
||||
const { kAfter, kExecutionAsyncId,
|
||||
kInitTriggerAsyncId } = async_wrap.constants;
|
||||
|
||||
process._fatalException = function(er) {
|
||||
var caught;
|
||||
|
||||
// It's possible that kInitTriggerId was set for a constructor call that
|
||||
// threw and was never cleared. So clear it now.
|
||||
async_uid_fields[kInitTriggerId] = 0;
|
||||
// It's possible that kInitTriggerAsyncId was set for a constructor call
|
||||
// that threw and was never cleared. So clear it now.
|
||||
async_id_fields[kInitTriggerAsyncId] = 0;
|
||||
|
||||
if (process.domain && process.domain._errorHandler)
|
||||
caught = process.domain._errorHandler(er);
|
||||
@ -392,11 +393,11 @@
|
||||
if (async_hook_fields[kAfter] > 0) {
|
||||
do {
|
||||
NativeModule.require('async_hooks').emitAfter(
|
||||
async_uid_fields[kCurrentAsyncId]);
|
||||
async_id_fields[kExecutionAsyncId]);
|
||||
} while (asyncIdStackSize() > 0);
|
||||
// Or completely empty the id stack.
|
||||
} else {
|
||||
clearIdStack();
|
||||
clearAsyncIdStack();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -54,12 +54,12 @@ function setupNextTick() {
|
||||
const emitPendingUnhandledRejections = promises.setup(scheduleMicrotasks);
|
||||
const initTriggerId = async_hooks.initTriggerId;
|
||||
// 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.
|
||||
const { emitInit, emitBefore, emitAfter, emitDestroy } = async_hooks;
|
||||
// Grab the constants necessary for working with internal arrays.
|
||||
const { kInit, kDestroy, kAsyncUidCntr } = async_wrap.constants;
|
||||
const { async_id_symbol, trigger_id_symbol } = async_wrap;
|
||||
const { kInit, kDestroy, kAsyncIdCounter } = async_wrap.constants;
|
||||
const { async_id_symbol, trigger_async_id_symbol } = async_wrap;
|
||||
var nextTickQueue = new NextTickQueue();
|
||||
var microtasksScheduled = false;
|
||||
|
||||
@ -102,7 +102,7 @@ function setupNextTick() {
|
||||
args: undefined,
|
||||
domain: null,
|
||||
[async_id_symbol]: 0,
|
||||
[trigger_id_symbol]: 0
|
||||
[trigger_async_id_symbol]: 0
|
||||
};
|
||||
function scheduleMicrotasks() {
|
||||
if (microtasksScheduled)
|
||||
@ -158,10 +158,10 @@ function setupNextTick() {
|
||||
|
||||
// CHECK(Number.isSafeInteger(tock[async_id_symbol]))
|
||||
// CHECK(tock[async_id_symbol] > 0)
|
||||
// CHECK(Number.isSafeInteger(tock[trigger_id_symbol]))
|
||||
// CHECK(tock[trigger_id_symbol] > 0)
|
||||
// CHECK(Number.isSafeInteger(tock[trigger_async_id_symbol]))
|
||||
// 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
|
||||
// that calls the destroy callback in the future. It's called before
|
||||
// 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(tock[async_id_symbol] > 0)
|
||||
// CHECK(Number.isSafeInteger(tock[trigger_id_symbol]))
|
||||
// CHECK(tock[trigger_id_symbol] > 0)
|
||||
// CHECK(Number.isSafeInteger(tock[trigger_async_id_symbol]))
|
||||
// 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
|
||||
// isn't a good solution.
|
||||
if (async_hook_fields[kDestroy] > 0)
|
||||
@ -236,7 +236,7 @@ function setupNextTick() {
|
||||
this.args = args;
|
||||
this.domain = process.domain || null;
|
||||
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];
|
||||
}
|
||||
|
||||
const asyncId = ++async_uid_fields[kAsyncUidCntr];
|
||||
const asyncId = ++async_id_fields[kAsyncIdCounter];
|
||||
const triggerAsyncId = initTriggerId();
|
||||
const obj = new TickObject(callback, args, asyncId, triggerAsyncId);
|
||||
nextTickQueue.push(obj);
|
||||
@ -297,7 +297,7 @@ function setupNextTick() {
|
||||
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);
|
||||
nextTickQueue.push(obj);
|
||||
++tickInfo[kLength];
|
||||
|
@ -34,14 +34,14 @@ const debug = util.debuglog('timer');
|
||||
const kOnTimeout = TimerWrap.kOnTimeout | 0;
|
||||
const initTriggerId = async_hooks.initTriggerId;
|
||||
// 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.
|
||||
const { emitInit, emitBefore, emitAfter, emitDestroy } = async_hooks;
|
||||
// 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.
|
||||
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.
|
||||
const TIMEOUT_MAX = 2147483647; // 2^31-1
|
||||
@ -169,10 +169,12 @@ function insert(item, unrefed) {
|
||||
|
||||
if (!item[async_id_symbol] || item._destroyed) {
|
||||
item._destroyed = false;
|
||||
item[async_id_symbol] = ++async_uid_fields[kAsyncUidCntr];
|
||||
item[trigger_id_symbol] = initTriggerId();
|
||||
item[async_id_symbol] = ++async_id_fields[kAsyncIdCounter];
|
||||
item[trigger_async_id_symbol] = initTriggerId();
|
||||
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);
|
||||
@ -291,7 +293,7 @@ function tryOnTimeout(timer, list) {
|
||||
timer[async_id_symbol] : null;
|
||||
var threw = true;
|
||||
if (timerAsyncId !== null)
|
||||
emitBefore(timerAsyncId, timer[trigger_id_symbol]);
|
||||
emitBefore(timerAsyncId, timer[trigger_async_id_symbol]);
|
||||
try {
|
||||
ontimeout(timer);
|
||||
threw = false;
|
||||
@ -560,10 +562,12 @@ function Timeout(after, callback, args) {
|
||||
this._timerArgs = args;
|
||||
this._repeat = null;
|
||||
this._destroyed = false;
|
||||
this[async_id_symbol] = ++async_uid_fields[kAsyncUidCntr];
|
||||
this[trigger_id_symbol] = initTriggerId();
|
||||
this[async_id_symbol] = ++async_id_fields[kAsyncIdCounter];
|
||||
this[trigger_async_id_symbol] = initTriggerId();
|
||||
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.
|
||||
function tryOnImmediate(immediate, oldTail) {
|
||||
var threw = true;
|
||||
emitBefore(immediate[async_id_symbol], immediate[trigger_id_symbol]);
|
||||
emitBefore(immediate[async_id_symbol], immediate[trigger_async_id_symbol]);
|
||||
try {
|
||||
// make the actual call outside the try/finally to allow it to be optimized
|
||||
runCallback(immediate);
|
||||
@ -798,10 +802,12 @@ function Immediate() {
|
||||
this._onImmediate = null;
|
||||
this._destroyed = false;
|
||||
this.domain = process.domain;
|
||||
this[async_id_symbol] = ++async_uid_fields[kAsyncUidCntr];
|
||||
this[trigger_id_symbol] = initTriggerId();
|
||||
this[async_id_symbol] = ++async_id_fields[kAsyncIdCounter];
|
||||
this[trigger_async_id_symbol] = initTriggerId();
|
||||
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) {
|
||||
|
@ -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_;
|
||||
}
|
||||
|
||||
|
||||
inline double AsyncWrap::get_trigger_id() const {
|
||||
return trigger_id_;
|
||||
inline double AsyncWrap::get_trigger_async_id() const {
|
||||
return trigger_async_id_;
|
||||
}
|
||||
|
||||
|
||||
|
@ -140,8 +140,8 @@ RetainedObjectInfo* WrapperInfo(uint16_t class_id, Local<Value> wrapper) {
|
||||
// end RetainedAsyncInfo
|
||||
|
||||
|
||||
static void DestroyIdsCb(uv_timer_t* handle) {
|
||||
Environment* env = Environment::from_destroy_ids_timer_handle(handle);
|
||||
static void DestroyAsyncIdsCallback(uv_timer_t* handle) {
|
||||
Environment* env = Environment::from_destroy_async_ids_timer_handle(handle);
|
||||
|
||||
HandleScope handle_scope(env->isolate());
|
||||
Context::Scope context_scope(env->context());
|
||||
@ -150,15 +150,15 @@ static void DestroyIdsCb(uv_timer_t* handle) {
|
||||
TryCatch try_catch(env->isolate());
|
||||
|
||||
do {
|
||||
std::vector<double> destroy_ids_list;
|
||||
destroy_ids_list.swap(*env->destroy_ids_list());
|
||||
for (auto current_id : destroy_ids_list) {
|
||||
std::vector<double> destroy_async_id_list;
|
||||
destroy_async_id_list.swap(*env->destroy_async_id_list());
|
||||
for (auto async_id : destroy_async_id_list) {
|
||||
// Want each callback to be cleaned up after itself, instead of cleaning
|
||||
// them all up after the while() loop completes.
|
||||
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(
|
||||
env->context(), Undefined(env->isolate()), 1, &argv);
|
||||
env->context(), Undefined(env->isolate()), 1, &async_id_value);
|
||||
|
||||
if (ret.IsEmpty()) {
|
||||
ClearFatalExceptionHandlers(env);
|
||||
@ -166,18 +166,19 @@ static void DestroyIdsCb(uv_timer_t* handle) {
|
||||
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)
|
||||
return;
|
||||
|
||||
if (env->destroy_ids_list()->empty())
|
||||
uv_timer_start(env->destroy_ids_timer_handle(), DestroyIdsCb, 0, 0);
|
||||
if (env->destroy_async_id_list()->empty())
|
||||
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)
|
||||
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();
|
||||
TryCatch try_catch(env->isolate());
|
||||
MaybeLocal<Value> ar = fn->Call(
|
||||
env->context(), Undefined(env->isolate()), 1, &uid);
|
||||
env->context(), Undefined(env->isolate()), 1, &async_id_value);
|
||||
if (ar.IsEmpty()) {
|
||||
ClearFatalExceptionHandlers(env);
|
||||
FatalException(env->isolate(), try_catch);
|
||||
@ -206,11 +207,11 @@ void AsyncWrap::EmitBefore(Environment* env, double async_id) {
|
||||
if (async_hooks->fields()[AsyncHooks::kBefore] == 0)
|
||||
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();
|
||||
TryCatch try_catch(env->isolate());
|
||||
MaybeLocal<Value> ar = fn->Call(
|
||||
env->context(), Undefined(env->isolate()), 1, &uid);
|
||||
env->context(), Undefined(env->isolate()), 1, &async_id_value);
|
||||
if (ar.IsEmpty()) {
|
||||
ClearFatalExceptionHandlers(env);
|
||||
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
|
||||
// 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();
|
||||
TryCatch try_catch(env->isolate());
|
||||
MaybeLocal<Value> ar = fn->Call(
|
||||
env->context(), Undefined(env->isolate()), 1, &uid);
|
||||
env->context(), Undefined(env->isolate()), 1, &async_id_value);
|
||||
if (ar.IsEmpty()) {
|
||||
ClearFatalExceptionHandlers(env);
|
||||
FatalException(env->isolate(), try_catch);
|
||||
@ -248,7 +249,7 @@ class PromiseWrap : public AsyncWrap {
|
||||
size_t self_size() const override { return sizeof(*this); }
|
||||
|
||||
static constexpr int kPromiseField = 1;
|
||||
static constexpr int kParentIdField = 2;
|
||||
static constexpr int kParentAsyncIdField = 2;
|
||||
static constexpr int kInternalFieldCount = 3;
|
||||
|
||||
static PromiseWrap* New(Environment* env,
|
||||
@ -257,7 +258,7 @@ class PromiseWrap : public AsyncWrap {
|
||||
bool silent);
|
||||
static void GetPromise(Local<String> property,
|
||||
const PropertyCallbackInfo<Value>& info);
|
||||
static void GetParentId(Local<String> property,
|
||||
static void getParentAsyncId(Local<String> property,
|
||||
const PropertyCallbackInfo<Value>& info);
|
||||
};
|
||||
|
||||
@ -269,9 +270,9 @@ PromiseWrap* PromiseWrap::New(Environment* env,
|
||||
->NewInstance(env->context()).ToLocalChecked();
|
||||
object->SetInternalField(PromiseWrap::kPromiseField, promise);
|
||||
if (parent_wrap != nullptr) {
|
||||
object->SetInternalField(PromiseWrap::kParentIdField,
|
||||
object->SetInternalField(PromiseWrap::kParentAsyncIdField,
|
||||
Number::New(env->isolate(),
|
||||
parent_wrap->get_id()));
|
||||
parent_wrap->get_async_id()));
|
||||
}
|
||||
CHECK_EQ(promise->GetAlignedPointerFromInternalField(0), nullptr);
|
||||
promise->SetInternalField(0, object);
|
||||
@ -283,9 +284,10 @@ void PromiseWrap::GetPromise(Local<String> property,
|
||||
info.GetReturnValue().Set(info.Holder()->GetInternalField(kPromiseField));
|
||||
}
|
||||
|
||||
void PromiseWrap::GetParentId(Local<String> property,
|
||||
void PromiseWrap::getParentAsyncId(Local<String> property,
|
||||
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,
|
||||
@ -317,8 +319,8 @@ static void PromiseHook(PromiseHookType type, Local<Promise> promise,
|
||||
parent_wrap = PromiseWrap::New(env, parent_promise, nullptr, true);
|
||||
}
|
||||
// get id from parentWrap
|
||||
double trigger_id = parent_wrap->get_id();
|
||||
env->set_init_trigger_id(trigger_id);
|
||||
double trigger_async_id = parent_wrap->get_async_id();
|
||||
env->set_init_trigger_async_id(trigger_async_id);
|
||||
}
|
||||
|
||||
wrap = PromiseWrap::New(env, promise, parent_wrap, silent);
|
||||
@ -326,20 +328,21 @@ static void PromiseHook(PromiseHookType type, Local<Promise> promise,
|
||||
|
||||
CHECK_NE(wrap, nullptr);
|
||||
if (type == PromiseHookType::kBefore) {
|
||||
env->async_hooks()->push_ids(wrap->get_id(), wrap->get_trigger_id());
|
||||
AsyncWrap::EmitBefore(wrap->env(), wrap->get_id());
|
||||
env->async_hooks()->push_async_ids(
|
||||
wrap->get_async_id(), wrap->get_trigger_async_id());
|
||||
AsyncWrap::EmitBefore(wrap->env(), wrap->get_async_id());
|
||||
} else if (type == PromiseHookType::kAfter) {
|
||||
AsyncWrap::EmitAfter(wrap->env(), wrap->get_id());
|
||||
if (env->current_async_id() == wrap->get_id()) {
|
||||
AsyncWrap::EmitAfter(wrap->env(), wrap->get_async_id());
|
||||
if (env->execution_async_id() == wrap->get_async_id()) {
|
||||
// This condition might not be true if async_hooks was enabled during
|
||||
// the promise callback execution.
|
||||
// Popping it off the stack can be skipped in that case, because is is
|
||||
// known that it would correspond to exactly one call with
|
||||
// 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) {
|
||||
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);
|
||||
promise_wrap_template->SetAccessor(
|
||||
FIXED_ONE_BYTE_STRING(env->isolate(), "parentId"),
|
||||
PromiseWrap::GetParentId);
|
||||
PromiseWrap::getParentAsyncId);
|
||||
env->set_promise_wrap_template(promise_wrap_template);
|
||||
}
|
||||
}
|
||||
@ -411,24 +414,24 @@ void AsyncWrap::GetAsyncId(const FunctionCallbackInfo<Value>& args) {
|
||||
AsyncWrap* wrap;
|
||||
args.GetReturnValue().Set(-1);
|
||||
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) {
|
||||
Environment* env = Environment::GetCurrent(args);
|
||||
// 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 trigger_id = args[1]->NumberValue(env->context()).FromJust();
|
||||
env->async_hooks()->push_ids(async_id, trigger_id);
|
||||
double trigger_async_id = args[1]->NumberValue(env->context()).FromJust();
|
||||
env->async_hooks()->push_async_ids(async_id, trigger_async_id);
|
||||
}
|
||||
|
||||
|
||||
void AsyncWrap::PopAsyncIds(const FunctionCallbackInfo<Value>& args) {
|
||||
Environment* env = Environment::GetCurrent(args);
|
||||
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);
|
||||
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());
|
||||
PushBackDestroyId(Environment::GetCurrent(args), args[0]->NumberValue());
|
||||
PushBackDestroyAsyncId(Environment::GetCurrent(args), args[0]->NumberValue());
|
||||
}
|
||||
|
||||
void AsyncWrap::AddWrapMethods(Environment* env,
|
||||
@ -476,8 +479,8 @@ void AsyncWrap::Initialize(Local<Object> target,
|
||||
env->SetMethod(target, "pushAsyncIds", PushAsyncIds);
|
||||
env->SetMethod(target, "popAsyncIds", PopAsyncIds);
|
||||
env->SetMethod(target, "asyncIdStackSize", AsyncIdStackSize);
|
||||
env->SetMethod(target, "clearIdStack", ClearIdStack);
|
||||
env->SetMethod(target, "addIdToDestroyList", QueueDestroyId);
|
||||
env->SetMethod(target, "clearAsyncIdStack", ClearAsyncIdStack);
|
||||
env->SetMethod(target, "queueDestroyAsyncId", QueueDestroyAsyncId);
|
||||
env->SetMethod(target, "enablePromiseHook", EnablePromiseHook);
|
||||
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.
|
||||
//
|
||||
// kInitTriggerId: Write the id of the resource responsible for a handle's
|
||||
// creation just before calling the new handle's constructor. After the new
|
||||
// handle is constructed kInitTriggerId is set back to 0.
|
||||
// kInitTriggerAsyncId: Write the id of the resource responsible for a
|
||||
// handle's creation just before calling the new handle's constructor.
|
||||
// After the new handle is constructed kInitTriggerAsyncId is set back to 0.
|
||||
FORCE_SET_TARGET_FIELD(target,
|
||||
"async_uid_fields",
|
||||
env->async_hooks()->uid_fields().GetJSArray());
|
||||
"async_id_fields",
|
||||
env->async_hooks()->async_id_fields().GetJSArray());
|
||||
|
||||
Local<Object> constants = Object::New(isolate);
|
||||
#define SET_HOOKS_CONSTANT(name) \
|
||||
@ -522,10 +525,10 @@ void AsyncWrap::Initialize(Local<Object> target,
|
||||
SET_HOOKS_CONSTANT(kDestroy);
|
||||
SET_HOOKS_CONSTANT(kPromiseResolve);
|
||||
SET_HOOKS_CONSTANT(kTotals);
|
||||
SET_HOOKS_CONSTANT(kCurrentAsyncId);
|
||||
SET_HOOKS_CONSTANT(kCurrentTriggerId);
|
||||
SET_HOOKS_CONSTANT(kAsyncUidCntr);
|
||||
SET_HOOKS_CONSTANT(kInitTriggerId);
|
||||
SET_HOOKS_CONSTANT(kExecutionAsyncId);
|
||||
SET_HOOKS_CONSTANT(kTriggerAsyncId);
|
||||
SET_HOOKS_CONSTANT(kAsyncIdCounter);
|
||||
SET_HOOKS_CONSTANT(kInitTriggerAsyncId);
|
||||
#undef SET_HOOKS_CONSTANT
|
||||
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")));
|
||||
FORCE_SET_TARGET_FIELD(
|
||||
target,
|
||||
"trigger_id_symbol",
|
||||
Symbol::New(isolate, FIXED_ONE_BYTE_STRING(isolate, "triggerId")));
|
||||
"trigger_async_id_symbol",
|
||||
Symbol::New(isolate, FIXED_ONE_BYTE_STRING(isolate, "triggerAsyncId")));
|
||||
|
||||
#undef FORCE_SET_TARGET_FIELD
|
||||
|
||||
@ -586,7 +589,7 @@ AsyncWrap::AsyncWrap(Environment* env,
|
||||
|
||||
|
||||
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.
|
||||
void AsyncWrap::AsyncReset(bool silent) {
|
||||
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;
|
||||
|
||||
EmitAsyncInit(env(), object(),
|
||||
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<String> type,
|
||||
double async_id,
|
||||
double trigger_id) {
|
||||
double trigger_async_id) {
|
||||
CHECK(!object.IsEmpty());
|
||||
CHECK(!type.IsEmpty());
|
||||
AsyncHooks* async_hooks = env->async_hooks();
|
||||
@ -625,7 +628,7 @@ void AsyncWrap::EmitAsyncInit(Environment* env,
|
||||
Local<Value> argv[] = {
|
||||
Number::New(env->isolate(), async_id),
|
||||
type,
|
||||
Number::New(env->isolate(), trigger_id),
|
||||
Number::New(env->isolate(), trigger_async_id),
|
||||
object,
|
||||
};
|
||||
|
||||
@ -643,7 +646,7 @@ void AsyncWrap::EmitAsyncInit(Environment* env,
|
||||
MaybeLocal<Value> AsyncWrap::MakeCallback(const Local<Function> cb,
|
||||
int argc,
|
||||
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);
|
||||
}
|
||||
|
||||
@ -652,12 +655,12 @@ MaybeLocal<Value> AsyncWrap::MakeCallback(const Local<Function> cb,
|
||||
|
||||
|
||||
async_id AsyncHooksGetExecutionAsyncId(Isolate* isolate) {
|
||||
return Environment::GetCurrent(isolate)->current_async_id();
|
||||
return Environment::GetCurrent(isolate)->execution_async_id();
|
||||
}
|
||||
|
||||
|
||||
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
|
||||
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 = {
|
||||
env->new_async_id(), // async_id_
|
||||
@ -694,7 +697,8 @@ async_context EmitAsyncInit(Isolate* isolate,
|
||||
}
|
||||
|
||||
void EmitAsyncDestroy(Isolate* isolate, async_context asyncContext) {
|
||||
PushBackDestroyId(Environment::GetCurrent(isolate), asyncContext.async_id);
|
||||
PushBackDestroyAsyncId(Environment::GetCurrent(isolate),
|
||||
asyncContext.async_id);
|
||||
}
|
||||
|
||||
} // namespace node
|
||||
|
@ -111,15 +111,17 @@ class AsyncWrap : public BaseObject {
|
||||
static void PushAsyncIds(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 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 QueueDestroyId(const v8::FunctionCallbackInfo<v8::Value>& args);
|
||||
static void QueueDestroyAsyncId(
|
||||
const v8::FunctionCallbackInfo<v8::Value>& args);
|
||||
|
||||
static void EmitAsyncInit(Environment* env,
|
||||
v8::Local<v8::Object> object,
|
||||
v8::Local<v8::String> type,
|
||||
double id,
|
||||
double trigger_id);
|
||||
double trigger_async_id);
|
||||
|
||||
static void EmitBefore(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 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);
|
||||
|
||||
@ -152,7 +154,7 @@ class AsyncWrap : public BaseObject {
|
||||
const ProviderType provider_type_;
|
||||
// Because the values may be Reset(), cannot be made const.
|
||||
double async_id_;
|
||||
double trigger_id_;
|
||||
double trigger_async_id_;
|
||||
};
|
||||
|
||||
void LoadAsyncWrapperInfo(Environment* env);
|
||||
|
@ -51,7 +51,7 @@ void ConnectionWrap<WrapType, UVType>::OnConnection(uv_stream_t* handle,
|
||||
};
|
||||
|
||||
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.
|
||||
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)
|
||||
: isolate_(isolate),
|
||||
fields_(isolate, kFieldsCount),
|
||||
uid_fields_(isolate, kUidFieldsCount) {
|
||||
async_id_fields_(isolate, kUidFieldsCount) {
|
||||
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()).
|
||||
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
|
||||
// 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>&
|
||||
Environment::AsyncHooks::uid_fields() {
|
||||
return uid_fields_;
|
||||
Environment::AsyncHooks::async_id_fields() {
|
||||
return async_id_fields_;
|
||||
}
|
||||
|
||||
inline int Environment::AsyncHooks::uid_fields_count() const {
|
||||
inline int Environment::AsyncHooks::async_id_fields_count() const {
|
||||
return kUidFieldsCount;
|
||||
}
|
||||
|
||||
@ -129,29 +129,29 @@ inline v8::Local<v8::String> Environment::AsyncHooks::provider_string(int idx) {
|
||||
return providers_[idx].Get(isolate_);
|
||||
}
|
||||
|
||||
inline void Environment::AsyncHooks::push_ids(double async_id,
|
||||
double trigger_id) {
|
||||
inline void Environment::AsyncHooks::push_async_ids(double async_id,
|
||||
double trigger_async_id) {
|
||||
CHECK_GE(async_id, -1);
|
||||
CHECK_GE(trigger_id, -1);
|
||||
CHECK_GE(trigger_async_id, -1);
|
||||
|
||||
ids_stack_.push({ uid_fields_[kCurrentAsyncId],
|
||||
uid_fields_[kCurrentTriggerId] });
|
||||
uid_fields_[kCurrentAsyncId] = async_id;
|
||||
uid_fields_[kCurrentTriggerId] = trigger_id;
|
||||
async_ids_stack_.push({ async_id_fields_[kExecutionAsyncId],
|
||||
async_id_fields_[kTriggerAsyncId] });
|
||||
async_id_fields_[kExecutionAsyncId] = async_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
|
||||
// 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
|
||||
// hasn't been corrupted.
|
||||
if (uid_fields_[kCurrentAsyncId] != async_id) {
|
||||
if (async_id_fields_[kExecutionAsyncId] != async_id) {
|
||||
fprintf(stderr,
|
||||
"Error: async hook stack has become corrupted ("
|
||||
"actual: %.f, expected: %.f)\n",
|
||||
uid_fields_.GetValue(kCurrentAsyncId),
|
||||
async_id_fields_.GetValue(kExecutionAsyncId),
|
||||
async_id);
|
||||
Environment* env = Environment::GetCurrent(isolate_);
|
||||
DumpBacktrace(stderr);
|
||||
@ -163,35 +163,37 @@ inline bool Environment::AsyncHooks::pop_ids(double async_id) {
|
||||
ABORT_NO_BACKTRACE();
|
||||
}
|
||||
|
||||
auto ids = ids_stack_.top();
|
||||
ids_stack_.pop();
|
||||
uid_fields_[kCurrentAsyncId] = ids.async_id;
|
||||
uid_fields_[kCurrentTriggerId] = ids.trigger_id;
|
||||
return !ids_stack_.empty();
|
||||
auto async_ids = async_ids_stack_.top();
|
||||
async_ids_stack_.pop();
|
||||
async_id_fields_[kExecutionAsyncId] = async_ids.async_id;
|
||||
async_id_fields_[kTriggerAsyncId] = async_ids.trigger_async_id;
|
||||
return !async_ids_stack_.empty();
|
||||
}
|
||||
|
||||
inline size_t Environment::AsyncHooks::stack_size() {
|
||||
return ids_stack_.size();
|
||||
return async_ids_stack_.size();
|
||||
}
|
||||
|
||||
inline void Environment::AsyncHooks::clear_id_stack() {
|
||||
while (!ids_stack_.empty())
|
||||
ids_stack_.pop();
|
||||
uid_fields_[kCurrentAsyncId] = 0;
|
||||
uid_fields_[kCurrentTriggerId] = 0;
|
||||
inline void Environment::AsyncHooks::clear_async_id_stack() {
|
||||
while (!async_ids_stack_.empty())
|
||||
async_ids_stack_.pop();
|
||||
async_id_fields_[kExecutionAsyncId] = 0;
|
||||
async_id_fields_[kTriggerAsyncId] = 0;
|
||||
}
|
||||
|
||||
inline Environment::AsyncHooks::InitScope::InitScope(
|
||||
Environment* env, double init_trigger_id)
|
||||
Environment* env, double init_trigger_async_id)
|
||||
: env_(env),
|
||||
uid_fields_ref_(env->async_hooks()->uid_fields()) {
|
||||
CHECK_GE(init_trigger_id, -1);
|
||||
env->async_hooks()->push_ids(uid_fields_ref_[AsyncHooks::kCurrentAsyncId],
|
||||
init_trigger_id);
|
||||
async_id_fields_ref_(env->async_hooks()->async_id_fields()) {
|
||||
CHECK_GE(init_trigger_async_id, -1);
|
||||
env->async_hooks()->push_async_ids(
|
||||
async_id_fields_ref_[AsyncHooks::kExecutionAsyncId],
|
||||
init_trigger_async_id);
|
||||
}
|
||||
|
||||
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)
|
||||
@ -306,7 +308,7 @@ inline Environment::Environment(IsolateData* isolate_data,
|
||||
|
||||
AssignToContext(context);
|
||||
|
||||
destroy_ids_list_.reserve(512);
|
||||
destroy_async_id_list_.reserve(512);
|
||||
performance_state_ = Calloc<performance::performance_state>(1);
|
||||
performance_state_->milestones[
|
||||
performance::NODE_PERFORMANCE_MILESTONE_ENVIRONMENT] =
|
||||
@ -358,13 +360,13 @@ inline uv_idle_t* Environment::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) {
|
||||
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() {
|
||||
return &destroy_ids_timer_handle_;
|
||||
inline uv_timer_t* Environment::destroy_async_ids_timer_handle() {
|
||||
return &destroy_async_ids_timer_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;
|
||||
}
|
||||
|
||||
inline std::vector<double>* Environment::destroy_ids_list() {
|
||||
return &destroy_ids_list_;
|
||||
inline std::vector<double>* Environment::destroy_async_id_list() {
|
||||
return &destroy_async_id_list_;
|
||||
}
|
||||
|
||||
inline double Environment::new_async_id() {
|
||||
async_hooks()->uid_fields()[AsyncHooks::kAsyncUidCntr] =
|
||||
async_hooks()->uid_fields()[AsyncHooks::kAsyncUidCntr] + 1;
|
||||
return async_hooks()->uid_fields()[AsyncHooks::kAsyncUidCntr];
|
||||
async_hooks()->async_id_fields()[AsyncHooks::kAsyncIdCounter] =
|
||||
async_hooks()->async_id_fields()[AsyncHooks::kAsyncIdCounter] + 1;
|
||||
return async_hooks()->async_id_fields()[AsyncHooks::kAsyncIdCounter];
|
||||
}
|
||||
|
||||
inline double Environment::current_async_id() {
|
||||
return async_hooks()->uid_fields()[AsyncHooks::kCurrentAsyncId];
|
||||
inline double Environment::execution_async_id() {
|
||||
return async_hooks()->async_id_fields()[AsyncHooks::kExecutionAsyncId];
|
||||
}
|
||||
|
||||
inline double Environment::trigger_id() {
|
||||
return async_hooks()->uid_fields()[AsyncHooks::kCurrentTriggerId];
|
||||
inline double Environment::trigger_async_id() {
|
||||
return async_hooks()->async_id_fields()[AsyncHooks::kTriggerAsyncId];
|
||||
}
|
||||
|
||||
inline double Environment::get_init_trigger_id() {
|
||||
AliasedBuffer<double, v8::Float64Array>& uid_fields =
|
||||
async_hooks()->uid_fields();
|
||||
double tid = uid_fields[AsyncHooks::kInitTriggerId];
|
||||
uid_fields[AsyncHooks::kInitTriggerId] = 0;
|
||||
if (tid <= 0) tid = current_async_id();
|
||||
inline double Environment::get_init_trigger_async_id() {
|
||||
AliasedBuffer<double, v8::Float64Array>& async_id_fields =
|
||||
async_hooks()->async_id_fields();
|
||||
double tid = async_id_fields[AsyncHooks::kInitTriggerAsyncId];
|
||||
async_id_fields[AsyncHooks::kInitTriggerAsyncId] = 0;
|
||||
if (tid <= 0) tid = execution_async_id();
|
||||
return tid;
|
||||
}
|
||||
|
||||
inline void Environment::set_init_trigger_id(const double id) {
|
||||
async_hooks()->uid_fields()[AsyncHooks::kInitTriggerId] = id;
|
||||
inline void Environment::set_init_trigger_async_id(const double id) {
|
||||
async_hooks()->async_id_fields()[AsyncHooks::kInitTriggerAsyncId] = id;
|
||||
}
|
||||
|
||||
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_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) {
|
||||
handle->data = env;
|
||||
@ -75,7 +75,7 @@ void Environment::Start(int argc,
|
||||
close_and_finish,
|
||||
nullptr);
|
||||
RegisterHandleCleanup(
|
||||
reinterpret_cast<uv_handle_t*>(&destroy_ids_timer_handle_),
|
||||
reinterpret_cast<uv_handle_t*>(&destroy_async_ids_timer_handle_),
|
||||
close_and_finish,
|
||||
nullptr);
|
||||
|
||||
|
53
src/env.h
53
src/env.h
@ -332,7 +332,7 @@ class Environment;
|
||||
|
||||
struct node_async_ids {
|
||||
double async_id;
|
||||
double trigger_id;
|
||||
double trigger_async_id;
|
||||
};
|
||||
|
||||
class IsolateData {
|
||||
@ -388,10 +388,10 @@ class Environment {
|
||||
};
|
||||
|
||||
enum UidFields {
|
||||
kCurrentAsyncId,
|
||||
kCurrentTriggerId,
|
||||
kAsyncUidCntr,
|
||||
kInitTriggerId,
|
||||
kExecutionAsyncId,
|
||||
kTriggerAsyncId,
|
||||
kAsyncIdCounter,
|
||||
kInitTriggerAsyncId,
|
||||
kUidFieldsCount,
|
||||
};
|
||||
|
||||
@ -400,28 +400,28 @@ class Environment {
|
||||
inline AliasedBuffer<uint32_t, v8::Uint32Array>& fields();
|
||||
inline int fields_count() const;
|
||||
|
||||
inline AliasedBuffer<double, v8::Float64Array>& uid_fields();
|
||||
inline int uid_fields_count() const;
|
||||
inline AliasedBuffer<double, v8::Float64Array>& async_id_fields();
|
||||
inline int async_id_fields_count() const;
|
||||
|
||||
inline v8::Local<v8::String> provider_string(int idx);
|
||||
|
||||
inline void push_ids(double async_id, double trigger_id);
|
||||
inline bool pop_ids(double async_id);
|
||||
inline void push_async_ids(double async_id, double trigger_async_id);
|
||||
inline bool pop_async_id(double async_id);
|
||||
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
|
||||
// resources using RAII. Instead of needing to pass the trigger_id along
|
||||
// with other constructor arguments.
|
||||
// Used to propagate the trigger_async_id to the constructor of any newly
|
||||
// created resources using RAII. Instead of needing to pass the
|
||||
// trigger_async_id along with other constructor arguments.
|
||||
class InitScope {
|
||||
public:
|
||||
InitScope() = delete;
|
||||
explicit InitScope(Environment* env, double init_trigger_id);
|
||||
explicit InitScope(Environment* env, double init_trigger_async_id);
|
||||
~InitScope();
|
||||
|
||||
private:
|
||||
Environment* env_;
|
||||
AliasedBuffer<double, v8::Float64Array> uid_fields_ref_;
|
||||
AliasedBuffer<double, v8::Float64Array> async_id_fields_ref_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(InitScope);
|
||||
};
|
||||
@ -434,12 +434,12 @@ class Environment {
|
||||
// Used by provider_string().
|
||||
v8::Isolate* isolate_;
|
||||
// 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
|
||||
// each type.
|
||||
AliasedBuffer<uint32_t, v8::Uint32Array> fields_;
|
||||
// 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);
|
||||
};
|
||||
@ -549,10 +549,11 @@ class Environment {
|
||||
inline uint32_t watched_providers() const;
|
||||
|
||||
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_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.
|
||||
inline void RegisterHandleCleanup(uv_handle_t* handle,
|
||||
@ -581,13 +582,13 @@ class Environment {
|
||||
|
||||
// The necessary API for async_hooks.
|
||||
inline double new_async_id();
|
||||
inline double current_async_id();
|
||||
inline double trigger_id();
|
||||
inline double get_init_trigger_id();
|
||||
inline void set_init_trigger_id(const double id);
|
||||
inline double execution_async_id();
|
||||
inline double trigger_async_id();
|
||||
inline double get_init_trigger_async_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.
|
||||
inline std::vector<double>* destroy_ids_list();
|
||||
inline std::vector<double>* destroy_async_id_list();
|
||||
|
||||
std::unordered_multimap<int, loader::ModuleWrap*> module_map;
|
||||
|
||||
@ -686,7 +687,7 @@ class Environment {
|
||||
IsolateData* const isolate_data_;
|
||||
uv_check_t immediate_check_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_check_t idle_check_handle_;
|
||||
|
||||
@ -700,7 +701,7 @@ class Environment {
|
||||
bool abort_on_uncaught_exception_;
|
||||
bool emit_napi_warning_;
|
||||
size_t makecallback_cntr_;
|
||||
std::vector<double> destroy_ids_list_;
|
||||
std::vector<double> destroy_async_id_list_;
|
||||
|
||||
performance::performance_state* performance_state_ = nullptr;
|
||||
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);
|
||||
}
|
||||
|
||||
env->async_hooks()->push_ids(async_context_.async_id,
|
||||
env->async_hooks()->push_async_ids(async_context_.async_id,
|
||||
async_context_.trigger_async_id);
|
||||
pushed_ids_ = true;
|
||||
}
|
||||
@ -1396,7 +1396,7 @@ void InternalCallbackScope::Close() {
|
||||
HandleScope handle_scope(env_->isolate());
|
||||
|
||||
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;
|
||||
|
||||
@ -1420,8 +1420,8 @@ void InternalCallbackScope::Close() {
|
||||
|
||||
// Make sure the stack unwound properly. If there are nested MakeCallback's
|
||||
// then it should return early and not reach this code.
|
||||
CHECK_EQ(env_->current_async_id(), 0);
|
||||
CHECK_EQ(env_->trigger_id(), 0);
|
||||
CHECK_EQ(env_->execution_async_id(), 0);
|
||||
CHECK_EQ(env_->trigger_async_id(), 0);
|
||||
|
||||
Local<Object> process = env_->process_object();
|
||||
|
||||
@ -1430,8 +1430,8 @@ void InternalCallbackScope::Close() {
|
||||
return;
|
||||
}
|
||||
|
||||
CHECK_EQ(env_->current_async_id(), 0);
|
||||
CHECK_EQ(env_->trigger_id(), 0);
|
||||
CHECK_EQ(env_->execution_async_id(), 0);
|
||||
CHECK_EQ(env_->trigger_async_id(), 0);
|
||||
|
||||
if (env_->tick_callback_function()->Call(process, 0, nullptr).IsEmpty()) {
|
||||
failed_ = true;
|
||||
@ -4695,9 +4695,9 @@ inline int Start(Isolate* isolate, IsolateData* isolate_data,
|
||||
|
||||
{
|
||||
Environment::AsyncCallbackScope callback_scope(&env);
|
||||
env.async_hooks()->push_ids(1, 0);
|
||||
env.async_hooks()->push_async_ids(1, 0);
|
||||
LoadEnvironment(&env);
|
||||
env.async_hooks()->pop_ids(1);
|
||||
env.async_hooks()->pop_async_id(1);
|
||||
}
|
||||
|
||||
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
|
||||
* 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
|
||||
* 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());
|
||||
// Should always be called from the same context.
|
||||
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->Init(type);
|
||||
}
|
||||
|
@ -52,7 +52,7 @@ using AsyncHooks = Environment::AsyncHooks;
|
||||
|
||||
Local<Object> PipeWrap::Instantiate(Environment* env, AsyncWrap* parent) {
|
||||
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());
|
||||
Local<Function> constructor = env->pipe_constructor_template()->GetFunction();
|
||||
CHECK_EQ(false, constructor.IsEmpty());
|
||||
|
@ -136,7 +136,7 @@ void StreamBase::JSMethod(const FunctionCallbackInfo<Value>& args) {
|
||||
if (!wrap->IsAlive())
|
||||
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));
|
||||
}
|
||||
|
||||
|
@ -55,7 +55,7 @@ int StreamBase::Shutdown(const FunctionCallbackInfo<Value>& args) {
|
||||
|
||||
AsyncWrap* wrap = GetAsyncWrap();
|
||||
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,
|
||||
req_wrap_obj,
|
||||
this,
|
||||
@ -160,7 +160,7 @@ int StreamBase::Writev(const FunctionCallbackInfo<Value>& args) {
|
||||
|
||||
wrap = GetAsyncWrap();
|
||||
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);
|
||||
|
||||
offset = 0;
|
||||
@ -249,7 +249,7 @@ int StreamBase::WriteBuffer(const FunctionCallbackInfo<Value>& args) {
|
||||
|
||||
wrap = GetAsyncWrap();
|
||||
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
|
||||
req_wrap = WriteWrap::New(env, req_wrap_obj, this, AfterWrite);
|
||||
|
||||
@ -334,7 +334,7 @@ int StreamBase::WriteString(const FunctionCallbackInfo<Value>& args) {
|
||||
|
||||
wrap = GetAsyncWrap();
|
||||
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);
|
||||
|
||||
data = req_wrap->Extra();
|
||||
|
@ -55,7 +55,7 @@ using AsyncHooks = Environment::AsyncHooks;
|
||||
|
||||
Local<Object> TCPWrap::Instantiate(Environment* env, AsyncWrap* parent) {
|
||||
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);
|
||||
Local<Function> constructor = env->tcp_constructor_template()->GetFunction();
|
||||
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);
|
||||
|
||||
if (err == 0) {
|
||||
env->set_init_trigger_id(wrap->get_id());
|
||||
env->set_init_trigger_async_id(wrap->get_async_id());
|
||||
ConnectWrap* req_wrap =
|
||||
new ConnectWrap(env, req_wrap_obj, AsyncWrap::PROVIDER_TCPCONNECTWRAP);
|
||||
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);
|
||||
|
||||
if (err == 0) {
|
||||
env->set_init_trigger_id(wrap->get_id());
|
||||
env->set_init_trigger_async_id(wrap->get_async_id());
|
||||
ConnectWrap* req_wrap =
|
||||
new ConnectWrap(env, req_wrap_obj, AsyncWrap::PROVIDER_TCPCONNECTWRAP);
|
||||
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]);
|
||||
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);
|
||||
size_t msg_size = 0;
|
||||
|
||||
@ -498,7 +498,7 @@ void UDPWrap::OnRecv(uv_udp_t* handle,
|
||||
|
||||
Local<Object> UDPWrap::Instantiate(Environment* env, AsyncWrap* parent) {
|
||||
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.
|
||||
CHECK_EQ(env->udp_constructor_function().IsEmpty(), false);
|
||||
Local<Object> instance = env->udp_constructor_function()
|
||||
|
@ -74,15 +74,15 @@ if (process.env.NODE_TEST_WITH_ASYNC_HOOKS) {
|
||||
util.inspect(initHandles[k]);
|
||||
});
|
||||
|
||||
const _addIdToDestroyList = async_wrap.addIdToDestroyList;
|
||||
async_wrap.addIdToDestroyList = function addIdToDestroyList(id) {
|
||||
const _queueDestroyAsyncId = async_wrap.queueDestroyAsyncId;
|
||||
async_wrap.queueDestroyAsyncId = function queueDestroyAsyncId(id) {
|
||||
if (destroyListList[id] !== undefined) {
|
||||
process._rawDebug(destroyListList[id]);
|
||||
process._rawDebug();
|
||||
throw new Error(`same id added twice (${id})`);
|
||||
}
|
||||
destroyListList[id] = new Error().stack;
|
||||
_addIdToDestroyList(id);
|
||||
_queueDestroyAsyncId(id);
|
||||
};
|
||||
|
||||
require('async_hooks').createHook({
|
||||
|
@ -32,6 +32,6 @@ hooks = async_hooks.createHook({
|
||||
if (n <= 0) return;
|
||||
|
||||
test_id = (Math.random() * 1e9) >>> 0;
|
||||
async_wrap.addIdToDestroyList(test_id);
|
||||
async_wrap.queueDestroyAsyncId(test_id);
|
||||
setImmediate(common.mustCall(runner), n - 1);
|
||||
})(RUNS);
|
||||
|
Loading…
x
Reference in New Issue
Block a user