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+
1013typedef struct {
1114 int32_t _input;
1215 int32_t _output;
@@ -15,6 +18,7 @@ typedef struct {
1518} carrier;
1619
1720carrier the_carrier;
21+ carrier async_carrier[MAX_CANCEL_THREADS];
1822
1923struct 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+
114182void 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
122192NAPI_MODULE (addon, Init)
0 commit comments