1
+ #include < future>
1
2
#include " napi.h"
2
3
3
4
using namespace Napi ;
4
5
5
6
namespace {
6
7
8
+ std::promise<void > promise_for_child_process_;
9
+ std::promise<void > promise_for_worker_thread_;
10
+
11
+ void ResetPromises (const CallbackInfo&) {
12
+ promise_for_child_process_ = std::promise<void >();
13
+ promise_for_worker_thread_ = std::promise<void >();
14
+ }
15
+
16
+ void WaitForWorkerThread (const CallbackInfo&) {
17
+ std::future<void > future = promise_for_worker_thread_.get_future ();
18
+
19
+ std::future_status status = future.wait_for (std::chrono::seconds (5 ));
20
+
21
+ if (status != std::future_status::ready) {
22
+ Error::Fatal (" WaitForWorkerThread" , " status != std::future_status::ready" );
23
+ }
24
+ }
25
+
26
+ void ReleaseAndWaitForChildProcess (const CallbackInfo& info,
27
+ const uint32_t index) {
28
+ if (info.Length () < index + 1 ) {
29
+ return ;
30
+ }
31
+
32
+ if (!info[index ].As <Boolean >().Value ()) {
33
+ return ;
34
+ }
35
+
36
+ promise_for_worker_thread_.set_value ();
37
+
38
+ std::future<void > future = promise_for_child_process_.get_future ();
39
+
40
+ std::future_status status = future.wait_for (std::chrono::seconds (5 ));
41
+
42
+ if (status != std::future_status::ready) {
43
+ Error::Fatal (" ReleaseAndWaitForChildProcess" ,
44
+ " status != std::future_status::ready" );
45
+ }
46
+ }
47
+
48
+ void ReleaseWorkerThread (const CallbackInfo&) {
49
+ promise_for_child_process_.set_value ();
50
+ }
51
+
7
52
void DoNotCatch (const CallbackInfo& info) {
8
53
Function thrower = info[0 ].As <Function>();
9
54
thrower ({});
@@ -18,16 +63,22 @@ void ThrowApiError(const CallbackInfo& info) {
18
63
19
64
void ThrowJSError (const CallbackInfo& info) {
20
65
std::string message = info[0 ].As <String>().Utf8Value ();
66
+
67
+ ReleaseAndWaitForChildProcess (info, 1 );
21
68
throw Error::New (info.Env (), message);
22
69
}
23
70
24
71
void ThrowTypeError (const CallbackInfo& info) {
25
72
std::string message = info[0 ].As <String>().Utf8Value ();
73
+
74
+ ReleaseAndWaitForChildProcess (info, 1 );
26
75
throw TypeError::New (info.Env (), message);
27
76
}
28
77
29
78
void ThrowRangeError (const CallbackInfo& info) {
30
79
std::string message = info[0 ].As <String>().Utf8Value ();
80
+
81
+ ReleaseAndWaitForChildProcess (info, 1 );
31
82
throw RangeError::New (info.Env (), message);
32
83
}
33
84
@@ -83,16 +134,22 @@ void CatchAndRethrowErrorThatEscapesScope(const CallbackInfo& info) {
83
134
84
135
void ThrowJSError (const CallbackInfo& info) {
85
136
std::string message = info[0 ].As <String>().Utf8Value ();
137
+
138
+ ReleaseAndWaitForChildProcess (info, 1 );
86
139
Error::New (info.Env (), message).ThrowAsJavaScriptException ();
87
140
}
88
141
89
142
void ThrowTypeError (const CallbackInfo& info) {
90
143
std::string message = info[0 ].As <String>().Utf8Value ();
144
+
145
+ ReleaseAndWaitForChildProcess (info, 1 );
91
146
TypeError::New (info.Env (), message).ThrowAsJavaScriptException ();
92
147
}
93
148
94
149
void ThrowRangeError (const CallbackInfo& info) {
95
150
std::string message = info[0 ].As <String>().Utf8Value ();
151
+
152
+ ReleaseAndWaitForChildProcess (info, 1 );
96
153
RangeError::New (info.Env (), message).ThrowAsJavaScriptException ();
97
154
}
98
155
@@ -187,6 +244,8 @@ void ThrowDefaultError(const CallbackInfo& info) {
187
244
Error::Fatal (" ThrowDefaultError" , " napi_get_named_property" );
188
245
}
189
246
247
+ ReleaseAndWaitForChildProcess (info, 1 );
248
+
190
249
// The macro creates a `Napi::Error` using the factory that takes only the
191
250
// env, however, it heeds the exception mechanism to be used.
192
251
NAPI_THROW_IF_FAILED_VOID (env, status);
@@ -209,5 +268,8 @@ Object InitError(Env env) {
209
268
Function::New (env, CatchAndRethrowErrorThatEscapesScope);
210
269
exports[" throwFatalError" ] = Function::New (env, ThrowFatalError);
211
270
exports[" throwDefaultError" ] = Function::New (env, ThrowDefaultError);
271
+ exports[" resetPromises" ] = Function::New (env, ResetPromises);
272
+ exports[" waitForWorkerThread" ] = Function::New (env, WaitForWorkerThread);
273
+ exports[" releaseWorkerThread" ] = Function::New (env, ReleaseWorkerThread);
212
274
return exports;
213
275
}
0 commit comments