Skip to content

Commit

Permalink
async_hooks: executionAsyncResource matches in hooks
Browse files Browse the repository at this point in the history
Ensure that resource returned by executionAsyncResource() in before
and after hook matches that resource causing this before/after calls.

PR-URL: #31821
Refs: #30959
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Minwoo Jung <nodecorelab@gmail.com>
Reviewed-By: Chengzhong Wu <legendecas@gmail.com>
Reviewed-By: Stephen Belanger <admin@stephenbelanger.com>
Reviewed-By: Vladimir de Turckheim <vlad2t@hotmail.com>
  • Loading branch information
Flarna authored and targos committed Apr 28, 2020
1 parent f7adfcc commit b4ca132
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 9 deletions.
18 changes: 9 additions & 9 deletions src/api/callback.cc
Expand Up @@ -62,16 +62,16 @@ InternalCallbackScope::InternalCallbackScope(Environment* env,
// If you hit this assertion, you forgot to enter the v8::Context first.
CHECK_EQ(Environment::GetCurrent(env->isolate()), env);

env->async_hooks()->push_async_context(
async_context_.async_id, async_context_.trigger_async_id, object);

pushed_ids_ = true;

if (asyncContext.async_id != 0 && !skip_hooks_) {
// No need to check a return value because the application will exit if
// an exception occurs.
AsyncWrap::EmitBefore(env, asyncContext.async_id);
}

env->async_hooks()->push_async_context(async_context_.async_id,
async_context_.trigger_async_id, object);

pushed_ids_ = true;
}

InternalCallbackScope::~InternalCallbackScope() {
Expand All @@ -88,15 +88,15 @@ void InternalCallbackScope::Close() {
env_->async_hooks()->clear_async_id_stack();
}

if (!failed_ && async_context_.async_id != 0 && !skip_hooks_) {
AsyncWrap::EmitAfter(env_, async_context_.async_id);
}

if (pushed_ids_)
env_->async_hooks()->pop_async_context(async_context_.async_id);

if (failed_) return;

if (async_context_.async_id != 0 && !skip_hooks_) {
AsyncWrap::EmitAfter(env_, async_context_.async_id);
}

if (env_->async_callback_scope_depth() > 1 || skip_task_queues_) {
return;
}
Expand Down
62 changes: 62 additions & 0 deletions test/async-hooks/test-async-exec-resource-match.js
@@ -0,0 +1,62 @@
'use strict';

const common = require('../common');
const assert = require('assert');
const { readFile } = require('fs');
const {
createHook,
executionAsyncResource,
AsyncResource
} = require('async_hooks');

// Ignore any asyncIds created before our hook is active.
let firstSeenAsyncId = -1;
const idResMap = new Map();
const numExpectedCalls = 5;

createHook({
init: common.mustCallAtLeast(
(asyncId, type, triggerId, resource) => {
if (firstSeenAsyncId === -1) {
firstSeenAsyncId = asyncId;
}
assert.ok(idResMap.get(asyncId) === undefined);
idResMap.set(asyncId, resource);
}, numExpectedCalls),
before(asyncId) {
if (asyncId >= firstSeenAsyncId) {
beforeHook(asyncId);
}
},
after(asyncId) {
if (asyncId >= firstSeenAsyncId) {
afterHook(asyncId);
}
}
}).enable();

const beforeHook = common.mustCallAtLeast(
(asyncId) => {
const res = idResMap.get(asyncId);
assert.ok(res !== undefined);
const execRes = executionAsyncResource();
assert.ok(execRes === res, 'resource mismatch in before');
}, numExpectedCalls);

const afterHook = common.mustCallAtLeast(
(asyncId) => {
const res = idResMap.get(asyncId);
assert.ok(res !== undefined);
const execRes = executionAsyncResource();
assert.ok(execRes === res, 'resource mismatch in after');
}, numExpectedCalls);

const res = new AsyncResource('TheResource');
const initRes = idResMap.get(res.asyncId());
assert.ok(initRes === res, 'resource mismatch in init');
res.runInAsyncScope(common.mustCall(() => {
const execRes = executionAsyncResource();
assert.ok(execRes === res, 'resource mismatch in cb');
}));

readFile(__filename, common.mustCall());

0 comments on commit b4ca132

Please sign in to comment.