diff options
author | Jason Ginchereau <jasongin@microsoft.com> | 2017-08-26 15:44:43 -0700 |
---|---|---|
committer | Michael Dawson <mdawson@devrus.com> | 2017-09-14 16:05:46 -0400 |
commit | 0c258bdc4040fcc4ab590fc80dbcd2182b4c74ae (patch) | |
tree | 6e0ea3e5311bb931ebc469d839f3e95226fde06a /src/node_api.cc | |
parent | 92e5f5cc09fdbf223a418aef1154b2b75b3f9dcd (diff) | |
download | android-node-v8-0c258bdc4040fcc4ab590fc80dbcd2182b4c74ae.tar.gz android-node-v8-0c258bdc4040fcc4ab590fc80dbcd2182b4c74ae.tar.bz2 android-node-v8-0c258bdc4040fcc4ab590fc80dbcd2182b4c74ae.zip |
n-api: Context for custom async operations
- Add napi_async_context opaque pointer type.
(If needed, we could later add APIs for getting the async IDs
out of this context.)
- Add napi_async_init() and napi_async_destroy() APIs.
- Add async_context parameter to napi_make_callback().
- Add code and checks to test_make_callback to validate async context
APIs by checking async hooks are called with correct context.
- Update API documentation.
PR-URL: https://github.com/nodejs/node/pull/15189
Fixes: https://github.com/nodejs/node/issues/13254
Reviewed-By: Michael Dawson <michael_dawson@ca.ibm.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Diffstat (limited to 'src/node_api.cc')
-rw-r--r-- | src/node_api.cc | 61 |
1 files changed, 58 insertions, 3 deletions
diff --git a/src/node_api.cc b/src/node_api.cc index a8b449ece5..ef51599648 100644 --- a/src/node_api.cc +++ b/src/node_api.cc @@ -2765,7 +2765,52 @@ napi_status napi_instanceof(napi_env env, return GET_RETURN_STATUS(env); } +napi_status napi_async_init(napi_env env, + napi_value async_resource, + napi_value async_resource_name, + napi_async_context* result) { + CHECK_ENV(env); + CHECK_ARG(env, async_resource_name); + CHECK_ARG(env, result); + + v8::Isolate* isolate = env->isolate; + v8::Local<v8::Context> context = isolate->GetCurrentContext(); + + v8::Local<v8::Object> v8_resource; + if (async_resource != nullptr) { + CHECK_TO_OBJECT(env, context, v8_resource, async_resource); + } else { + v8_resource = v8::Object::New(isolate); + } + + v8::Local<v8::String> v8_resource_name; + CHECK_TO_STRING(env, context, v8_resource_name, async_resource_name); + + // TODO(jasongin): Consider avoiding allocation here by using + // a tagged pointer with 2×31 bit fields instead. + node::async_context* async_context = new node::async_context(); + + *async_context = node::EmitAsyncInit(isolate, v8_resource, v8_resource_name); + *result = reinterpret_cast<napi_async_context>(async_context); + + return napi_clear_last_error(env); +} + +napi_status napi_async_destroy(napi_env env, + napi_async_context async_context) { + CHECK_ENV(env); + CHECK_ARG(env, async_context); + + v8::Isolate* isolate = env->isolate; + node::async_context* node_async_context = + reinterpret_cast<node::async_context*>(async_context); + node::EmitAsyncDestroy(isolate, *node_async_context); + + return napi_clear_last_error(env); +} + napi_status napi_make_callback(napi_env env, + napi_async_context async_context, napi_value recv, napi_value func, size_t argc, @@ -2786,12 +2831,22 @@ napi_status napi_make_callback(napi_env env, v8::Local<v8::Function> v8func; CHECK_TO_FUNCTION(env, v8func, func); - v8::Local<v8::Value> callback_result = node::MakeCallback( + node::async_context* node_async_context = + reinterpret_cast<node::async_context*>(async_context); + if (node_async_context == nullptr) { + static node::async_context empty_context = { 0, 0 }; + node_async_context = &empty_context; + } + + v8::MaybeLocal<v8::Value> callback_result = node::MakeCallback( isolate, v8recv, v8func, argc, - reinterpret_cast<v8::Local<v8::Value>*>(const_cast<napi_value*>(argv))); + reinterpret_cast<v8::Local<v8::Value>*>(const_cast<napi_value*>(argv)), + *node_async_context); + CHECK_MAYBE_EMPTY(env, callback_result, napi_generic_failure); if (result != nullptr) { - *result = v8impl::JsValueFromV8LocalValue(callback_result); + *result = v8impl::JsValueFromV8LocalValue( + callback_result.ToLocalChecked()); } return GET_RETURN_STATUS(env); |