diff options
author | Anna Henningsen <anna@addaleax.net> | 2017-11-17 22:16:43 +0100 |
---|---|---|
committer | Anna Henningsen <anna@addaleax.net> | 2017-11-21 08:33:23 +0100 |
commit | 9cf352553576ec3cf003a003da7e236772cd245e (patch) | |
tree | 81e135066868794a5d60b732a25e53828f729fa8 /src/node_api.cc | |
parent | c0f3bc24de1c88fe8daa74d3520880775a021fee (diff) | |
download | android-node-v8-9cf352553576ec3cf003a003da7e236772cd245e.tar.gz android-node-v8-9cf352553576ec3cf003a003da7e236772cd245e.tar.bz2 android-node-v8-9cf352553576ec3cf003a003da7e236772cd245e.zip |
n-api: add helper for addons to get the event loop
Add a utility functions for addons to use when they need
a reference to the current event loop.
While the libuv API is not directly part of N-API, it
provides a quite stable C API as well, and is tightly
integrated with Node itself.
As a particular use case, without access to the event loop
it is hard to do something interesting from inside a N-API
finalizer function, since calls into JS and therefore virtually
all other N-API functions are not allowed.
PR-URL: https://github.com/nodejs/node/pull/17109
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Diffstat (limited to 'src/node_api.cc')
-rw-r--r-- | src/node_api.cc | 28 |
1 files changed, 19 insertions, 9 deletions
diff --git a/src/node_api.cc b/src/node_api.cc index ad922d9ad1..84e57d03d6 100644 --- a/src/node_api.cc +++ b/src/node_api.cc @@ -18,7 +18,7 @@ #include "node_api.h" #include "node_internals.h" -#define NAPI_VERSION 1 +#define NAPI_VERSION 2 static napi_status napi_set_last_error(napi_env env, napi_status error_code, @@ -28,8 +28,10 @@ static napi_status napi_clear_last_error(napi_env env); struct napi_env__ { - explicit napi_env__(v8::Isolate* _isolate): isolate(_isolate), - last_error() {} + explicit napi_env__(v8::Isolate* _isolate, uv_loop_t* _loop) + : isolate(_isolate), + last_error(), + loop(_loop) {} ~napi_env__() { last_exception.Reset(); wrap_template.Reset(); @@ -43,6 +45,7 @@ struct napi_env__ { v8::Persistent<v8::ObjectTemplate> accessor_data_template; napi_extended_error_info last_error; int open_handle_scopes = 0; + uv_loop_t* loop = nullptr; }; #define ENV_OBJECT_TEMPLATE(env, prefix, destination, field_count) \ @@ -771,7 +774,7 @@ napi_env GetEnv(v8::Local<v8::Context> context) { if (value->IsExternal()) { result = static_cast<napi_env>(value.As<v8::External>()->Value()); } else { - result = new napi_env__(isolate); + result = new napi_env__(isolate, node::GetCurrentEventLoop(isolate)); auto external = v8::External::New(isolate, result); // We must also stop hard if the result of assigning the env to the global @@ -3401,15 +3404,22 @@ napi_status napi_delete_async_work(napi_env env, napi_async_work work) { return napi_clear_last_error(env); } +napi_status napi_get_uv_event_loop(napi_env env, uv_loop_t** loop) { + CHECK_ENV(env); + CHECK_ARG(env, loop); + *loop = env->loop; + return napi_clear_last_error(env); +} + napi_status napi_queue_async_work(napi_env env, napi_async_work work) { CHECK_ENV(env); CHECK_ARG(env, work); - // Consider: Encapsulate the uv_loop_t into an opaque pointer parameter. - // Currently the environment event loop is the same as the UV default loop. - // Someday (if node ever supports multiple isolates), it may be better to get - // the loop from node::Environment::GetCurrent(env->isolate)->event_loop(); - uv_loop_t* event_loop = uv_default_loop(); + napi_status status; + uv_loop_t* event_loop = nullptr; + status = napi_get_uv_event_loop(env, &event_loop); + if (status != napi_ok) + return napi_set_last_error(env, status); uvimpl::Work* w = reinterpret_cast<uvimpl::Work*>(work); |