Skip to content

Commit 9d2c394

Browse files
author
Gabriel Schulhof
committed
test: fix tsfn sum test
The TSFN sum test was not waiting for all TSFN calls to complete before releasing the TSFN completely. The main thread must only release the TSFN and resolve the deferred if all calls have completed.
1 parent 3661d0e commit 9d2c394

File tree

1 file changed

+21
-6
lines changed

1 file changed

+21
-6
lines changed

test/threadsafe_function/threadsafe_function_sum.cc

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,21 @@ namespace {
1313
struct 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

163179
static 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

Comments
 (0)