GeezerVison is showing github.com — async_hooks: remove internal only error checking · nodejs/node@9d26358
File treeExpand file treeCollapse file tree Open diff view settings Expand file treeCollapse file tree Open diff view settings Collapse file Copy file name to clipboardExpand all lines: lib/async_hooks.js +6Lines changed: 6 additions & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
| 8 | 8 |
| 9 | 9 | const { | 10 | 10 | ERR_ASYNC_CALLBACK, | | 11 | + ERR_ASYNC_TYPE, | 11 | 12 | ERR_INVALID_ASYNC_ID | 12 | 13 | } = require('internal/errors').codes; | 13 | 14 | const { validateString } = require('internal/validators'); | @@ -31,6 +32,7 @@ const { | 31 | 32 | emitBefore, | 32 | 33 | emitAfter, | 33 | 34 | emitDestroy, | | 35 | + enabledHooksExist, | 34 | 36 | initHooksExist, | 35 | 37 | } = internal_async_hooks; | 36 | 38 |
| @@ -157,6 +159,10 @@ class AsyncResource { | 157 | 159 | this[trigger_async_id_symbol] = triggerAsyncId; | 158 | 160 |
| 159 | 161 | if (initHooksExist()) { | | 162 | + if (enabledHooksExist() && type.length === 0) { | | 163 | + throw new ERR_ASYNC_TYPE(type); | | 164 | + } | | 165 | + | 160 | 166 | emitInit(asyncId, type, triggerAsyncId, this); | 161 | 167 | } | 162 | 168 |
| |
Collapse file Copy file name to clipboardExpand all lines: lib/internal/async_hooks.js +5-37Lines changed: 5 additions & 37 deletions | Original file line number | Diff line number | Diff line change |
|---|
| 3 | 3 | const { | 4 | 4 | Error, | 5 | 5 | FunctionPrototypeBind, | 6 | | - NumberIsSafeInteger, | 7 | 6 | ObjectDefineProperty, | 8 | 7 | Symbol, | 9 | 8 | } = primordials; | 10 | 9 |
| 11 | | -const { | 12 | | - ERR_ASYNC_TYPE, | 13 | | - ERR_INVALID_ASYNC_ID | 14 | | -} = require('internal/errors').codes; | 15 | | - | 16 | 10 | const async_wrap = internalBinding('async_wrap'); | 17 | 11 | /* async_hook_fields is a Uint32Array wrapping the uint32_t array of | 18 | 12 | * Environment::AsyncHooks::fields_[]. Each index tracks the number of active | @@ -117,15 +111,6 @@ function fatalError(e) { | 117 | 111 | } | 118 | 112 |
| 119 | 113 |
| 120 | | -function validateAsyncId(asyncId, type) { | 121 | | - // Skip validation when async_hooks is disabled | 122 | | - if (async_hook_fields[kCheck] <= 0) return; | 123 | | - | 124 | | - if (!NumberIsSafeInteger(asyncId) || asyncId < -1) { | 125 | | - fatalError(new ERR_INVALID_ASYNC_ID(type, asyncId)); | 126 | | - } | 127 | | -} | 128 | | - | 129 | 114 | // Emit From Native // | 130 | 115 |
| 131 | 116 | // Used by C++ to call all init() callbacks. Because some state can be setup | @@ -314,6 +299,9 @@ function defaultTriggerAsyncIdScope(triggerAsyncId, block, ...args) { | 314 | 299 | } | 315 | 300 | } | 316 | 301 |
| | 302 | +function enabledHooksExist() { | | 303 | + return async_hook_fields[kCheck] > 0; | | 304 | +} | 317 | 305 |
| 318 | 306 | function initHooksExist() { | 319 | 307 | return async_hook_fields[kInit] > 0; | @@ -329,21 +317,11 @@ function destroyHooksExist() { | 329 | 317 |
| 330 | 318 |
| 331 | 319 | function emitInitScript(asyncId, type, triggerAsyncId, resource) { | 332 | | - validateAsyncId(asyncId, 'asyncId'); | 333 | | - if (triggerAsyncId !== null) | 334 | | - validateAsyncId(triggerAsyncId, 'triggerAsyncId'); | 335 | | - if (async_hook_fields[kCheck] > 0 && | 336 | | - (typeof type !== 'string' || type.length <= 0)) { | 337 | | - throw new ERR_ASYNC_TYPE(type); | 338 | | - } | 339 | | - | 340 | 320 | // Short circuit all checks for the common case. Which is that no hooks have | 341 | 321 | // been set. Do this to remove performance impact for embedders (and core). | 342 | 322 | if (async_hook_fields[kInit] === 0) | 343 | 323 | return; | 344 | 324 |
| 345 | | - // This can run after the early return check b/c running this function | 346 | | - // manually means that the embedder must have used getDefaultTriggerAsyncId(). | 347 | 325 | if (triggerAsyncId === null) { | 348 | 326 | triggerAsyncId = getDefaultTriggerAsyncId(); | 349 | 327 | } | @@ -353,12 +331,6 @@ function emitInitScript(asyncId, type, triggerAsyncId, resource) { | 353 | 331 |
| 354 | 332 |
| 355 | 333 | function emitBeforeScript(asyncId, triggerAsyncId) { | 356 | | - // Validate the ids. An id of -1 means it was never set and is visible on the | 357 | | - // call graph. An id < -1 should never happen in any circumstance. Throw | 358 | | - // on user calls because async state should still be recoverable. | 359 | | - validateAsyncId(asyncId, 'asyncId'); | 360 | | - validateAsyncId(triggerAsyncId, 'triggerAsyncId'); | 361 | | - | 362 | 334 | pushAsyncIds(asyncId, triggerAsyncId); | 363 | 335 |
| 364 | 336 | if (async_hook_fields[kBefore] > 0) | @@ -367,8 +339,6 @@ function emitBeforeScript(asyncId, triggerAsyncId) { | 367 | 339 |
| 368 | 340 |
| 369 | 341 | function emitAfterScript(asyncId) { | 370 | | - validateAsyncId(asyncId, 'asyncId'); | 371 | | - | 372 | 342 | if (async_hook_fields[kAfter] > 0) | 373 | 343 | emitAfterNative(asyncId); | 374 | 344 |
| @@ -377,8 +347,6 @@ function emitAfterScript(asyncId) { | 377 | 347 |
| 378 | 348 |
| 379 | 349 | function emitDestroyScript(asyncId) { | 380 | | - validateAsyncId(asyncId, 'asyncId'); | 381 | | - | 382 | 350 | // Return early if there are no destroy callbacks, or invalid asyncId. | 383 | 351 | if (async_hook_fields[kDestroy] === 0 || asyncId <= 0) | 384 | 352 | return; | @@ -418,8 +386,7 @@ function popAsyncIds(asyncId) { | 418 | 386 | const stackLength = async_hook_fields[kStackLength]; | 419 | 387 | if (stackLength === 0) return false; | 420 | 388 |
| 421 | | - if (async_hook_fields[kCheck] > 0 && | 422 | | - async_id_fields[kExecutionAsyncId] !== asyncId) { | | 389 | + if (enabledHooksExist() && async_id_fields[kExecutionAsyncId] !== asyncId) { | 423 | 390 | // Do the same thing as the native code (i.e. crash hard). | 424 | 391 | return popAsyncIds_(asyncId); | 425 | 392 | } | @@ -464,6 +431,7 @@ module.exports = { | 464 | 431 | getOrSetAsyncId, | 465 | 432 | getDefaultTriggerAsyncId, | 466 | 433 | defaultTriggerAsyncIdScope, | | 434 | + enabledHooksExist, | 467 | 435 | initHooksExist, | 468 | 436 | afterHooksExist, | 469 | 437 | destroyHooksExist, | |
Collapse file Copy file name to clipboardExpand all lines: test/async-hooks/test-emit-before-after.js +15-33Lines changed: 15 additions & 33 deletions | Original file line number | Diff line number | Diff line change |
|---|
| 3 | 3 |
| 4 | 4 | const common = require('../common'); | 5 | 5 | const assert = require('assert'); | 6 | | -const spawnSync = require('child_process').spawnSync; | 7 | 6 | const async_hooks = require('internal/async_hooks'); | 8 | 7 | const initHooks = require('./init-hooks'); | 9 | 8 |
| 10 | | -if (!common.isMainThread) | 11 | | - common.skip('Worker bootstrapping works differently -> different async IDs'); | 12 | | - | 13 | | -switch (process.argv[2]) { | 14 | | - case 'test_invalid_async_id': | 15 | | - async_hooks.emitBefore(-2, 1); | 16 | | - return; | 17 | | - case 'test_invalid_trigger_id': | 18 | | - async_hooks.emitBefore(1, -2); | 19 | | - return; | 20 | | -} | 21 | | -assert.ok(!process.argv[2]); | 22 | | - | 23 | | - | 24 | | -const c1 = spawnSync(process.execPath, [ | 25 | | - '--expose-internals', __filename, 'test_invalid_async_id' | 26 | | -]); | 27 | | -assert.strictEqual( | 28 | | - c1.stderr.toString().split(/[\r\n]+/g)[0], | 29 | | - 'RangeError [ERR_INVALID_ASYNC_ID]: Invalid asyncId value: -2'); | 30 | | -assert.strictEqual(c1.status, 1); | 31 | | - | 32 | | -const c2 = spawnSync(process.execPath, [ | 33 | | - '--expose-internals', __filename, 'test_invalid_trigger_id' | 34 | | -]); | 35 | | -assert.strictEqual( | 36 | | - c2.stderr.toString().split(/[\r\n]+/g)[0], | 37 | | - 'RangeError [ERR_INVALID_ASYNC_ID]: Invalid triggerAsyncId value: -2'); | 38 | | -assert.strictEqual(c2.status, 1); | 39 | | - | 40 | 9 | const expectedId = async_hooks.newAsyncId(); | 41 | 10 | const expectedTriggerId = async_hooks.newAsyncId(); | 42 | 11 | const expectedType = 'test_emit_before_after_type'; | @@ -45,9 +14,22 @@ const expectedType = 'test_emit_before_after_type'; | 45 | 14 | async_hooks.emitBefore(expectedId, expectedTriggerId); | 46 | 15 | async_hooks.emitAfter(expectedId); | 47 | 16 |
| | 17 | +const chkBefore = common.mustCall((id) => assert.strictEqual(id, expectedId)); | | 18 | +const chkAfter = common.mustCall((id) => assert.strictEqual(id, expectedId)); | | 19 | + | | 20 | +const checkOnce = (fn) => { | | 21 | + let called = false; | | 22 | + return (...args) => { | | 23 | + if (called) return; | | 24 | + | | 25 | + called = true; | | 26 | + fn(...args); | | 27 | + }; | | 28 | +}; | | 29 | + | 48 | 30 | initHooks({ | 49 | | - onbefore: common.mustCall((id) => assert.strictEqual(id, expectedId)), | 50 | | - onafter: common.mustCall((id) => assert.strictEqual(id, expectedId)), | | 31 | + onbefore: checkOnce(chkBefore), | | 32 | + onafter: checkOnce(chkAfter), | 51 | 33 | allowNoInit: true | 52 | 34 | }).enable(); | 53 | 35 |
| |
Collapse file Copy file name to clipboardExpand all lines: test/async-hooks/test-emit-init.js -40Lines changed: 0 additions & 40 deletions | Original file line number | Diff line number | Diff line change |
|---|
| 3 | 3 |
| 4 | 4 | const common = require('../common'); | 5 | 5 | const assert = require('assert'); | 6 | | -const spawnSync = require('child_process').spawnSync; | 7 | 6 | const async_hooks = require('internal/async_hooks'); | 8 | 7 | const initHooks = require('./init-hooks'); | 9 | 8 |
| @@ -23,45 +22,6 @@ const hooks1 = initHooks({ | 23 | 22 |
| 24 | 23 | hooks1.enable(); | 25 | 24 |
| 26 | | -switch (process.argv[2]) { | 27 | | - case 'test_invalid_async_id': | 28 | | - async_hooks.emitInit(); | 29 | | - return; | 30 | | - case 'test_invalid_trigger_id': | 31 | | - async_hooks.emitInit(expectedId); | 32 | | - return; | 33 | | - case 'test_invalid_trigger_id_negative': | 34 | | - async_hooks.emitInit(expectedId, expectedType, -2); | 35 | | - return; | 36 | | -} | 37 | | -assert.ok(!process.argv[2]); | 38 | | - | 39 | | - | 40 | | -const c1 = spawnSync(process.execPath, [ | 41 | | - '--expose-internals', __filename, 'test_invalid_async_id' | 42 | | -]); | 43 | | -assert.strictEqual( | 44 | | - c1.stderr.toString().split(/[\r\n]+/g)[0], | 45 | | - 'RangeError [ERR_INVALID_ASYNC_ID]: Invalid asyncId value: undefined'); | 46 | | -assert.strictEqual(c1.status, 1); | 47 | | - | 48 | | -const c2 = spawnSync(process.execPath, [ | 49 | | - '--expose-internals', __filename, 'test_invalid_trigger_id' | 50 | | -]); | 51 | | -assert.strictEqual( | 52 | | - c2.stderr.toString().split(/[\r\n]+/g)[0], | 53 | | - 'RangeError [ERR_INVALID_ASYNC_ID]: Invalid triggerAsyncId value: undefined'); | 54 | | -assert.strictEqual(c2.status, 1); | 55 | | - | 56 | | -const c3 = spawnSync(process.execPath, [ | 57 | | - '--expose-internals', __filename, 'test_invalid_trigger_id_negative' | 58 | | -]); | 59 | | -assert.strictEqual( | 60 | | - c3.stderr.toString().split(/[\r\n]+/g)[0], | 61 | | - 'RangeError [ERR_INVALID_ASYNC_ID]: Invalid triggerAsyncId value: -2'); | 62 | | -assert.strictEqual(c3.status, 1); | 63 | | - | 64 | | - | 65 | 25 | async_hooks.emitInit(expectedId, expectedType, expectedTriggerId, | 66 | 26 | expectedResource); | 67 | 27 |
| |
|