7
7
#include < unistd.h>
8
8
#endif
9
9
10
+ // this needs to be greater than the thread pool size
11
+ #define MAX_CANCEL_THREADS 6
12
+
10
13
typedef struct {
11
14
int32_t _input;
12
15
int32_t _output;
@@ -15,6 +18,7 @@ typedef struct {
15
18
} carrier;
16
19
17
20
carrier the_carrier;
21
+ carrier async_carrier[MAX_CANCEL_THREADS];
18
22
19
23
struct AutoHandleScope {
20
24
explicit AutoHandleScope (napi_env env)
@@ -74,7 +78,7 @@ void Complete(napi_env env, napi_status status, void* data) {
74
78
75
79
napi_value result;
76
80
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));
78
82
79
83
NAPI_CALL_RETURN_VOID (env, napi_delete_reference (env, c->_callback ));
80
84
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) {
111
115
return nullptr ;
112
116
}
113
117
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
+
114
182
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));
120
190
}
121
191
122
192
NAPI_MODULE (addon, Init)
0 commit comments