Skip to content

Commit d883f37

Browse files
authored
Prevent asserting with significant expressions (nodejs#126)
* Move code that is necessary to run out of assert() so it runs in non-debug builds PR-URL: nodejs#126 Reviewed-By: Michael Dawson <michael_dawson@ca.ibm.com>
1 parent 3d61643 commit d883f37

9 files changed

Lines changed: 99 additions & 63 deletions

File tree

async_work_thread_safe_function/node-api/binding.c renamed to async_work_thread_safe_function/napi/binding.c

Lines changed: 43 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ typedef struct {
1919
static void CallJs(napi_env env, napi_value js_cb, void* context, void* data) {
2020
// This parameter is not used.
2121
(void) context;
22+
napi_status status;
2223

2324
// Retrieve the prime from the item created by the worker thread.
2425
int the_prime = *(int*)data;
@@ -31,20 +32,23 @@ static void CallJs(napi_env env, napi_value js_cb, void* context, void* data) {
3132
napi_value undefined, js_the_prime;
3233

3334
// Convert the integer to a napi_value.
34-
assert(napi_create_int32(env, the_prime, &js_the_prime) == napi_ok);
35+
status = napi_create_int32(env, the_prime, &js_the_prime);
36+
assert(status == napi_ok);
3537

3638
// Retrieve the JavaScript `undefined` value so we can use it as the `this`
3739
// value of the JavaScript function call.
38-
assert(napi_get_undefined(env, &undefined) == napi_ok);
40+
status = napi_get_undefined(env, &undefined);
41+
assert(status == napi_ok);
3942

4043
// Call the JavaScript function and pass it the prime that the secondary
4144
// thread found.
42-
assert(napi_call_function(env,
45+
status = napi_call_function(env,
4346
undefined,
4447
js_cb,
4548
1,
4649
&js_the_prime,
47-
NULL) == napi_ok);
50+
NULL);
51+
assert(status == napi_ok);
4852
}
4953

5054
// Free the item created by the worker thread.
@@ -57,11 +61,13 @@ static void ExecuteWork(napi_env env, void* data) {
5761
AddonData* addon_data = (AddonData*)data;
5862
int idx_inner, idx_outer;
5963
int prime_count = 0;
64+
napi_status status;
6065

6166
// We bracket the use of the thread-safe function by this thread by a call to
6267
// napi_acquire_threadsafe_function() here, and by a call to
6368
// napi_release_threadsafe_function() immediately prior to thread exit.
64-
assert(napi_acquire_threadsafe_function(addon_data->tsfn) == napi_ok);
69+
status = napi_acquire_threadsafe_function(addon_data->tsfn);
70+
assert(status == napi_ok);
6571

6672
// Find the first 1000 prime numbers using an extremely inefficient algorithm.
6773
for (idx_outer = 2; prime_count < PRIME_COUNT; idx_outer++) {
@@ -85,15 +91,17 @@ static void ExecuteWork(napi_env env, void* data) {
8591

8692
// Initiate the call into JavaScript. The call into JavaScript will not
8793
// have happened when this function returns, but it will be queued.
88-
assert(napi_call_threadsafe_function(addon_data->tsfn,
94+
status = napi_call_threadsafe_function(addon_data->tsfn,
8995
the_prime,
90-
napi_tsfn_blocking) == napi_ok);
96+
napi_tsfn_blocking);
97+
assert(status == napi_ok);
9198
}
9299
}
93100

94101
// Indicate that this thread will make no further use of the thread-safe function.
95-
assert(napi_release_threadsafe_function(addon_data->tsfn,
96-
napi_tsfn_release) == napi_ok);
102+
status = napi_release_threadsafe_function(addon_data->tsfn,
103+
napi_tsfn_release);
104+
assert(status == napi_ok);
97105
}
98106

99107
// This function runs on the main thread after `ExecuteWork` exits.
@@ -102,9 +110,11 @@ static void WorkComplete(napi_env env, napi_status status, void* data) {
102110

103111
// Clean up the thread-safe function and the work item associated with this
104112
// run.
105-
assert(napi_release_threadsafe_function(addon_data->tsfn,
106-
napi_tsfn_release) == napi_ok);
107-
assert(napi_delete_async_work(env, addon_data->work) == napi_ok);
113+
status = napi_release_threadsafe_function(addon_data->tsfn,
114+
napi_tsfn_release);
115+
assert(status == napi_ok);
116+
status = napi_delete_async_work(env, addon_data->work);
117+
assert(status == napi_ok);
108118

109119
// Set both values to NULL so JavaScript can order a new run of the thread.
110120
addon_data->work = NULL;
@@ -119,28 +129,31 @@ static napi_value StartThread(napi_env env, napi_callback_info info) {
119129
size_t argc = 1;
120130
napi_value js_cb, work_name;
121131
AddonData* addon_data;
132+
napi_status status;
122133

123134
// Retrieve the JavaScript callback we should call with items generated by the
124135
// worker thread, and the per-addon data.
125-
assert(napi_get_cb_info(env,
136+
status = napi_get_cb_info(env,
126137
info,
127138
&argc,
128139
&js_cb,
129140
NULL,
130-
(void**)(&addon_data)) == napi_ok);
141+
(void**)(&addon_data));
142+
assert(status == napi_ok);
131143

132144
// Ensure that no work is currently in progress.
133145
assert(addon_data->work == NULL && "Only one work item must exist at a time");
134146

135147
// Create a string to describe this asynchronous operation.
136-
assert(napi_create_string_utf8(env,
148+
status = napi_create_string_utf8(env,
137149
"N-API Thread-safe Call from Async Work Item",
138150
NAPI_AUTO_LENGTH,
139-
&work_name) == napi_ok);
151+
&work_name);
152+
assert(status == napi_ok);
140153

141154
// Convert the callback retrieved from JavaScript into a thread-safe function
142155
// which we can call from a worker thread.
143-
assert(napi_create_threadsafe_function(env,
156+
status = napi_create_threadsafe_function(env,
144157
js_cb,
145158
NULL,
146159
work_name,
@@ -150,20 +163,23 @@ static napi_value StartThread(napi_env env, napi_callback_info info) {
150163
NULL,
151164
NULL,
152165
CallJs,
153-
&(addon_data->tsfn)) == napi_ok);
166+
&(addon_data->tsfn));
167+
assert(status == napi_ok);
154168

155169
// Create an async work item, passing in the addon data, which will give the
156170
// worker thread access to the above-created thread-safe function.
157-
assert(napi_create_async_work(env,
171+
status = napi_create_async_work(env,
158172
NULL,
159173
work_name,
160174
ExecuteWork,
161175
WorkComplete,
162176
addon_data,
163-
&(addon_data->work)) == napi_ok);
177+
&(addon_data->work));
178+
assert(status == napi_ok);
164179

165180
// Queue the work item for execution.
166-
assert(napi_queue_async_work(env, addon_data->work) == napi_ok);
181+
status = napi_queue_async_work(env, addon_data->work);
182+
assert(status == napi_ok);
167183

168184
// This causes `undefined` to be returned to JavaScript.
169185
return NULL;
@@ -183,7 +199,7 @@ static void addon_getting_unloaded(napi_env env, void* data, void* hint) {
183199
// commented below and as though there were parameters passed in as commented
184200
// below.
185201
/*napi_value*/ NAPI_MODULE_INIT(/*napi_env env, napi_value exports*/) {
186-
202+
napi_status status;
187203
// Define addon-level data associated with this instance of the addon.
188204
AddonData* addon_data = (AddonData*)malloc(sizeof(*addon_data));
189205
addon_data->work = NULL;
@@ -201,16 +217,18 @@ static void addon_getting_unloaded(napi_env env, void* data, void* hint) {
201217
};
202218

203219
// Decorate exports with the above-defined properties.
204-
assert(napi_define_properties(env, exports, 1, &start_work) == napi_ok);
220+
status = napi_define_properties(env, exports, 1, &start_work);
221+
assert(status == napi_ok);
205222

206223
// Associate the addon data with the exports object, to make sure that when
207224
// the addon gets unloaded our data gets freed.
208-
assert(napi_wrap(env,
225+
status = napi_wrap(env,
209226
exports,
210227
addon_data,
211228
addon_getting_unloaded,
212229
NULL,
213-
NULL) == napi_ok);
230+
NULL);
231+
assert(status == napi_ok);
214232

215233
// Return the decorated exports object.
216234
return exports;
File renamed without changes.
File renamed without changes.
File renamed without changes.

multiple_load/napi/multiple_load.c

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,17 @@
1-
#include <assert.h>
1+
#include <stdio.h>
22
#include <math.h>
33
#include <stdlib.h>
44
#include <node_api.h>
55

6+
#define CHECK(expr) \
7+
{ \
8+
if ((expr) == 0) { \
9+
fprintf(stderr, "%s:%d: failed assertion `%s'\n", __FILE__, __LINE__, #expr); \
10+
fflush(stderr); \
11+
abort(); \
12+
} \
13+
}
14+
615
// Structure containing information needed for as long as the addon exists. It
716
// replaces the use of global static data with per-addon-instance data by
817
// associating an instance of this structure with each instance of this addon
@@ -48,7 +57,7 @@ static void DeleteAddonData(napi_env env, void* data, void* hint) {
4857
static AddonData* CreateAddonData(napi_env env, napi_value exports) {
4958
AddonData* result = malloc(sizeof(*result));
5059
result->value = 0.0;
51-
assert(napi_wrap(env,
60+
CHECK(napi_wrap(env,
5261
exports,
5362
result,
5463
DeleteAddonData,
@@ -62,7 +71,7 @@ static AddonData* CreateAddonData(napi_env env, napi_value exports) {
6271
static napi_value Increment(napi_env env, napi_callback_info info) {
6372
// Retrieve the per-addon-instance data.
6473
AddonData* addon_data = NULL;
65-
assert(napi_get_cb_info(env,
74+
CHECK(napi_get_cb_info(env,
6675
info,
6776
NULL,
6877
NULL,
@@ -72,7 +81,7 @@ static napi_value Increment(napi_env env, napi_callback_info info) {
7281
// Increment the per-addon-instance value and create a new JavaScript integer
7382
// from it.
7483
napi_value result;
75-
assert(napi_create_int32(env,
84+
CHECK(napi_create_int32(env,
7685
ModifyAddonData(addon_data, 1.0),
7786
&result) == napi_ok);
7887

@@ -85,7 +94,7 @@ static napi_value Increment(napi_env env, napi_callback_info info) {
8594
static napi_value Decrement(napi_env env, napi_callback_info info) {
8695
// Retrieve the per-addon-instance data.
8796
AddonData* addon_data = NULL;
88-
assert(napi_get_cb_info(env,
97+
CHECK(napi_get_cb_info(env,
8998
info,
9099
NULL,
91100
NULL,
@@ -95,7 +104,7 @@ static napi_value Decrement(napi_env env, napi_callback_info info) {
95104
// Decrement the per-addon-instance value and create a new JavaScript integer
96105
// from it.
97106
napi_value result;
98-
assert(napi_create_int32(env,
107+
CHECK(napi_create_int32(env,
99108
ModifyAddonData(addon_data, -1.0),
100109
&result) == napi_ok);
101110

@@ -125,7 +134,7 @@ NAPI_MODULE_INIT(/*env, exports*/) {
125134
};
126135

127136
// Expose the two bindings declared above to JavaScript.
128-
assert(napi_define_properties(env,
137+
CHECK(napi_define_properties(env,
129138
exports,
130139
sizeof(bindings) / sizeof(bindings[0]),
131140
bindings) == napi_ok);
File renamed without changes.
File renamed without changes.
File renamed without changes.

0 commit comments

Comments
 (0)