libstdc++: testsuite: Address random failure in pthread_create() [PR54185] The test for this PR calls pthread_create() many times in a row, which may fail with EAGAIN sometimes. Avoid generating a test failure in this case. libstdc++-v3/ChangeLog: PR libstdc++/54185 * testsuite/30_threads/condition_variable/54185.cc: Make test robust to random pthread_create() failures. diff --git a/libstdc++-v3/testsuite/30_threads/condition_variable/54185.cc b/libstdc++-v3/testsuite/30_threads/condition_variable/54185.cc index ea0d5bb8740..cbd21e11e57 100644 --- a/libstdc++-v3/testsuite/30_threads/condition_variable/54185.cc +++ b/libstdc++-v3/testsuite/30_threads/condition_variable/54185.cc @@ -31,19 +31,25 @@ std::condition_variable* cond = nullptr; std::mutex mx; int started = 0; +bool notified = false; int constexpr NUM_THREADS = 10; +static void finalize_cond() +{ + /* Lock should be held when calling this. */ + notified = true; + cond->notify_all(); + delete cond; + cond = nullptr; +} + void do_thread_a() { std::unique_lock lock(mx); if(++started >= NUM_THREADS) - { - cond->notify_all(); - delete cond; - cond = nullptr; - } + finalize_cond(); else - cond->wait(lock); + cond->wait(lock, [] { return notified; }); } int main(){ @@ -51,11 +57,24 @@ int main(){ 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); + } + catch(const std::system_error&) + { + /* Thread creation may fail due to resource limits; just move on. */ + std::unique_lock lock(mx); + finalize_cond(); + break; + } + } + for(auto& thread: vec) + thread.join(); vec.clear(); } }