From 1cb50c17d3119a8f315da410ccbf3ad23baf26e1 Mon Sep 17 00:00:00 2001 From: legendecas Date: Wed, 7 Oct 2020 02:05:15 +0800 Subject: [PATCH] n-api: napi_make_callback emit async init with resource of async_context MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit instead of emit async init with receiver of the callback. PR-URL: https://github.com/nodejs/node/pull/32930 Fixes: https://github.com/nodejs/node/issues/32898 Reviewed-By: Stephen Belanger Reviewed-By: Michael Dawson Reviewed-By: Gerhard Stöbich --- doc/api/n-api.md | 36 +++- src/node_api.cc | 187 +++++++++++++----- test/node-api/test_async_context/binding.c | 128 ++++++++++++ test/node-api/test_async_context/binding.gyp | 9 + .../test-gcable-callback.js | 65 ++++++ .../test-gcable.js} | 4 +- test/node-api/test_async_context/test.js | 63 ++++++ test/node-api/test_make_callback/binding.c | 45 +---- .../test_make_callback/test-async-hooks.js | 11 +- test/node-api/test_make_callback/test.js | 15 +- 10 files changed, 465 insertions(+), 98 deletions(-) create mode 100644 test/node-api/test_async_context/binding.c create mode 100644 test/node-api/test_async_context/binding.gyp create mode 100644 test/node-api/test_async_context/test-gcable-callback.js rename test/node-api/{test_make_callback/test-async-hooks-gcable.js => test_async_context/test-gcable.js} (95%) create mode 100644 test/node-api/test_async_context/test.js diff --git a/doc/api/n-api.md b/doc/api/n-api.md index 7c09bdcbd000ef..6a03ffd3d29d34 100644 --- a/doc/api/n-api.md +++ b/doc/api/n-api.md @@ -5167,19 +5167,31 @@ napi_status napi_async_init(napi_env env, * `[in] env`: The environment that the API is invoked under. * `[in] async_resource`: Object associated with the async work - that will be passed to possible `async_hooks` [`init` hooks][]. - In order to retain ABI compatibility with previous versions, - passing `NULL` for `async_resource` does not result in an error. However, - this results in incorrect operation of async hooks for the - napi_async_context created. Potential issues include - loss of async context when using the AsyncLocalStorage API. -* `[in] async_resource_name`: Identifier for the kind of resource - that is being provided for diagnostic information exposed by the - `async_hooks` API. + that will be passed to possible `async_hooks` [`init` hooks][] and can be + accessed by [`async_hooks.executionAsyncResource()`][]. +* `[in] async_resource_name`: Identifier for the kind of resource that is being + provided for diagnostic information exposed by the `async_hooks` API. * `[out] result`: The initialized async context. Returns `napi_ok` if the API succeeded. +The `async_resource` object needs to be kept alive until +[`napi_async_destroy`][] to keep `async_hooks` related API acts correctly. In +order to retain ABI compatibility with previous versions, `napi_async_context`s +are not maintaining the strong reference to the `async_resource` objects to +avoid introducing causing memory leaks. However, if the `async_resource` is +garbage collected by JavaScript engine before the `napi_async_context` was +destroyed by `napi_async_destroy`, calling `napi_async_context` related APIs +like [`napi_open_callback_scope`][] and [`napi_make_callback`][] can cause +problems like loss of async context when using the `AsyncLocalStoage` API. + +In order to retain ABI compatibility with previous versions, passing `NULL` +for `async_resource` does not result in an error. However, this is not +recommended as this will result poor results with `async_hooks` +[`init` hooks][] and `async_hooks.executionAsyncResource()` as the resource is +now required by the underlying `async_hooks` implementation in order to provide +the linkage between async callbacks. + ### napi_async_destroy