blob: 1fe7465cfec1ae1a1197489fbd8470fa4041d1f0 [file]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* License); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
#ifdef ENABLE_THREADS
#include "common/thread_pool.h"
#include <gtest/gtest.h>
#include <atomic>
#include <chrono>
#include <future>
#include <thread>
// Regression: a zero-sized ThreadPool used to silently accept submit() but
// block wait_all() forever (no worker thread, so active_ never reaches 0).
// init_common() clamps thread_count_ to >= 1 before building the global pool,
// but the ctor normalizes zero to a single worker as a defensive backstop so
// any direct ThreadPool(0) still makes progress instead of hanging.
TEST(ThreadPoolTest, ZeroThreadPoolStillExecutesAndDrains) {
common::ThreadPool pool(0);
EXPECT_GE(pool.num_threads(), static_cast<size_t>(1));
std::atomic<int> ran{0};
pool.submit([&ran]() { ran.fetch_add(1); });
auto fut = pool.submit([]() { return 42; });
auto wait_with_timeout = [&pool]() {
// wait_all has no timeout; run it in a helper thread we can join().
std::promise<void> done;
auto fut = done.get_future();
std::thread t([&pool, &done]() {
pool.wait_all();
done.set_value();
});
auto status = fut.wait_for(std::chrono::seconds(2));
if (status != std::future_status::ready) {
// Detach so a hung pool doesn't terminate the test process.
t.detach();
return false;
}
t.join();
return true;
};
ASSERT_TRUE(wait_with_timeout()) << "wait_all hung — zero-thread pool";
EXPECT_EQ(ran.load(), 1);
EXPECT_EQ(fut.get(), 42);
}
#endif // ENABLE_THREADS