Skip to content

Commit 1d96803

Browse files
committed
test: add coverage for napi_cancel_async_work
adding test coverage for napi_cancel_async_work based on coverage report PR-URL: #12575 Reviewed-By: James M Snell <[email protected]> Reviewed-By: Colin Ihrig <[email protected]> Reviewed-By: Anna Henningsen <[email protected]>
1 parent 35d2137 commit 1d96803

File tree

2 files changed

+80
-7
lines changed

2 files changed

+80
-7
lines changed

test/addons-napi/test_async/test.js

+4-1
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,11 @@ const common = require('../../common');
33
const assert = require('assert');
44
const test_async = require(`./build/${common.buildType}/test_async`);
55

6-
test_async(5, common.mustCall(function(err, val) {
6+
test_async.Test(5, common.mustCall(function(err, val) {
77
assert.strictEqual(err, null);
88
assert.strictEqual(val, 10);
99
process.nextTick(common.mustCall(function() {}));
1010
}));
11+
12+
const cancelSuceeded = function() {};
13+
test_async.TestCancel(common.mustCall(cancelSuceeded));

test/addons-napi/test_async/test_async.cc

+76-6
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@
77
#include <unistd.h>
88
#endif
99

10+
// this needs to be greater than the thread pool size
11+
#define MAX_CANCEL_THREADS 6
12+
1013
typedef struct {
1114
int32_t _input;
1215
int32_t _output;
@@ -15,6 +18,7 @@ typedef struct {
1518
} carrier;
1619

1720
carrier the_carrier;
21+
carrier async_carrier[MAX_CANCEL_THREADS];
1822

1923
struct AutoHandleScope {
2024
explicit AutoHandleScope(napi_env env)
@@ -74,7 +78,7 @@ void Complete(napi_env env, napi_status status, void* data) {
7478

7579
napi_value result;
7680
NAPI_CALL_RETURN_VOID(env,
77-
napi_call_function(env, global, callback, 2, argv, &result));
81+
napi_make_callback(env, global, callback, 2, argv, &result));
7882

7983
NAPI_CALL_RETURN_VOID(env, napi_delete_reference(env, c->_callback));
8084
NAPI_CALL_RETURN_VOID(env, napi_delete_async_work(env, c->_request));
@@ -111,12 +115,78 @@ napi_value Test(napi_env env, napi_callback_info info) {
111115
return nullptr;
112116
}
113117

118+
void BusyCancelComplete(napi_env env, napi_status status, void* data) {
119+
AutoHandleScope scope(env);
120+
carrier* c = static_cast<carrier*>(data);
121+
NAPI_CALL_RETURN_VOID(env, napi_delete_async_work(env, c->_request));
122+
}
123+
124+
void CancelComplete(napi_env env, napi_status status, void* data) {
125+
AutoHandleScope scope(env);
126+
carrier* c = static_cast<carrier*>(data);
127+
128+
if (status == napi_cancelled) {
129+
// ok we got the status we expected so make the callback to
130+
// indicate the cancel succeeded.
131+
napi_value callback;
132+
NAPI_CALL_RETURN_VOID(env,
133+
napi_get_reference_value(env, c->_callback, &callback));
134+
napi_value global;
135+
NAPI_CALL_RETURN_VOID(env, napi_get_global(env, &global));
136+
napi_value result;
137+
NAPI_CALL_RETURN_VOID(env,
138+
napi_make_callback(env, global, callback, 0, nullptr, &result));
139+
}
140+
141+
NAPI_CALL_RETURN_VOID(env, napi_delete_async_work(env, c->_request));
142+
NAPI_CALL_RETURN_VOID(env, napi_delete_reference(env, c->_callback));
143+
}
144+
145+
void CancelExecute(napi_env env, void* data) {
146+
#if defined _WIN32
147+
Sleep(1000);
148+
#else
149+
sleep(1);
150+
#endif
151+
}
152+
153+
napi_value TestCancel(napi_env env, napi_callback_info info) {
154+
size_t argc = 1;
155+
napi_value argv[1];
156+
napi_value _this;
157+
void* data;
158+
159+
// make sure the work we are going to cancel will not be
160+
// able to start by using all the threads in the pool
161+
for (int i = 1; i < MAX_CANCEL_THREADS; i++) {
162+
NAPI_CALL(env, napi_create_async_work(env, CancelExecute,
163+
BusyCancelComplete, &async_carrier[i], &async_carrier[i]._request));
164+
NAPI_CALL(env, napi_queue_async_work(env, async_carrier[i]._request));
165+
}
166+
167+
// now queue the work we are going to cancel and then cancel it.
168+
// cancel will fail if the work has already started, but
169+
// we have prevented it from starting by consuming all of the
170+
// workers above.
171+
NAPI_CALL(env,
172+
napi_get_cb_info(env, info, &argc, argv, &_this, &data));
173+
NAPI_CALL(env, napi_create_async_work(env, CancelExecute,
174+
CancelComplete, &async_carrier[0], &async_carrier[0]._request));
175+
NAPI_CALL(env,
176+
napi_create_reference(env, argv[0], 1, &async_carrier[0]._callback));
177+
NAPI_CALL(env, napi_queue_async_work(env, async_carrier[0]._request));
178+
NAPI_CALL(env, napi_cancel_async_work(env, async_carrier[0]._request));
179+
return nullptr;
180+
}
181+
114182
void Init(napi_env env, napi_value exports, napi_value module, void* priv) {
115-
napi_value test;
116-
NAPI_CALL_RETURN_VOID(env,
117-
napi_create_function(env, "Test", Test, nullptr, &test));
118-
NAPI_CALL_RETURN_VOID(env,
119-
napi_set_named_property(env, module, "exports", test));
183+
napi_property_descriptor properties[] = {
184+
DECLARE_NAPI_PROPERTY("Test", Test),
185+
DECLARE_NAPI_PROPERTY("TestCancel", TestCancel),
186+
};
187+
188+
NAPI_CALL_RETURN_VOID(env, napi_define_properties(
189+
env, exports, sizeof(properties) / sizeof(*properties), properties));
120190
}
121191

122192
NAPI_MODULE(addon, Init)

0 commit comments

Comments
 (0)