diff --git a/libstdc++-v3/testsuite/30_threads/condition_variable/54185.cc b/libstdc++-v3/testsuite/30_threads/condition_variable/54185.cc index ea0d5bb8740..8ccb79e6de6 100644 --- a/libstdc++-v3/testsuite/30_threads/condition_variable/54185.cc +++ b/libstdc++-v3/testsuite/30_threads/condition_variable/54185.cc @@ -31,31 +31,48 @@ std::condition_variable* cond = nullptr; std::mutex mx; int started = 0; +bool notified = false; int constexpr NUM_THREADS = 10; -void do_thread_a() +void do_thread_a(bool wait) { std::unique_lock lock(mx); - if(++started >= NUM_THREADS) + if (++started >= NUM_THREADS) { + notified = true; cond->notify_all(); delete cond; cond = nullptr; } - else - cond->wait(lock); + else if (wait) + cond->wait(lock, [] { return notified; }); } -int main(){ +int main() +{ std::vector vec; - for(int j = 0; j < 1000; ++j) + for (int j = 0; j < 1000; ++j) { started = 0; + notified = false; cond = new std::condition_variable; for (int i = 0; i < NUM_THREADS; ++i) - vec.emplace_back(&do_thread_a); - for (int i = 0; i < NUM_THREADS; ++i) - vec[i].join(); + { + try + { + vec.emplace_back(&do_thread_a, true); + } + catch(const std::system_error& e) + { + if (e.code() == std::errc::resource_unavailable_try_again) + // Thread creation may fail due to resource limits; run serially. + do_thread_a(false); + else + throw; + } + } + for (auto& thread : vec) + thread.join(); vec.clear(); } }