Skip to content

Commit 9ff352c

Browse files
committed
add tsfn test with tsfn cb function call
1 parent 630d88b commit 9ff352c

File tree

5 files changed

+106
-0
lines changed

5 files changed

+106
-0
lines changed

test/binding.cc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ Object InitThreadSafeFunctionPtr(Env env);
4848
Object InitThreadSafeFunctionSum(Env env);
4949
Object InitThreadSafeFunctionUnref(Env env);
5050
Object InitThreadSafeFunction(Env env);
51+
Object InitThreadSafeFunctionExCall(Env env);
5152
Object InitThreadSafeFunctionExContext(Env env);
5253
Object InitThreadSafeFunctionExSimple(Env env);
5354
#endif
@@ -107,6 +108,7 @@ Object Init(Env env, Object exports) {
107108
exports.Set("threadsafe_function_sum", InitThreadSafeFunctionSum(env));
108109
exports.Set("threadsafe_function_unref", InitThreadSafeFunctionUnref(env));
109110
exports.Set("threadsafe_function", InitThreadSafeFunction(env));
111+
exports.Set("threadsafe_function_ex_call", InitThreadSafeFunctionExCall(env));
110112
exports.Set("threadsafe_function_ex_context", InitThreadSafeFunctionExContext(env));
111113
exports.Set("threadsafe_function_ex_simple", InitThreadSafeFunctionExSimple(env));
112114
#endif

test/binding.gyp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
'object/set_property.cc',
3535
'promise.cc',
3636
'run_script.cc',
37+
'threadsafe_function_ex/call.cc',
3738
'threadsafe_function_ex/context.cc',
3839
'threadsafe_function_ex/simple.cc',
3940
'threadsafe_function/threadsafe_function_ctx.cc',

test/index.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ let testModules = [
4141
'object/set_property',
4242
'promise',
4343
'run_script',
44+
'threadsafe_function_ex/call',
4445
'threadsafe_function_ex/context',
4546
'threadsafe_function_ex/simple',
4647
'threadsafe_function/threadsafe_function_ctx',
@@ -83,6 +84,7 @@ if (napiVersion < 4) {
8384
testModules.splice(testModules.indexOf('threadsafe_function/threadsafe_function_sum'), 1);
8485
testModules.splice(testModules.indexOf('threadsafe_function/threadsafe_function_unref'), 1);
8586
testModules.splice(testModules.indexOf('threadsafe_function/threadsafe_function'), 1);
87+
testModules.splice(testModules.indexOf('threadsafe_function_ex/call'), 1);
8688
testModules.splice(testModules.indexOf('threadsafe_function_ex/context'), 1);
8789
testModules.splice(testModules.indexOf('threadsafe_function_ex/simple'), 1);
8890
}

test/threadsafe_function_ex/call.cc

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
#include "napi.h"
2+
3+
#if (NAPI_VERSION > 3)
4+
5+
using namespace Napi;
6+
7+
namespace {
8+
9+
// Context of our TSFN.
10+
using TSFNContext = void;
11+
12+
// Data passed (as pointer) to ThreadSafeFunctionEx::[Non]BlockingCall
13+
struct TSFNData {
14+
Reference<Napi::Value> data;
15+
Promise::Deferred deferred;
16+
};
17+
18+
// CallJs callback function
19+
static void CallJs(Napi::Env env, Napi::Function jsCallback,
20+
TSFNContext * /*context*/, TSFNData *data) {
21+
jsCallback.Call(env.Undefined(), {data->data.Value()});
22+
data->deferred.Resolve(data->data.Value());
23+
delete data;
24+
}
25+
26+
// Full type of our ThreadSafeFunctionEx
27+
using TSFN = ThreadSafeFunctionEx<TSFNContext, TSFNData, CallJs>;
28+
29+
// A JS-accessible wrap that holds a TSFN.
30+
class TSFNWrap : public ObjectWrap<TSFNWrap> {
31+
public:
32+
static Object Init(Napi::Env env, Object exports);
33+
TSFNWrap(const CallbackInfo &info);
34+
35+
Napi::Value DoCall(const CallbackInfo &info) {
36+
Napi::Env env = info.Env();
37+
TSFNData *data =
38+
new TSFNData{Napi::Reference<Napi::Value>(Persistent(info[0])),
39+
Promise::Deferred::New(env)};
40+
_tsfn.NonBlockingCall(data);
41+
return data->deferred.Promise();
42+
};
43+
44+
Napi::Value Release(const CallbackInfo &) {
45+
_tsfn.Release();
46+
return _deferred.Promise();
47+
};
48+
49+
private:
50+
TSFN _tsfn;
51+
Promise::Deferred _deferred;
52+
};
53+
54+
Object TSFNWrap::Init(Napi::Env env, Object exports) {
55+
Function func = DefineClass(env, "TSFNWrap",
56+
{InstanceMethod("doCall", &TSFNWrap::DoCall),
57+
InstanceMethod("release", &TSFNWrap::Release)});
58+
59+
exports.Set("TSFNWrap", func);
60+
return exports;
61+
}
62+
63+
TSFNWrap::TSFNWrap(const CallbackInfo &info)
64+
: ObjectWrap<TSFNWrap>(info),
65+
_deferred(Promise::Deferred::New(info.Env())) {
66+
Napi::Env env = info.Env();
67+
Function callback = info[0].As<Function>();
68+
69+
_tsfn = TSFN::New(env, // napi_env env,
70+
callback, // const Function& callback,
71+
Value(), // const Object& resource,
72+
"Test", // ResourceString resourceName,
73+
0, // size_t maxQueueSize,
74+
1 // size_t initialThreadCount,
75+
);
76+
}
77+
} // namespace
78+
79+
Object InitThreadSafeFunctionExCall(Env env) {
80+
return TSFNWrap::Init(env, Object::New(env));
81+
}
82+
83+
#endif

test/threadsafe_function_ex/call.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
'use strict';
2+
3+
const assert = require('assert');
4+
const buildType = process.config.target_defaults.default_configuration;
5+
6+
module.exports = Promise.all([
7+
test(require(`../build/${buildType}/binding.node`)),
8+
test(require(`../build/${buildType}/binding_noexcept.node`))
9+
]);
10+
11+
async function test(binding) {
12+
const data = {};
13+
const tsfn = new binding.threadsafe_function_ex_call.TSFNWrap(tsfnData => {
14+
assert(data === tsfnData, "Data in and out of tsfn call do not equal");
15+
});
16+
await tsfn.doCall(data);
17+
await tsfn.release();
18+
}

0 commit comments

Comments
 (0)