Skip to content

Commit 156a8b6

Browse files
jasonginMylesBorins
authored andcommittedApr 16, 2018
n-api: change async resource name to napi_value
Backport-PR-URL: #19447 PR-URL: #14697 Reviewed-By: Anna Henningsen <anna@addaleax.net>
1 parent 7588eea commit 156a8b6

File tree

7 files changed

+156
-13
lines changed

7 files changed

+156
-13
lines changed
 

‎doc/api/n-api.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -3265,7 +3265,7 @@ changes:
32653265
NAPI_EXTERN
32663266
napi_status napi_create_async_work(napi_env env,
32673267
napi_value async_resource,
3268-
const char* async_resource_name,
3268+
napi_value async_resource_name,
32693269
napi_async_execute_callback execute,
32703270
napi_async_complete_callback complete,
32713271
void* data,

‎node.gyp

+1
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,7 @@
241241
'src/handle_wrap.cc',
242242
'src/js_stream.cc',
243243
'src/node.cc',
244+
'src/node_api_backport.cc',
244245
'src/node_api.cc',
245246
'src/node_api.h',
246247
'src/node_api_types.h',

‎src/node_api.cc

+10-7
Original file line numberDiff line numberDiff line change
@@ -3255,7 +3255,7 @@ class Work : public node::AsyncResource {
32553255
private:
32563256
explicit Work(napi_env env,
32573257
v8::Local<v8::Object> async_resource,
3258-
const char* async_resource_name,
3258+
v8::Local<v8::String> async_resource_name,
32593259
napi_async_execute_callback execute,
32603260
napi_async_complete_callback complete = nullptr,
32613261
void* data = nullptr)
@@ -3275,7 +3275,7 @@ class Work : public node::AsyncResource {
32753275
public:
32763276
static Work* New(napi_env env,
32773277
v8::Local<v8::Object> async_resource,
3278-
const char* async_resource_name,
3278+
v8::Local<v8::String> async_resource_name,
32793279
napi_async_execute_callback execute,
32803280
napi_async_complete_callback complete,
32813281
void* data) {
@@ -3345,7 +3345,7 @@ class Work : public node::AsyncResource {
33453345

33463346
napi_status napi_create_async_work(napi_env env,
33473347
napi_value async_resource,
3348-
const char* async_resource_name,
3348+
napi_value async_resource_name,
33493349
napi_async_execute_callback execute,
33503350
napi_async_complete_callback complete,
33513351
void* data,
@@ -3354,17 +3354,20 @@ napi_status napi_create_async_work(napi_env env,
33543354
CHECK_ARG(env, execute);
33553355
CHECK_ARG(env, result);
33563356

3357+
v8::Local<v8::Context> context = env->isolate->GetCurrentContext();
3358+
33573359
v8::Local<v8::Object> resource;
33583360
if (async_resource != nullptr) {
3359-
auto value = v8impl::V8LocalValueFromJsValue(async_resource);
3360-
RETURN_STATUS_IF_FALSE(env, value->IsObject(), napi_invalid_arg);
3361-
resource = value.As<v8::Object>();
3361+
CHECK_TO_OBJECT(env, context, resource, async_resource);
33623362
} else {
33633363
resource = v8::Object::New(env->isolate);
33643364
}
33653365

3366+
v8::Local<v8::String> resource_name;
3367+
CHECK_TO_STRING(env, context, resource_name, async_resource_name);
3368+
33663369
uvimpl::Work* work =
3367-
uvimpl::Work::New(env, resource, async_resource_name,
3370+
uvimpl::Work::New(env, resource, resource_name,
33683371
execute, complete, data);
33693372

33703373
*result = reinterpret_cast<napi_async_work>(work);

‎src/node_api.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -525,7 +525,7 @@ NAPI_EXTERN napi_status napi_get_dataview_info(napi_env env,
525525
NAPI_EXTERN
526526
napi_status napi_create_async_work(napi_env env,
527527
napi_value async_resource,
528-
const char* async_resource_name,
528+
napi_value async_resource_name,
529529
napi_async_execute_callback execute,
530530
napi_async_complete_callback complete,
531531
void* data,

‎src/node_api_backport.cc

+89
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
#include "node_api_backport.h"
2+
3+
using v8::Function;
4+
using v8::HandleScope;
5+
using v8::Local;
6+
using v8::MaybeLocal;
7+
using v8::Object;
8+
using v8::TryCatch;
9+
using v8::Value;
10+
11+
namespace node {
12+
13+
CallbackScope::CallbackScope(v8::Isolate *_isolate,
14+
v8::Local<v8::Object> _object,
15+
node::async_context context) :
16+
isolate(_isolate),
17+
env(node::Environment::GetCurrent(isolate->GetCurrentContext())),
18+
_try_catch(isolate),
19+
object(_object),
20+
callback_scope(
21+
node::Environment::GetCurrent(isolate->GetCurrentContext())) {
22+
Local<Function> pre_fn = env->async_hooks_pre_function();
23+
24+
Local<Value> async_queue_v = object->Get(env->async_queue_string());
25+
if (async_queue_v->IsObject())
26+
ran_init_callback = true;
27+
28+
if (ran_init_callback && !pre_fn.IsEmpty()) {
29+
TryCatch try_catch(env->isolate());
30+
MaybeLocal<Value> ar = pre_fn->Call(env->context(), object, 0, nullptr);
31+
if (ar.IsEmpty()) {
32+
ClearFatalExceptionHandlers(env);
33+
FatalException(env->isolate(), try_catch);
34+
}
35+
}
36+
}
37+
38+
CallbackScope::~CallbackScope() {
39+
Local<Function> post_fn = env->async_hooks_post_function();
40+
if (ran_init_callback && !post_fn.IsEmpty()) {
41+
Local<Value> did_throw = v8::Boolean::New(isolate, _try_catch.HasCaught());
42+
// Currently there's no way to retrieve an uid from node::MakeCallback().
43+
// This needs to be fixed.
44+
Local<Value> vals[] =
45+
{ Undefined(env->isolate()).As<Value>(), did_throw };
46+
TryCatch try_catch(env->isolate());
47+
MaybeLocal<Value> ar =
48+
post_fn->Call(env->context(), object, arraysize(vals), vals);
49+
if (ar.IsEmpty()) {
50+
ClearFatalExceptionHandlers(env);
51+
FatalException(env->isolate(), try_catch);
52+
return;
53+
}
54+
}
55+
56+
if (callback_scope.in_makecallback()) {
57+
return;
58+
}
59+
60+
Environment::TickInfo* tick_info = env->tick_info();
61+
62+
if (tick_info->length() == 0) {
63+
env->isolate()->RunMicrotasks();
64+
}
65+
66+
if (tick_info->length() == 0) {
67+
tick_info->set_index(0);
68+
return;
69+
}
70+
71+
env->tick_callback_function()->Call(env->process_object(), 0, nullptr);
72+
}
73+
74+
AsyncResource::AsyncResource(v8::Isolate* _isolate,
75+
v8::Local<v8::Object> _object,
76+
v8::Local<v8::String> name) : isolate(_isolate) {
77+
object.Reset(isolate, _object);
78+
}
79+
80+
AsyncResource::~AsyncResource() {
81+
object.Reset();
82+
}
83+
84+
} // end of namespace node
85+
86+
CallbackScope::CallbackScope(node::AsyncResource* work) :
87+
scope(work->isolate,
88+
v8::Local<Object>::New(work->isolate,
89+
work->object), {0, 0}) {}

‎src/node_api_backport.h

+43-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,48 @@
55
// which have appeared in later versions of Node.js, and which are required for
66
// N-API.
77

8-
#define ToChecked FromJust
8+
#include "node_internals.h"
9+
10+
namespace node {
11+
12+
typedef int async_id;
13+
14+
typedef struct async_context {
15+
node::async_id async_id;
16+
node::async_id trigger_async_id;
17+
} async_context;
18+
19+
class CallbackScope {
20+
public:
21+
CallbackScope(v8::Isolate *isolate,
22+
v8::Local<v8::Object> object,
23+
node::async_context context);
24+
~CallbackScope();
25+
private:
26+
v8::Isolate* isolate = nullptr;
27+
node::Environment* env = nullptr;
28+
v8::TryCatch _try_catch;
29+
bool ran_init_callback = false;
30+
v8::Local<v8::Object> object;
31+
Environment::AsyncCallbackScope callback_scope;
32+
};
33+
34+
class AsyncResource {
35+
public:
36+
AsyncResource(v8::Isolate* _isolate,
37+
v8::Local<v8::Object> _object,
38+
v8::Local<v8::String> name);
39+
~AsyncResource();
40+
v8::Isolate* isolate;
41+
v8::Persistent<v8::Object> object;
42+
};
43+
} // end of namespace node
44+
45+
class CallbackScope {
46+
public:
47+
explicit CallbackScope(node::AsyncResource* work);
48+
private:
49+
node::CallbackScope scope;
50+
};
951

1052
#endif // SRC_NODE_API_BACKPORT_H_

‎test/addons-napi/test_async/test_async.cc

+11-3
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ napi_value Test(napi_env env, napi_callback_info info) {
7171
size_t argc = 3;
7272
napi_value argv[3];
7373
napi_value _this;
74+
napi_value resource_name;
7475
void* data;
7576
NAPI_CALL(env,
7677
napi_get_cb_info(env, info, &argc, argv, &_this, &data));
@@ -93,7 +94,10 @@ napi_value Test(napi_env env, napi_callback_info info) {
9394
napi_get_value_int32(env, argv[0], &the_carrier._input));
9495
NAPI_CALL(env,
9596
napi_create_reference(env, argv[2], 1, &the_carrier._callback));
96-
NAPI_CALL(env, napi_create_async_work(env, argv[1], "TestResource",
97+
98+
NAPI_CALL(env,
99+
napi_create_string_utf8(env, "TestResource", -1, &resource_name));
100+
NAPI_CALL(env, napi_create_async_work(env, argv[1], resource_name,
97101
Execute, Complete, &the_carrier, &the_carrier._request));
98102
NAPI_CALL(env,
99103
napi_queue_async_work(env, the_carrier._request));
@@ -138,12 +142,16 @@ napi_value TestCancel(napi_env env, napi_callback_info info) {
138142
size_t argc = 1;
139143
napi_value argv[1];
140144
napi_value _this;
145+
napi_value resource_name;
141146
void* data;
142147

148+
NAPI_CALL(env,
149+
napi_create_string_utf8(env, "TestResource", -1, &resource_name));
150+
143151
// make sure the work we are going to cancel will not be
144152
// able to start by using all the threads in the pool
145153
for (int i = 1; i < MAX_CANCEL_THREADS; i++) {
146-
NAPI_CALL(env, napi_create_async_work(env, nullptr, "TestCancelBusy",
154+
NAPI_CALL(env, napi_create_async_work(env, nullptr, resource_name,
147155
CancelExecute, BusyCancelComplete,
148156
&async_carrier[i], &async_carrier[i]._request));
149157
NAPI_CALL(env, napi_queue_async_work(env, async_carrier[i]._request));
@@ -155,7 +163,7 @@ napi_value TestCancel(napi_env env, napi_callback_info info) {
155163
// workers above.
156164
NAPI_CALL(env,
157165
napi_get_cb_info(env, info, &argc, argv, &_this, &data));
158-
NAPI_CALL(env, napi_create_async_work(env, nullptr, "TestCancelled",
166+
NAPI_CALL(env, napi_create_async_work(env, nullptr, resource_name,
159167
CancelExecute, CancelComplete,
160168
&async_carrier[0], &async_carrier[0]._request));
161169
NAPI_CALL(env,

0 commit comments

Comments
 (0)
Please sign in to comment.