diff options
Diffstat (limited to 'lib/internal')
-rw-r--r-- | lib/internal/async_hooks.js | 45 | ||||
-rw-r--r-- | lib/internal/process/task_queues.js | 2 | ||||
-rw-r--r-- | lib/internal/timers.js | 6 |
3 files changed, 37 insertions, 16 deletions
diff --git a/lib/internal/async_hooks.js b/lib/internal/async_hooks.js index 02b0e91ac2..f7a7f7aad6 100644 --- a/lib/internal/async_hooks.js +++ b/lib/internal/async_hooks.js @@ -28,18 +28,26 @@ const async_wrap = internalBinding('async_wrap'); * 3. executionAsyncId of the current resource. * * async_ids_stack is a Float64Array that contains part of the async ID - * stack. Each pushAsyncIds() call adds two doubles to it, and each - * popAsyncIds() call removes two doubles from it. + * stack. Each pushAsyncContext() call adds two doubles to it, and each + * popAsyncContext() call removes two doubles from it. * It has a fixed size, so if that is exceeded, calls to the native - * side are used instead in pushAsyncIds() and popAsyncIds(). + * side are used instead in pushAsyncContext() and popAsyncContext(). */ -const { async_hook_fields, async_id_fields, owner_symbol } = async_wrap; +const { + async_hook_fields, + async_id_fields, + execution_async_resources, + owner_symbol +} = async_wrap; // Store the pair executionAsyncId and triggerAsyncId in a std::stack on // Environment::AsyncHooks::async_ids_stack_ tracks the resource responsible for // the current execution stack. This is unwound as each resource exits. In the // case of a fatal exception this stack is emptied after calling each hook's // after() callback. -const { pushAsyncIds: pushAsyncIds_, popAsyncIds: popAsyncIds_ } = async_wrap; +const { + pushAsyncContext: pushAsyncContext_, + popAsyncContext: popAsyncContext_ +} = async_wrap; // For performance reasons, only track Promises when a hook is enabled. const { enablePromiseHook, disablePromiseHook } = async_wrap; // Properties in active_hooks are used to keep track of the set of hooks being @@ -92,6 +100,15 @@ const emitDestroyNative = emitHookFactory(destroy_symbol, 'emitDestroyNative'); const emitPromiseResolveNative = emitHookFactory(promise_resolve_symbol, 'emitPromiseResolveNative'); +const topLevelResource = {}; + +function executionAsyncResource() { + const index = async_hook_fields[kStackLength] - 1; + if (index === -1) return topLevelResource; + const resource = execution_async_resources[index]; + return resource; +} + // Used to fatally abort the process if a callback throws. function fatalError(e) { if (typeof e.stack === 'string') { @@ -330,8 +347,8 @@ function emitInitScript(asyncId, type, triggerAsyncId, resource) { } -function emitBeforeScript(asyncId, triggerAsyncId) { - pushAsyncIds(asyncId, triggerAsyncId); +function emitBeforeScript(asyncId, triggerAsyncId, resource) { + pushAsyncContext(asyncId, triggerAsyncId, resource); if (async_hook_fields[kBefore] > 0) emitBeforeNative(asyncId); @@ -342,7 +359,7 @@ function emitAfterScript(asyncId) { if (async_hook_fields[kAfter] > 0) emitAfterNative(asyncId); - popAsyncIds(asyncId); + popAsyncContext(asyncId); } @@ -360,6 +377,7 @@ function clearAsyncIdStack() { async_id_fields[kExecutionAsyncId] = 0; async_id_fields[kTriggerAsyncId] = 0; async_hook_fields[kStackLength] = 0; + execution_async_resources.splice(0, execution_async_resources.length); } @@ -369,12 +387,13 @@ function hasAsyncIdStack() { // This is the equivalent of the native push_async_ids() call. -function pushAsyncIds(asyncId, triggerAsyncId) { +function pushAsyncContext(asyncId, triggerAsyncId, resource) { const offset = async_hook_fields[kStackLength]; if (offset * 2 >= async_wrap.async_ids_stack.length) - return pushAsyncIds_(asyncId, triggerAsyncId); + return pushAsyncContext_(asyncId, triggerAsyncId, resource); async_wrap.async_ids_stack[offset * 2] = async_id_fields[kExecutionAsyncId]; async_wrap.async_ids_stack[offset * 2 + 1] = async_id_fields[kTriggerAsyncId]; + execution_async_resources[offset] = resource; async_hook_fields[kStackLength]++; async_id_fields[kExecutionAsyncId] = asyncId; async_id_fields[kTriggerAsyncId] = triggerAsyncId; @@ -382,18 +401,19 @@ function pushAsyncIds(asyncId, triggerAsyncId) { // This is the equivalent of the native pop_async_ids() call. -function popAsyncIds(asyncId) { +function popAsyncContext(asyncId) { const stackLength = async_hook_fields[kStackLength]; if (stackLength === 0) return false; if (enabledHooksExist() && async_id_fields[kExecutionAsyncId] !== asyncId) { // Do the same thing as the native code (i.e. crash hard). - return popAsyncIds_(asyncId); + return popAsyncContext_(asyncId); } const offset = stackLength - 1; async_id_fields[kExecutionAsyncId] = async_wrap.async_ids_stack[2 * offset]; async_id_fields[kTriggerAsyncId] = async_wrap.async_ids_stack[2 * offset + 1]; + execution_async_resources.pop(); async_hook_fields[kStackLength] = offset; return offset > 0; } @@ -426,6 +446,7 @@ module.exports = { clearDefaultTriggerAsyncId, clearAsyncIdStack, hasAsyncIdStack, + executionAsyncResource, // Internal Embedder API newAsyncId, getOrSetAsyncId, diff --git a/lib/internal/process/task_queues.js b/lib/internal/process/task_queues.js index 8b2d2d808a..c07942587c 100644 --- a/lib/internal/process/task_queues.js +++ b/lib/internal/process/task_queues.js @@ -71,7 +71,7 @@ function processTicksAndRejections() { do { while (tock = queue.shift()) { const asyncId = tock[async_id_symbol]; - emitBefore(asyncId, tock[trigger_async_id_symbol]); + emitBefore(asyncId, tock[trigger_async_id_symbol], tock); try { const callback = tock.callback; diff --git a/lib/internal/timers.js b/lib/internal/timers.js index b62ab9499c..bb80f57ee2 100644 --- a/lib/internal/timers.js +++ b/lib/internal/timers.js @@ -96,7 +96,7 @@ const { emitInit, emitBefore, emitAfter, - emitDestroy + emitDestroy, } = require('internal/async_hooks'); // Symbols for storing async id state. @@ -448,7 +448,7 @@ function getTimerCallbacks(runNextTicks) { prevImmediate = immediate; const asyncId = immediate[async_id_symbol]; - emitBefore(asyncId, immediate[trigger_async_id_symbol]); + emitBefore(asyncId, immediate[trigger_async_id_symbol], immediate); try { const argv = immediate._argv; @@ -537,7 +537,7 @@ function getTimerCallbacks(runNextTicks) { continue; } - emitBefore(asyncId, timer[trigger_async_id_symbol]); + emitBefore(asyncId, timer[trigger_async_id_symbol], timer); let start; if (timer._repeat) |