Skip to content

Commit e223955

Browse files
committed
doc: tsfnex example uses ported tsfn example
1 parent ad9333e commit e223955

File tree

2 files changed

+57
-30
lines changed

2 files changed

+57
-30
lines changed

doc/threadsafe_function.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ New(napi_env env,
7171
`uv_thread_join()`. It is important that, aside from the main loop thread,
7272
there be no threads left using the thread-safe function after the finalize
7373
callback completes. Must implement `void operator()(Env env, DataType* data,
74-
Context* hint)`, skipping `data` or `hint` if they are not provided.
74+
ContextType* hint)`, skipping `data` or `hint` if they are not provided.
7575
- `[optional] data`: Data to be passed to `finalizeCallback`.
7676

7777
Returns a non-empty `Napi::ThreadSafeFunction` instance.

doc/threadsafe_function_ex.md

Lines changed: 56 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -192,8 +192,14 @@ Returns one of:
192192

193193
using namespace Napi;
194194

195+
using Context = Reference<Value>;
196+
using DataType = int;
197+
void CallJs( Napi::Env env, Function callback, Context* context, DataType* data );
198+
using TSFN = ThreadSafeFunctionEx<Context, DataType, CallJs>;
199+
using FinalizerDataType = void;
200+
195201
std::thread nativeThread;
196-
ThreadSafeFunction tsfn;
202+
TSFN tsfn;
197203

198204
Value Start( const CallbackInfo& info )
199205
{
@@ -214,35 +220,32 @@ Value Start( const CallbackInfo& info )
214220

215221
int count = info[1].As<Number>().Int32Value();
216222

223+
// Create a new context set to the the receiver (ie, `this`) of the function
224+
// call
225+
Context* context = new Reference<Value>( Persistent( info.This() ) );
226+
217227
// Create a ThreadSafeFunction
218-
tsfn = ThreadSafeFunction::New(
219-
env,
220-
info[0].As<Function>(), // JavaScript function called asynchronously
221-
"Resource Name", // Name
222-
0, // Unlimited queue
223-
1, // Only one thread will use this initially
224-
[]( Napi::Env ) { // Finalizer used to clean threads up
225-
nativeThread.join();
226-
} );
228+
tsfn = TSFN::New( env,
229+
info[0].As<Function>(), // JavaScript function called asynchronously
230+
"Resource Name", // Name
231+
0, // Unlimited queue
232+
1, // Only one thread will use this initially
233+
context,
234+
[]( Napi::Env, FinalizerDataType*,
235+
Context* ctx ) { // Finalizer used to clean threads up
236+
nativeThread.join();
237+
delete ctx;
238+
} );
227239

228240
// Create a native thread
229241
nativeThread = std::thread( [count] {
230-
auto callback = []( Napi::Env env, Function jsCallback, int* value ) {
231-
// Transform native data into JS data, passing it to the provided
232-
// `jsCallback` -- the TSFN's JavaScript function.
233-
jsCallback.Call( {Number::New( env, *value )} );
234-
235-
// We're finished with the data.
236-
delete value;
237-
};
238-
239242
for ( int i = 0; i < count; i++ )
240243
{
241244
// Create new data
242245
int* value = new int( clock() );
243246

244247
// Perform a blocking call
245-
napi_status status = tsfn.BlockingCall( value, callback );
248+
napi_status status = tsfn.BlockingCall( value );
246249
if ( status != napi_ok )
247250
{
248251
// Handle error
@@ -256,7 +259,29 @@ Value Start( const CallbackInfo& info )
256259
tsfn.Release();
257260
} );
258261

259-
return Boolean::New(env, true);
262+
return Boolean::New( env, true );
263+
}
264+
265+
// Transform native data into JS data, passing it to the provided
266+
// `callback` -- the TSFN's JavaScript function.
267+
void CallJs( Napi::Env env, Function callback, Context* context, DataType* data )
268+
{
269+
// Is the JavaScript environment still available to call into, eg. the TSFN is
270+
// not aborted
271+
if ( env != nullptr )
272+
{
273+
// On N-API 5+, the `callback` parameter is optional; however, this example
274+
// does ensure a callback is provided.
275+
if ( callback != nullptr )
276+
{
277+
callback.Call( context->Value(), {Number::New( env, *data )} );
278+
}
279+
}
280+
if ( data != nullptr )
281+
{
282+
// We're finished with the data.
283+
delete data;
284+
}
260285
}
261286

262287
Napi::Object Init( Napi::Env env, Object exports )
@@ -273,18 +298,20 @@ The above code can be used from JavaScript as follows:
273298
```js
274299
const { start } = require('bindings')('clock');
275300
276-
start(function () {
277-
console.log("JavaScript callback called with arguments", Array.from(arguments));
301+
start.call(new Date(), function (clock) {
302+
const context = this;
303+
console.log(context, clock);
278304
}, 5);
279305
```
280306

281307
When executed, the output will show the value of `clock()` five times at one
282-
second intervals:
308+
second intervals, prefixed with the TSFN's context -- `start`'s receiver (ie,
309+
`new Date()`):
283310

284311
```
285-
JavaScript callback called with arguments [ 84745 ]
286-
JavaScript callback called with arguments [ 103211 ]
287-
JavaScript callback called with arguments [ 104516 ]
288-
JavaScript callback called with arguments [ 105104 ]
289-
JavaScript callback called with arguments [ 105691 ]
312+
2020-08-18T21:04:25.116Z 49824
313+
2020-08-18T21:04:25.116Z 62493
314+
2020-08-18T21:04:25.116Z 62919
315+
2020-08-18T21:04:25.116Z 63228
316+
2020-08-18T21:04:25.116Z 63531
290317
```

0 commit comments

Comments
 (0)