summaryrefslogtreecommitdiff
path: root/lib/internal
diff options
context:
space:
mode:
Diffstat (limited to 'lib/internal')
-rw-r--r--lib/internal/async_hooks.js45
-rw-r--r--lib/internal/process/task_queues.js2
-rw-r--r--lib/internal/timers.js6
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)