Skip to content

Commit 3d3c62a

Browse files
amissineGabriel Schulhof
authored andcommitted
Add the 'prime' property (with its getter) to the 'ThreadItem' item
PR-URL: gabrielschulhof/abi-stable-node-addon-examples#4 PR-URL: #67 Reviewed-By: Gabriel Schulhof <gabriel.schulhof@intel.com> Reviewed-By: Michael Dawson <michael_dawson@ca.ibm.com>
1 parent 793de50 commit 3d3c62a

2 files changed

Lines changed: 45 additions & 26 deletions

File tree

thread_safe_function_round_trip/node-api/index.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
const bindings = require('bindings')('round_trip');
22

3-
bindings.startThread((item, thePrime) => {
3+
bindings.startThread(item => {
4+
const thePrime = item.prime;
45
console.log('The prime: ' + thePrime);
56

67
// Answer the call with a 90% probability of returning true somewhere between

thread_safe_function_round_trip/node-api/round_trip.c

Lines changed: 43 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ static void CallJs(napi_env env, napi_value js_cb, void* context, void* data) {
5151
// in `RegisterReturnValue` below, and we use the value here to decide whether
5252
// the data coming in from the secondary thread is stale or not.
5353
if (addon_data->js_accepts && !(env == NULL || js_cb == NULL)) {
54-
napi_value undefined, argv[2];
54+
napi_value undefined, js_thread_item;
5555
// Retrieve the JavaScript `undefined` value. This will serve as the `this`
5656
// value for the function call.
5757
assert(napi_get_undefined(env, &undefined) == napi_ok);
@@ -63,24 +63,27 @@ static void CallJs(napi_env env, napi_value js_cb, void* context, void* data) {
6363
&constructor) == napi_ok);
6464

6565
// Construct a new instance of the JavaScript class to hold the native item.
66-
assert(napi_new_instance(env, constructor, 0, NULL, &argv[0]) == napi_ok);
66+
assert(napi_new_instance(env,
67+
constructor,
68+
0,
69+
NULL,
70+
&js_thread_item) == napi_ok);
6771

6872
// Associate the native item with the newly constructed JavaScript object.
6973
// We assume that the JavaScript side will eventually pass this JavaScript
7074
// object back to us via `RegisterReturnValue`, which will allow the
7175
// eventual deallocation of the native data. That's why we do not provide a
7276
// finalizer here.
73-
assert(napi_wrap(env, argv[0], data, NULL, NULL, NULL) == napi_ok);
74-
75-
// Convert the prime number to a number `napi_value` we can pass into
76-
// JavaScript.
77-
assert(napi_create_int32(env,
78-
((ThreadItem*)data)->the_prime,
79-
&argv[1]) == napi_ok);
77+
assert(napi_wrap(env, js_thread_item, data, NULL, NULL, NULL) == napi_ok);
8078

8179
// Call the JavaScript function with the item as wrapped into an instance of
8280
// the JavaScript `ThreadItem` class and the prime.
83-
assert(napi_call_function(env, undefined, js_cb, 2, argv, NULL) == napi_ok);
81+
assert(napi_call_function(env,
82+
undefined,
83+
js_cb,
84+
1,
85+
&js_thread_item,
86+
NULL) == napi_ok);
8487
}
8588
}
8689

@@ -241,6 +244,17 @@ static napi_value StartThread(napi_env env, napi_callback_info info) {
241244
return NULL;
242245
}
243246

247+
static bool
248+
is_thread_item (napi_env env, napi_ref constructor_ref, napi_value value) {
249+
bool validate;
250+
napi_value constructor;
251+
assert(napi_get_reference_value(env,
252+
constructor_ref,
253+
&constructor) == napi_ok);
254+
assert(napi_instanceof(env, value, constructor, &validate) == napi_ok);
255+
return validate;
256+
}
257+
244258
// We use a separate binding to register a return value for a given call into
245259
// JavaScript, represented by a `ThreadItem` object on both the JavaScript side
246260
// and the native side. This allows the JavaScript side to asynchronously
@@ -251,9 +265,8 @@ static napi_value RegisterReturnValue(napi_env env, napi_callback_info info) {
251265
// 2. The desired return value.
252266
size_t argc = 2;
253267
napi_value argv[2];
254-
napi_value constructor;
255268
AddonData* addon_data;
256-
bool right_instance, return_value;
269+
bool return_value;
257270
ThreadItem* item;
258271

259272
// Retrieve the parameters with which this function was called.
@@ -275,19 +288,10 @@ static napi_value RegisterReturnValue(napi_env env, napi_callback_info info) {
275288

276289
assert(argc == 2 && "Exactly two arguments were received");
277290

278-
// Retrieve the constructor for `ThreadItem` instances.
279-
assert(napi_get_reference_value(env,
280-
addon_data->thread_item_constructor,
281-
&constructor) == napi_ok);
282-
283291
// Make sure the first parameter is an instance of the `ThreadItem` class.
284292
// This type check ensures that there *is* a pointer stored inside the
285293
// JavaScript object, and that the pointer is to a `ThreadItem` structure.
286-
assert(napi_instanceof(env,
287-
argv[0],
288-
constructor,
289-
&right_instance) == napi_ok);
290-
assert(right_instance && "First argument is a `ThreadItem`");
294+
assert(is_thread_item(env, addon_data->thread_item_constructor, argv[0]));
291295

292296
// Retrieve the native data from the item.
293297
assert(napi_unwrap(env, argv[0], (void**)&item) == napi_ok);
@@ -317,6 +321,18 @@ static napi_value ThreadItemConstructor(napi_env env, napi_callback_info info) {
317321
return NULL;
318322
}
319323

324+
// Getter for the `prime` property of the `ThreadItem` class.
325+
static napi_value GetPrime(napi_env env, napi_callback_info info) {
326+
napi_value jsthis, prime_property;
327+
AddonData* ad;
328+
assert(napi_ok == napi_get_cb_info(env, info, 0, 0, &jsthis, (void*)&ad));
329+
assert(is_thread_item(env, ad->thread_item_constructor, jsthis));
330+
ThreadItem* item;
331+
assert(napi_ok == napi_unwrap(env, jsthis, (void**)&item));
332+
assert(napi_ok == napi_create_int32(env, item->the_prime, &prime_property));
333+
return prime_property;
334+
}
335+
320336
static void addon_is_unloading(napi_env env, void* data, void* hint) {
321337
AddonData* addon_data = (AddonData*)data;
322338
uv_mutex_destroy(&(addon_data->check_status_mutex));
@@ -352,14 +368,16 @@ static void addon_is_unloading(napi_env env, void* data, void* hint) {
352368
assert(uv_mutex_init(&(addon_data->check_status_mutex)) == 0);
353369

354370
napi_value thread_item_class;
355-
371+
napi_property_descriptor thread_item_properties[] = {
372+
{ "prime", 0, 0, GetPrime, 0, 0, napi_enumerable, addon_data }
373+
};
356374
assert(napi_define_class(env,
357375
"ThreadItem",
358376
NAPI_AUTO_LENGTH,
359377
ThreadItemConstructor,
360378
addon_data,
361-
0,
362-
NULL,
379+
1,
380+
thread_item_properties,
363381
&thread_item_class) == napi_ok);
364382
assert(napi_create_reference(env,
365383
thread_item_class,

0 commit comments

Comments
 (0)