11cb0ef41Sopenharmony_ci'use strict';
21cb0ef41Sopenharmony_ci
31cb0ef41Sopenharmony_cilet hook;
41cb0ef41Sopenharmony_cilet config;
51cb0ef41Sopenharmony_ci
61cb0ef41Sopenharmony_ciconst {
71cb0ef41Sopenharmony_ci  SafeSet,
81cb0ef41Sopenharmony_ci} = primordials;
91cb0ef41Sopenharmony_ci
101cb0ef41Sopenharmony_cifunction lazyHookCreation() {
111cb0ef41Sopenharmony_ci  const inspector = internalBinding('inspector');
121cb0ef41Sopenharmony_ci  const { createHook } = require('async_hooks');
131cb0ef41Sopenharmony_ci  config = internalBinding('config');
141cb0ef41Sopenharmony_ci
151cb0ef41Sopenharmony_ci  hook = createHook({
161cb0ef41Sopenharmony_ci    init(asyncId, type, triggerAsyncId, resource) {
171cb0ef41Sopenharmony_ci    // It's difficult to tell which tasks will be recurring and which won't,
181cb0ef41Sopenharmony_ci    // therefore we mark all tasks as recurring. Based on the discussion
191cb0ef41Sopenharmony_ci    // in https://github.com/nodejs/node/pull/13870#discussion_r124515293,
201cb0ef41Sopenharmony_ci    // this should be fine as long as we call asyncTaskCanceled() too.
211cb0ef41Sopenharmony_ci      const recurring = true;
221cb0ef41Sopenharmony_ci      if (type === 'PROMISE')
231cb0ef41Sopenharmony_ci        this.promiseIds.add(asyncId);
241cb0ef41Sopenharmony_ci      else
251cb0ef41Sopenharmony_ci        inspector.asyncTaskScheduled(type, asyncId, recurring);
261cb0ef41Sopenharmony_ci    },
271cb0ef41Sopenharmony_ci
281cb0ef41Sopenharmony_ci    before(asyncId) {
291cb0ef41Sopenharmony_ci      if (this.promiseIds.has(asyncId))
301cb0ef41Sopenharmony_ci        return;
311cb0ef41Sopenharmony_ci      inspector.asyncTaskStarted(asyncId);
321cb0ef41Sopenharmony_ci    },
331cb0ef41Sopenharmony_ci
341cb0ef41Sopenharmony_ci    after(asyncId) {
351cb0ef41Sopenharmony_ci      if (this.promiseIds.has(asyncId))
361cb0ef41Sopenharmony_ci        return;
371cb0ef41Sopenharmony_ci      inspector.asyncTaskFinished(asyncId);
381cb0ef41Sopenharmony_ci    },
391cb0ef41Sopenharmony_ci
401cb0ef41Sopenharmony_ci    destroy(asyncId) {
411cb0ef41Sopenharmony_ci      if (this.promiseIds.has(asyncId))
421cb0ef41Sopenharmony_ci        return this.promiseIds.delete(asyncId);
431cb0ef41Sopenharmony_ci      inspector.asyncTaskCanceled(asyncId);
441cb0ef41Sopenharmony_ci    },
451cb0ef41Sopenharmony_ci  });
461cb0ef41Sopenharmony_ci
471cb0ef41Sopenharmony_ci  hook.promiseIds = new SafeSet();
481cb0ef41Sopenharmony_ci}
491cb0ef41Sopenharmony_ci
501cb0ef41Sopenharmony_cifunction enable() {
511cb0ef41Sopenharmony_ci  if (hook === undefined) lazyHookCreation();
521cb0ef41Sopenharmony_ci  if (config.bits < 64) {
531cb0ef41Sopenharmony_ci    // V8 Inspector stores task ids as (void*) pointers.
541cb0ef41Sopenharmony_ci    // async_hooks store ids as 64bit numbers.
551cb0ef41Sopenharmony_ci    // As a result, we cannot reliably translate async_hook ids to V8 async_task
561cb0ef41Sopenharmony_ci    // ids on 32bit platforms.
571cb0ef41Sopenharmony_ci    process.emitWarning(
581cb0ef41Sopenharmony_ci      'Warning: Async stack traces in debugger are not available ' +
591cb0ef41Sopenharmony_ci      `on ${config.bits}bit platforms. The feature is disabled.`,
601cb0ef41Sopenharmony_ci      {
611cb0ef41Sopenharmony_ci        code: 'INSPECTOR_ASYNC_STACK_TRACES_NOT_AVAILABLE',
621cb0ef41Sopenharmony_ci      });
631cb0ef41Sopenharmony_ci  } else {
641cb0ef41Sopenharmony_ci    hook.enable();
651cb0ef41Sopenharmony_ci  }
661cb0ef41Sopenharmony_ci}
671cb0ef41Sopenharmony_ci
681cb0ef41Sopenharmony_cifunction disable() {
691cb0ef41Sopenharmony_ci  if (hook === undefined) lazyHookCreation();
701cb0ef41Sopenharmony_ci  hook.disable();
711cb0ef41Sopenharmony_ci}
721cb0ef41Sopenharmony_ci
731cb0ef41Sopenharmony_cimodule.exports = {
741cb0ef41Sopenharmony_ci  enable,
751cb0ef41Sopenharmony_ci  disable,
761cb0ef41Sopenharmony_ci};
77