@ -58,8 +58,8 @@ const active_hooks = {
// Each constant tracks how many callbacks there are for any given step of
// Each constant tracks how many callbacks there are for any given step of
// async execution. These are tracked so if the user didn't include callbacks
// async execution. These are tracked so if the user didn't include callbacks
// for a given step, that step can bail out early.
// for a given step, that step can bail out early.
const { kInit , kBefore , kAfter , kDestroy , kTotals , kCurrentAsyncId ,
const { kInit , kBefore , kAfter , kDestroy , kPromiseResolve , kTotals ,
kCurrentTriggerId , kAsyncUidCntr ,
kCurrentAsyncId , kCurrent TriggerId , kAsyncUidCntr ,
kInitTriggerId } = async_wrap . constants ;
kInitTriggerId } = async_wrap . constants ;
// Symbols used to store the respective ids on both AsyncResource instances and
// Symbols used to store the respective ids on both AsyncResource instances and
@ -72,9 +72,12 @@ const init_symbol = Symbol('init');
const before_symbol = Symbol ( 'before' ) ;
const before_symbol = Symbol ( 'before' ) ;
const after_symbol = Symbol ( 'after' ) ;
const after_symbol = Symbol ( 'after' ) ;
const destroy_symbol = Symbol ( 'destroy' ) ;
const destroy_symbol = Symbol ( 'destroy' ) ;
const promise_resolve_symbol = Symbol ( 'promiseResolve' ) ;
const emitBeforeNative = emitHookFactory ( before_symbol , 'emitBeforeNative' ) ;
const emitBeforeNative = emitHookFactory ( before_symbol , 'emitBeforeNative' ) ;
const emitAfterNative = emitHookFactory ( after_symbol , 'emitAfterNative' ) ;
const emitAfterNative = emitHookFactory ( after_symbol , 'emitAfterNative' ) ;
const emitDestroyNative = emitHookFactory ( destroy_symbol , 'emitDestroyNative' ) ;
const emitDestroyNative = emitHookFactory ( destroy_symbol , 'emitDestroyNative' ) ;
const emitPromiseResolveNative =
emitHookFactory ( promise_resolve_symbol , 'emitPromiseResolveNative' ) ;
// TODO(refack): move to node-config.cc
// TODO(refack): move to node-config.cc
const abort_regex = /^--abort[_-]on[_-]uncaught[_-]exception$/ ;
const abort_regex = /^--abort[_-]on[_-]uncaught[_-]exception$/ ;
@ -86,7 +89,8 @@ const abort_regex = /^--abort[_-]on[_-]uncaught[_-]exception$/;
async_wrap . setupHooks ( { init : emitInitNative ,
async_wrap . setupHooks ( { init : emitInitNative ,
before : emitBeforeNative ,
before : emitBeforeNative ,
after : emitAfterNative ,
after : emitAfterNative ,
destroy : emitDestroyNative } ) ;
destroy : emitDestroyNative ,
promise_resolve : emitPromiseResolveNative } ) ;
// Used to fatally abort the process if a callback throws.
// Used to fatally abort the process if a callback throws.
function fatalError ( e ) {
function fatalError ( e ) {
@ -107,7 +111,7 @@ function fatalError(e) {
// Public API //
// Public API //
class AsyncHook {
class AsyncHook {
constructor ( { init , before , after , destroy } ) {
constructor ( { init , before , after , destroy , promiseResolve } ) {
if ( init !== undefined && typeof init !== 'function' )
if ( init !== undefined && typeof init !== 'function' )
throw new errors . TypeError ( 'ERR_ASYNC_CALLBACK' , 'init' ) ;
throw new errors . TypeError ( 'ERR_ASYNC_CALLBACK' , 'init' ) ;
if ( before !== undefined && typeof before !== 'function' )
if ( before !== undefined && typeof before !== 'function' )
@ -116,11 +120,14 @@ class AsyncHook {
throw new errors . TypeError ( 'ERR_ASYNC_CALLBACK' , 'before' ) ;
throw new errors . TypeError ( 'ERR_ASYNC_CALLBACK' , 'before' ) ;
if ( destroy !== undefined && typeof destroy !== 'function' )
if ( destroy !== undefined && typeof destroy !== 'function' )
throw new errors . TypeError ( 'ERR_ASYNC_CALLBACK' , 'before' ) ;
throw new errors . TypeError ( 'ERR_ASYNC_CALLBACK' , 'before' ) ;
if ( promiseResolve !== undefined && typeof promiseResolve !== 'function' )
throw new errors . TypeError ( 'ERR_ASYNC_CALLBACK' , 'promiseResolve' ) ;
this [ init_symbol ] = init ;
this [ init_symbol ] = init ;
this [ before_symbol ] = before ;
this [ before_symbol ] = before ;
this [ after_symbol ] = after ;
this [ after_symbol ] = after ;
this [ destroy_symbol ] = destroy ;
this [ destroy_symbol ] = destroy ;
this [ promise_resolve_symbol ] = promiseResolve ;
}
}
enable ( ) {
enable ( ) {
@ -144,6 +151,8 @@ class AsyncHook {
hook_fields [ kTotals ] += hook_fields [ kBefore ] += + ! ! this [ before_symbol ] ;
hook_fields [ kTotals ] += hook_fields [ kBefore ] += + ! ! this [ before_symbol ] ;
hook_fields [ kTotals ] += hook_fields [ kAfter ] += + ! ! this [ after_symbol ] ;
hook_fields [ kTotals ] += hook_fields [ kAfter ] += + ! ! this [ after_symbol ] ;
hook_fields [ kTotals ] += hook_fields [ kDestroy ] += + ! ! this [ destroy_symbol ] ;
hook_fields [ kTotals ] += hook_fields [ kDestroy ] += + ! ! this [ destroy_symbol ] ;
hook_fields [ kTotals ] +=
hook_fields [ kPromiseResolve ] += + ! ! this [ promise_resolve_symbol ] ;
hooks_array . push ( this ) ;
hooks_array . push ( this ) ;
if ( prev_kTotals === 0 && hook_fields [ kTotals ] > 0 )
if ( prev_kTotals === 0 && hook_fields [ kTotals ] > 0 )
@ -166,6 +175,8 @@ class AsyncHook {
hook_fields [ kTotals ] += hook_fields [ kBefore ] -= + ! ! this [ before_symbol ] ;
hook_fields [ kTotals ] += hook_fields [ kBefore ] -= + ! ! this [ before_symbol ] ;
hook_fields [ kTotals ] += hook_fields [ kAfter ] -= + ! ! this [ after_symbol ] ;
hook_fields [ kTotals ] += hook_fields [ kAfter ] -= + ! ! this [ after_symbol ] ;
hook_fields [ kTotals ] += hook_fields [ kDestroy ] -= + ! ! this [ destroy_symbol ] ;
hook_fields [ kTotals ] += hook_fields [ kDestroy ] -= + ! ! this [ destroy_symbol ] ;
hook_fields [ kTotals ] +=
hook_fields [ kPromiseResolve ] -= + ! ! this [ promise_resolve_symbol ] ;
hooks_array . splice ( index , 1 ) ;
hooks_array . splice ( index , 1 ) ;
if ( prev_kTotals > 0 && hook_fields [ kTotals ] === 0 )
if ( prev_kTotals > 0 && hook_fields [ kTotals ] === 0 )
@ -198,6 +209,7 @@ function storeActiveHooks() {
active_hooks . tmp_fields [ kBefore ] = async_hook_fields [ kBefore ] ;
active_hooks . tmp_fields [ kBefore ] = async_hook_fields [ kBefore ] ;
active_hooks . tmp_fields [ kAfter ] = async_hook_fields [ kAfter ] ;
active_hooks . tmp_fields [ kAfter ] = async_hook_fields [ kAfter ] ;
active_hooks . tmp_fields [ kDestroy ] = async_hook_fields [ kDestroy ] ;
active_hooks . tmp_fields [ kDestroy ] = async_hook_fields [ kDestroy ] ;
active_hooks . tmp_fields [ kPromiseResolve ] = async_hook_fields [ kPromiseResolve ] ;
}
}
@ -209,6 +221,7 @@ function restoreActiveHooks() {
async_hook_fields [ kBefore ] = active_hooks . tmp_fields [ kBefore ] ;
async_hook_fields [ kBefore ] = active_hooks . tmp_fields [ kBefore ] ;
async_hook_fields [ kAfter ] = active_hooks . tmp_fields [ kAfter ] ;
async_hook_fields [ kAfter ] = active_hooks . tmp_fields [ kAfter ] ;
async_hook_fields [ kDestroy ] = active_hooks . tmp_fields [ kDestroy ] ;
async_hook_fields [ kDestroy ] = active_hooks . tmp_fields [ kDestroy ] ;
async_hook_fields [ kPromiseResolve ] = active_hooks . tmp_fields [ kPromiseResolve ] ;
active_hooks . tmp_array = null ;
active_hooks . tmp_array = null ;
active_hooks . tmp_fields = null ;
active_hooks . tmp_fields = null ;