17#include <boost/shared_ptr.hpp>
32 : pool_size_(pool_size), io_service_(io_service),
33 run_state_(
State::STOPPED), mutex_(), thread_cv_(),
34 main_cv_(), paused_(0), running_(0), exited_(0) {
74IoServiceThreadPool::getState() {
75 std::lock_guard<std::mutex> lck(mutex_);
80IoServiceThreadPool::validateStateChange(
State state)
const {
93IoServiceThreadPool::stateToText(State state) {
96 return (std::string(
"stopped"));
98 return (std::string(
"running"));
100 return (std::string(
"paused"));
102 return (std::string(
"unknown-state"));
111IoServiceThreadPool::checkPermissions(
State state) {
112 auto id = std::this_thread::get_id();
113 if (checkThreadId(
id)) {
115 << IoServiceThreadPool::stateToText(state) <<
" performed by worker thread");
120IoServiceThreadPool::checkThreadId(std::thread::id
id) {
121 for (
auto const& thread : threads_) {
122 if (
id == thread->get_id()) {
130IoServiceThreadPool::setState(State state) {
131 checkPermissions(state);
133 std::unique_lock<std::mutex> main_lck(mutex_);
136 if (!validateStateChange(state)) {
142 thread_cv_.notify_all();
147 io_service_->restart();
150 while (threads_.size() < pool_size_) {
151 boost::shared_ptr<std::thread> thread(
new std::thread(
152 std::bind(&IoServiceThreadPool::threadWork,
this)));
155 threads_.push_back(thread);
159 main_cv_.wait(main_lck,
161 return (running_ == threads_.size());
170 if (!io_service_->stopped()) {
181 main_cv_.wait(main_lck,
183 return (paused_ == threads_.size());
191 if (!io_service_->stopped()) {
202 main_cv_.wait(main_lck,
204 return (exited_ == threads_.size());
207 for (
auto const& thread : threads_) {
217IoServiceThreadPool::threadWork() {
220 switch (getState()) {
223 std::unique_lock<std::mutex> lck(mutex_);
227 if (running_ == pool_size_) {
228 main_cv_.notify_all();
241 std::unique_lock<std::mutex> lck(mutex_);
249 std::unique_lock<std::mutex> lck(mutex_);
253 if (paused_ == threads_.size()) {
254 main_cv_.notify_all();
273 std::unique_lock<std::mutex> lck(mutex_);
277 if (exited_ == threads_.size()) {
278 main_cv_.notify_all();
284 return (io_service_);
294 return (threads_.size());
A generic exception that is thrown if a parameter given to a method is considered invalid in that con...
Exception thrown when a worker thread is trying to stop or pause the respective thread pool (which wo...
The IOService class is a wrapper for the ASIO io_context class.
asiolink::IOServicePtr getIOService() const
Fetches the IOService that drives the pool.
void checkPausePermissions()
Check current thread permissions to transition to the new PAUSED state.
uint16_t getPoolSize() const
Fetches the maximum size of the thread pool.
~IoServiceThreadPool()
Destructor.
void stop()
Transitions the pool from RUNNING or PAUSED to STOPPED.
void pause()
Transitions the pool from RUNNING to PAUSED.
IoServiceThreadPool(asiolink::IOServicePtr io_service, size_t pool_size, bool defer_start=false)
Constructor.
void run()
Transitions the pool from STOPPED or PAUSED to RUNNING.
uint16_t getThreadCount() const
Fetches the number of threads in the pool.
State
Describes the possible operational state of the thread pool.
@ RUNNING
Pool is not operational.
@ PAUSED
Pool is populated with running threads.
Defines a State within the State Model.
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
boost::shared_ptr< IOService > IOServicePtr
Defines a smart pointer to an IOService instance.
Defines the logger used by the top-level component of kea-lfc.