-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtsfn_test.cc
68 lines (59 loc) · 1.8 KB
/
tsfn_test.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
#include <stdarg.h>
#include <chrono>
#include <thread>
#include <napi.h>
void fpstderr_sync(const char *str, ...) {
va_list ap;
va_start(ap, str);
vfprintf(stderr, str, ap);
fflush(stderr);
va_end(ap);
}
class TSFNOR : public Napi::ObjectWrap<TSFNOR> {
public:
static Napi::Object Init(Napi::Env env) {
return DefineClass(env, "TSFNOR", {});
}
TSFNOR(const Napi::CallbackInfo& info): Napi::ObjectWrap<TSFNOR>(info) {
_tsfn = Napi::ThreadSafeFunction::New(
info.Env(),
info[0].As<Napi::Function>(),
"TSFNOR",
1,
1);
_thread = std::thread(&TSFNOR::Thread, std::ref(_tsfn));
}
~TSFNOR() {
_thread.join();
}
private:
static void Thread(const Napi::ThreadSafeFunction& tsfn) {
int the_value = 0;
while(true) {
fpstderr_sync("Thread: Issuing blocking call with %d\n", the_value);
int* value_copy = new int(the_value);
napi_status status = tsfn.BlockingCall(
value_copy,
[](Napi::Env env, Napi::Function fn, int* data) {
int native_value = *data;
delete data;
fpstderr_sync("main with %d: Calling into JS\n", native_value);
fn.Call({Napi::Number::New(env, *data)});
fpstderr_sync("main with %d: exception is %spending\n", native_value, env.IsExceptionPending() ? "" : "not ");
});
fpstderr_sync("Thread: Status for %d: %d\n", the_value, status);
if (status == napi_closing) {
fpstderr_sync("Thread: TSFN is closing\n");
break;
}
the_value++;
}
fpstderr_sync("Thread: Exiting\n");
}
Napi::ThreadSafeFunction _tsfn;
std::thread _thread;
};
Napi::Object TsfnTestInit(Napi::Env env, Napi::Object exports) {
return TSFNOR::Init(env);
}
NODE_API_MODULE(TsfnTest, TsfnTestInit)