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 <[email protected]>
Reviewed-By: Minwoo Jung <[email protected]>
Reviewed-By: Chengzhong Wu <[email protected]>
Reviewed-By: Stephen Belanger <[email protected]>
Reviewed-By: Vladimir de Turckheim <[email protected]>
  • Loading branch information
Flarna authored and codebytere committed Feb 27, 2020
1 parent ae3929e commit 6af9e7e
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
@@ -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 6af9e7e

Please sign in to comment.