@@ -13,12 +13,21 @@ namespace {
1313struct TestData {
1414
1515 TestData (Promise::Deferred&& deferred) : deferred(std::move(deferred)) {};
16+
17+ // These variables are accessed only from the main thread. They keep track of
18+ // the number of expected incoming calls that have completed. We do not want
19+ // to release the thread-safe function until all expected calls are complete.
20+ size_t threadsCreated = 0 ;
21+ size_t callsCompleted = 0 ;
22+ // A value of true for this variable indicates that no more new threads will
23+ // be created.
24+ bool threadsStopped = false ;
1625
1726 // Native Promise returned to JavaScript
1827 Promise::Deferred deferred;
1928
20- // List of threads created for test. This list only ever accessed via main
21- // thread.
29+ // List of threads created for test. This list is only ever accessed via the
30+ // main thread.
2231 std::vector<std::thread> threads = {};
2332
2433 ThreadSafeFunction tsfn = ThreadSafeFunction();
@@ -142,11 +151,16 @@ static Value TestDelayedTSFN(const CallbackInfo &info) {
142151 return testData->deferred .Promise ();
143152}
144153
145- void entryAcquire (ThreadSafeFunction tsfn, int threadId) {
154+ void entryAcquire (ThreadSafeFunction tsfn, int threadId, TestData* testData ) {
146155 tsfn.Acquire ();
147156 std::this_thread::sleep_for (std::chrono::milliseconds (std::rand () % 100 + 1 ));
148157 tsfn.BlockingCall ( [=](Napi::Env env, Function callback) {
149158 callback.Call ( { Number::New (env, static_cast <double >(threadId))});
159+ testData->callsCompleted ++;
160+ if (testData->threadsStopped &&
161+ testData->callsCompleted == testData->threadsCreated ) {
162+ testData->tsfn .Release ();
163+ }
150164 });
151165 tsfn.Release ();
152166}
@@ -156,14 +170,15 @@ static Value CreateThread(const CallbackInfo& info) {
156170 ThreadSafeFunction tsfn = testData->tsfn ;
157171 int threadId = testData->threads .size ();
158172 // A copy of the ThreadSafeFunction will go to the thread entry point
159- testData->threads .push_back ( std::thread (entryAcquire, tsfn, threadId) );
173+ testData->threads
174+ .push_back (std::thread (entryAcquire, tsfn, threadId, testData));
175+ testData->threadsCreated ++;
160176 return Number::New (info.Env (), threadId);
161177}
162178
163179static Value StopThreads (const CallbackInfo& info) {
164180 TestData* testData = static_cast <TestData*>(info.Data ());
165- ThreadSafeFunction tsfn = testData->tsfn ;
166- tsfn.Release ();
181+ testData->threadsStopped = true ;
167182 return info.Env ().Undefined ();
168183}
169184
0 commit comments