| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent d9b58a0 commit f3563d3
2 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -5,7 +5,6 @@ const { | |||
| 5 | 5 | ErrorCaptureStackTrace, | |
| 6 | 6 | ObjectPrototypeHasOwnProperty, | |
| 7 | 7 | ObjectDefineProperty, | |
| 8 | - Promise, | ||
| 9 | 8 | Symbol, | |
| 10 | 9 | } = primordials; | |
| 11 | 10 | ||
@@ -53,7 +52,7 @@ const { | |||
| 53 | 52 | clearAsyncIdStack, | |
| 54 | 53 | } = async_wrap; | |
| 55 | 54 | // For performance reasons, only track Promises when a hook is enabled. | |
| 56 | - const { enablePromiseHook, disablePromiseHook } = async_wrap; | ||
| 55 | + const { enablePromiseHook, disablePromiseHook, setPromiseHooks } = async_wrap; | ||
| 57 | 56 | // Properties in active_hooks are used to keep track of the set of hooks being | |
| 58 | 57 | // executed in case another hook is enabled/disabled. The new set of hooks is | |
| 59 | 58 | // then restored once the active set of hooks is finished executing. | |
@@ -303,71 +302,68 @@ function restoreActiveHooks() { | |||
| 303 | 302 | active_hooks.tmp_fields = null; | |
| 304 | 303 | } | |
| 305 | 304 | ||
| 306 | - function trackPromise(promise, parent, silent) { | ||
| 307 | - const asyncId = getOrSetAsyncId(promise); | ||
| 305 | + function trackPromise(promise, parent) { | ||
| 306 | + if (promise[async_id_symbol]) { | ||
| 307 | + return; | ||
| 308 | + } | ||
| 308 | 309 | ||
| 310 | + promise[async_id_symbol] = newAsyncId(); | ||
| 309 | 311 | promise[trigger_async_id_symbol] = parent ? getOrSetAsyncId(parent) : | |
| 310 | 312 | getDefaultTriggerAsyncId(); | |
| 313 | + } | ||
| 311 | 314 | ||
| 312 | - if (!silent && initHooksExist()) { | ||
| 313 | - const triggerId = promise[trigger_async_id_symbol]; | ||
| 314 | - emitInitScript(asyncId, 'PROMISE', triggerId, promise); | ||
| 315 | - } | ||
| 315 | + function promiseInitHook(promise, parent) { | ||
| 316 | + trackPromise(promise, parent); | ||
| 317 | + const asyncId = promise[async_id_symbol]; | ||
| 318 | + const triggerAsyncId = promise[trigger_async_id_symbol]; | ||
| 319 | + emitInitScript(asyncId, 'PROMISE', triggerAsyncId, promise); | ||
| 316 | 320 | } | |
| 317 | 321 | ||
| 318 | - function fastPromiseHook(type, promise, parent) { | ||
| 319 | - if (type === kInit || !promise[async_id_symbol]) { | ||
| 320 | - const silent = type !== kInit; | ||
| 321 | - if (parent instanceof Promise) { | ||
| 322 | - trackPromise(promise, parent, silent); | ||
| 323 | - } else { | ||
| 324 | - trackPromise(promise, null, silent); | ||
| 325 | - } | ||
| 322 | + function promiseBeforeHook(promise) { | ||
| 323 | + trackPromise(promise); | ||
| 324 | + const asyncId = promise[async_id_symbol]; | ||
| 325 | + const triggerId = promise[trigger_async_id_symbol]; | ||
| 326 | + emitBeforeScript(asyncId, triggerId, promise); | ||
| 327 | + } | ||
| 326 | 328 | ||
| 327 | - if (!silent) return; | ||
| 329 | + function promiseAfterHook(promise) { | ||
| 330 | + trackPromise(promise); | ||
| 331 | + const asyncId = promise[async_id_symbol]; | ||
| 332 | + if (hasHooks(kAfter)) { | ||
| 333 | + emitAfterNative(asyncId); | ||
| 328 | 334 | } | |
| 335 | + if (asyncId === executionAsyncId()) { | ||
| 336 | + // This condition might not be true if async_hooks was enabled during | ||
| 337 | + // the promise callback execution. | ||
| 338 | + // Popping it off the stack can be skipped in that case, because it is | ||
| 339 | + // known that it would correspond to exactly one call with | ||
| 340 | + // PromiseHookType::kBefore that was not witnessed by the PromiseHook. | ||
| 341 | + popAsyncContext(asyncId); | ||
| 342 | + } | ||
| 343 | + } | ||
| 329 | 344 | ||
| 345 | + function promiseResolveHook(promise) { | ||
| 346 | + trackPromise(promise); | ||
| 330 | 347 | const asyncId = promise[async_id_symbol]; | |
| 331 | - switch (type) { | ||
| 332 | - case kBefore: | ||
| 333 | - const triggerId = promise[trigger_async_id_symbol]; | ||
| 334 | - emitBeforeScript(asyncId, triggerId, promise); | ||
| 335 | - break; | ||
| 336 | - case kAfter: | ||
| 337 | - if (hasHooks(kAfter)) { | ||
| 338 | - emitAfterNative(asyncId); | ||
| 339 | - } | ||
| 340 | - if (asyncId === executionAsyncId()) { | ||
| 341 | - // This condition might not be true if async_hooks was enabled during | ||
| 342 | - // the promise callback execution. | ||
| 343 | - // Popping it off the stack can be skipped in that case, because it is | ||
| 344 | - // known that it would correspond to exactly one call with | ||
| 345 | - // PromiseHookType::kBefore that was not witnessed by the PromiseHook. | ||
| 346 | - popAsyncContext(asyncId); | ||
| 347 | - } | ||
| 348 | - break; | ||
| 349 | - case kPromiseResolve: | ||
| 350 | - emitPromiseResolveNative(asyncId); | ||
| 351 | - break; | ||
| 352 | - } | ||
| 348 | + emitPromiseResolveNative(asyncId); | ||
| 353 | 349 | } | |
| 354 | 350 | ||
| 355 | 351 | let wantPromiseHook = false; | |
| 356 | 352 | function enableHooks() { | |
| 357 | 353 | async_hook_fields[kCheck] += 1; | |
| 358 | 354 | } | |
| 359 | 355 | ||
| 360 | - let promiseHookMode = -1; | ||
| 361 | 356 | function updatePromiseHookMode() { | |
| 362 | 357 | wantPromiseHook = true; | |
| 363 | 358 | if (destroyHooksExist()) { | |
| 364 | - if (promiseHookMode !== 1) { | ||
| 365 | - promiseHookMode = 1; | ||
| 366 | - enablePromiseHook(); | ||
| 367 | - } | ||
| 368 | - } else if (promiseHookMode !== 0) { | ||
| 369 | - promiseHookMode = 0; | ||
| 370 | - enablePromiseHook(fastPromiseHook); | ||
| 359 | + enablePromiseHook(); | ||
| 360 | + } else { | ||
| 361 | + setPromiseHooks( | ||
| 362 | + initHooksExist() ? promiseInitHook : undefined, | ||
| 363 | + promiseBeforeHook, | ||
| 364 | + promiseAfterHook, | ||
| 365 | + promiseResolveHooksExist() ? promiseResolveHook : undefined, | ||
| 366 | + ); | ||
| 371 | 367 | } | |
| 372 | 368 | } | |
| 373 | 369 | ||
@@ -383,8 +379,8 @@ function disableHooks() { | |||
| 383 | 379 | ||
| 384 | 380 | function disablePromiseHookIfNecessary() { | |
| 385 | 381 | if (!wantPromiseHook) { | |
| 386 | - promiseHookMode = -1; | ||
| 387 | 382 | disablePromiseHook(); | |
| 383 | + setPromiseHooks(undefined, undefined, undefined, undefined); | ||
| 388 | 384 | } | |
| 389 | 385 | } | |
| 390 | 386 | ||
@@ -458,6 +454,10 @@ function destroyHooksExist() { | |||
| 458 | 454 | return hasHooks(kDestroy); | |
| 459 | 455 | } | |
| 460 | 456 | ||
| 457 | + function promiseResolveHooksExist() { | ||
| 458 | + return hasHooks(kPromiseResolve); | ||
| 459 | + } | ||
| 460 | + | ||
| 461 | 461 | ||
| 462 | 462 | function emitInitScript(asyncId, type, triggerAsyncId, resource) { | |
| 463 | 463 | // Short circuit all checks for the common case. Which is that no hooks have | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -491,6 +491,15 @@ static void EnablePromiseHook(const FunctionCallbackInfo<Value>& args) { | |||
| 491 | 491 | } | |
| 492 | 492 | } | |
| 493 | 493 | ||
| 494 | + static void SetPromiseHooks(const FunctionCallbackInfo<Value>& args) { | ||
| 495 | + Environment* env = Environment::GetCurrent(args); | ||
| 496 | + Local<Context> ctx = env->context(); | ||
| 497 | + ctx->SetPromiseHooks( | ||
| 498 | + args[0]->IsFunction() ? args[0].As<Function>() : Local<Function>(), | ||
| 499 | + args[1]->IsFunction() ? args[1].As<Function>() : Local<Function>(), | ||
| 500 | + args[2]->IsFunction() ? args[2].As<Function>() : Local<Function>(), | ||
| 501 | + args[3]->IsFunction() ? args[3].As<Function>() : Local<Function>()); | ||
| 502 | + } | ||
| 494 | 503 | ||
| 495 | 504 | static void DisablePromiseHook(const FunctionCallbackInfo<Value>& args) { | |
| 496 | 505 | Environment* env = Environment::GetCurrent(args); | |
@@ -670,6 +679,7 @@ void AsyncWrap::Initialize(Local<Object> target, | |||
| 670 | 679 | env->SetMethod(target, "clearAsyncIdStack", ClearAsyncIdStack); | |
| 671 | 680 | env->SetMethod(target, "queueDestroyAsyncId", QueueDestroyAsyncId); | |
| 672 | 681 | env->SetMethod(target, "enablePromiseHook", EnablePromiseHook); | |
| 682 | + env->SetMethod(target, "setPromiseHooks", SetPromiseHooks); | ||
| 673 | 683 | env->SetMethod(target, "disablePromiseHook", DisablePromiseHook); | |
| 674 | 684 | env->SetMethod(target, "registerDestroyHook", RegisterDestroyHook); | |
| 675 | 685 | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments