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.
  • Loading branch information
Flarna committed Feb 26, 2020
1 parent fb73045 commit 19fbe32
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 19fbe32

Please sign in to comment.