diff --git a/packages/react-native/ReactCxxPlatform/react/threading/TaskDispatchThread.cpp b/packages/react-native/ReactCxxPlatform/react/threading/TaskDispatchThread.cpp index f57774e8890..466d95b07f7 100644 --- a/packages/react-native/ReactCxxPlatform/react/threading/TaskDispatchThread.cpp +++ b/packages/react-native/ReactCxxPlatform/react/threading/TaskDispatchThread.cpp @@ -118,6 +118,7 @@ void TaskDispatchThread::loop() noexcept { if (task.dispatchTime > now) { // Wait until the scheduled task time, if delayed loopCv_.wait_until(lock, task.dispatchTime); + continue; } } else { // Shutting down, skip all the remaining tasks diff --git a/packages/react-native/ReactCxxPlatform/react/threading/tests/TaskDispatchThreadTests.cpp b/packages/react-native/ReactCxxPlatform/react/threading/tests/TaskDispatchThreadTests.cpp index 8bd61a703d5..867f1815df2 100644 --- a/packages/react-native/ReactCxxPlatform/react/threading/tests/TaskDispatchThreadTests.cpp +++ b/packages/react-native/ReactCxxPlatform/react/threading/tests/TaskDispatchThreadTests.cpp @@ -128,10 +128,12 @@ TEST_F(TaskDispatchThreadTest, RunAsyncFromMultipleThreads) { EXPECT_EQ(counter.load(), 3); } +// Test: quit() shouldn't block if it is called inside loop thread TEST_F(TaskDispatchThreadTest, QuitInTaskShouldntBeBlockedForever) { dispatcher->runSync([&] { dispatcher->quit(); }); } +// Test: quit() should wait for already running task in the thread TEST_F(TaskDispatchThreadTest, QuitShouldWaitAlreadyRunningTask) { { std::unique_ptr counter = std::make_unique(0); @@ -147,4 +149,14 @@ TEST_F(TaskDispatchThreadTest, QuitShouldWaitAlreadyRunningTask) { // forcing dispatcher to join thread dispatcher.reset(); } + +// Test: sync tasks shouldn't be blocked for forever due to delayed task +TEST_F(TaskDispatchThreadTest, SyncTaskShouldntBeBlockedDueToDelayedTask) { + std::atomic counter = 0; + constexpr int kHugeDelay = 100000; + dispatcher->runAsync([&] {}, std::chrono::seconds(kHugeDelay)); + std::this_thread::sleep_for(std::chrono::milliseconds(50)); + dispatcher->runSync([&] { counter++; }); + EXPECT_EQ(counter.load(), 1); +} } // namespace facebook::react