async_hooks: reduce duplication with factory
PR-URL: https://github.com/nodejs/node/pull/13755 Reviewed-By: Trevor Norris <trev.norris@gmail.com> Reviewed-By: Refael Ackermann <refack@gmail.com> Reviewed-By: Andreas Madsen <amwebdk@gmail.com>
This commit is contained in:
parent
0011eb28cf
commit
5c6c02996b
@ -49,15 +49,18 @@ const init_symbol = Symbol('init');
|
|||||||
const before_symbol = Symbol('before');
|
const before_symbol = Symbol('before');
|
||||||
const after_symbol = Symbol('after');
|
const after_symbol = Symbol('after');
|
||||||
const destroy_symbol = Symbol('destroy');
|
const destroy_symbol = Symbol('destroy');
|
||||||
|
const emitBeforeNative = emitHookFactory(before_symbol, 'emitBeforeNative');
|
||||||
|
const emitAfterNative = emitHookFactory(after_symbol, 'emitAfterNative');
|
||||||
|
const emitDestroyNative = emitHookFactory(destroy_symbol, 'emitDestroyNative');
|
||||||
|
|
||||||
// Setup the callbacks that node::AsyncWrap will call when there are hooks to
|
// Setup the callbacks that node::AsyncWrap will call when there are hooks to
|
||||||
// process. They use the same functions as the JS embedder API. These callbacks
|
// process. They use the same functions as the JS embedder API. These callbacks
|
||||||
// are setup immediately to prevent async_wrap.setupHooks() from being hijacked
|
// are setup immediately to prevent async_wrap.setupHooks() from being hijacked
|
||||||
// and the cost of doing so is negligible.
|
// and the cost of doing so is negligible.
|
||||||
async_wrap.setupHooks({ init,
|
async_wrap.setupHooks({ init,
|
||||||
before: emitBeforeN,
|
before: emitBeforeNative,
|
||||||
after: emitAfterN,
|
after: emitAfterNative,
|
||||||
destroy: emitDestroyN });
|
destroy: emitDestroyNative });
|
||||||
|
|
||||||
// Used to fatally abort the process if a callback throws.
|
// Used to fatally abort the process if a callback throws.
|
||||||
function fatalError(e) {
|
function fatalError(e) {
|
||||||
@ -325,8 +328,8 @@ function emitInitS(asyncId, type, triggerAsyncId, resource) {
|
|||||||
triggerAsyncId = initTriggerId();
|
triggerAsyncId = initTriggerId();
|
||||||
}
|
}
|
||||||
|
|
||||||
// I'd prefer allowing these checks to not exist, or only throw in a debug
|
// TODO(trevnorris): I'd prefer allowing these checks to not exist, or only
|
||||||
// build, in order to improve performance.
|
// throw in a debug build, in order to improve performance.
|
||||||
if (!Number.isSafeInteger(asyncId) || asyncId < 0)
|
if (!Number.isSafeInteger(asyncId) || asyncId < 0)
|
||||||
throw new RangeError('asyncId must be an unsigned integer');
|
throw new RangeError('asyncId must be an unsigned integer');
|
||||||
if (typeof type !== 'string' || type.length <= 0)
|
if (typeof type !== 'string' || type.length <= 0)
|
||||||
@ -342,24 +345,35 @@ function emitInitS(asyncId, type, triggerAsyncId, resource) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function emitHookFactory(symbol, name) {
|
||||||
function emitBeforeN(asyncId) {
|
// Called from native. The asyncId stack handling is taken care of there
|
||||||
processing_hook = true;
|
// before this is called.
|
||||||
// Use a single try/catch for all hook to avoid setting up one per iteration.
|
// eslint-disable-next-line func-style
|
||||||
try {
|
const fn = function(asyncId) {
|
||||||
for (var i = 0; i < active_hooks_array.length; i++) {
|
processing_hook = true;
|
||||||
if (typeof active_hooks_array[i][before_symbol] === 'function') {
|
// Use a single try/catch for all hook to avoid setting up one per
|
||||||
active_hooks_array[i][before_symbol](asyncId);
|
// iteration.
|
||||||
|
try {
|
||||||
|
for (var i = 0; i < active_hooks_array.length; i++) {
|
||||||
|
if (typeof active_hooks_array[i][symbol] === 'function') {
|
||||||
|
active_hooks_array[i][symbol](asyncId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
} catch (e) {
|
||||||
|
fatalError(e);
|
||||||
}
|
}
|
||||||
} catch (e) {
|
processing_hook = false;
|
||||||
fatalError(e);
|
|
||||||
}
|
|
||||||
processing_hook = false;
|
|
||||||
|
|
||||||
if (tmp_active_hooks_array !== null) {
|
if (tmp_active_hooks_array !== null) {
|
||||||
restoreTmpHooks();
|
restoreTmpHooks();
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
// Set the name property of the anonymous function as it looks good in the
|
||||||
|
// stack trace.
|
||||||
|
Object.defineProperty(fn, 'name', {
|
||||||
|
value: name
|
||||||
|
});
|
||||||
|
return fn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -379,29 +393,7 @@ function emitBeforeS(asyncId, triggerAsyncId = asyncId) {
|
|||||||
|
|
||||||
if (async_hook_fields[kBefore] === 0)
|
if (async_hook_fields[kBefore] === 0)
|
||||||
return;
|
return;
|
||||||
emitBeforeN(asyncId);
|
emitBeforeNative(asyncId);
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Called from native. The asyncId stack handling is taken care of there before
|
|
||||||
// this is called.
|
|
||||||
function emitAfterN(asyncId) {
|
|
||||||
processing_hook = true;
|
|
||||||
// Use a single try/catch for all hook to avoid setting up one per iteration.
|
|
||||||
try {
|
|
||||||
for (var i = 0; i < active_hooks_array.length; i++) {
|
|
||||||
if (typeof active_hooks_array[i][after_symbol] === 'function') {
|
|
||||||
active_hooks_array[i][after_symbol](asyncId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
fatalError(e);
|
|
||||||
}
|
|
||||||
processing_hook = false;
|
|
||||||
|
|
||||||
if (tmp_active_hooks_array !== null) {
|
|
||||||
restoreTmpHooks();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -410,7 +402,7 @@ function emitAfterN(asyncId) {
|
|||||||
// after callbacks.
|
// after callbacks.
|
||||||
function emitAfterS(asyncId) {
|
function emitAfterS(asyncId) {
|
||||||
if (async_hook_fields[kAfter] > 0)
|
if (async_hook_fields[kAfter] > 0)
|
||||||
emitAfterN(asyncId);
|
emitAfterNative(asyncId);
|
||||||
|
|
||||||
popAsyncIds(asyncId);
|
popAsyncIds(asyncId);
|
||||||
}
|
}
|
||||||
@ -425,26 +417,6 @@ function emitDestroyS(asyncId) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function emitDestroyN(asyncId) {
|
|
||||||
processing_hook = true;
|
|
||||||
// Use a single try/catch for all hook to avoid setting up one per iteration.
|
|
||||||
try {
|
|
||||||
for (var i = 0; i < active_hooks_array.length; i++) {
|
|
||||||
if (typeof active_hooks_array[i][destroy_symbol] === 'function') {
|
|
||||||
active_hooks_array[i][destroy_symbol](asyncId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
fatalError(e);
|
|
||||||
}
|
|
||||||
processing_hook = false;
|
|
||||||
|
|
||||||
if (tmp_active_hooks_array !== null) {
|
|
||||||
restoreTmpHooks();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Emit callbacks for native calls. Since some state can be setup directly from
|
// Emit callbacks for native calls. Since some state can be setup directly from
|
||||||
// C++ there's no need to perform all the work here.
|
// C++ there's no need to perform all the work here.
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user