Skip to content

Commit

Permalink
feat: thread pool object
Browse files Browse the repository at this point in the history
  • Loading branch information
braindigitalis committed Sep 24, 2024
1 parent 0cbb698 commit b63492f
Show file tree
Hide file tree
Showing 3 changed files with 125 additions and 0 deletions.
1 change: 1 addition & 0 deletions include/dpp/dpp.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,3 +76,4 @@
#include <dpp/timed_listener.h>
#include <dpp/collector.h>
#include <dpp/bignum.h>
#include <dpp/thread_pool.h>
50 changes: 50 additions & 0 deletions include/dpp/thread_pool.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/************************************************************************************
*
* D++, A Lightweight C++ library for Discord
*
* SPDX-License-Identifier: Apache-2.0
* Copyright 2021 Craig Edwards and D++ contributors
* (https://github.com/brainboxdotcc/DPP/graphs/contributors)
*
* Licensed 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.
*
************************************************************************************/

#pragma once
#include <thread>
#include <queue>
#include <vector>
#include <condition_variable>
#include <mutex>
#include <functional>

/**
* A task within a thread pool. A simple lambda that accepts no parameters and returns void.
*/
using thread_pool_task = std::function<void()>;

/**
* @brief A thread pool contains 1 or more worker threads which accept thread_pool_task lambadas
* into a queue, which is processed in-order by whichever thread is free.
*/
struct thread_pool {
std::vector<std::thread> threads;
std::queue<thread_pool_task> tasks;
std::mutex queue_mutex;
std::condition_variable cv;
bool stop{false};

explicit thread_pool(size_t num_threads = std::thread::hardware_concurrency());
~thread_pool();
void enqueue(thread_pool_task task);
};
74 changes: 74 additions & 0 deletions src/dpp/thread_pool.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
/************************************************************************************
*
* D++, A Lightweight C++ library for Discord
*
* SPDX-License-Identifier: Apache-2.0
* Copyright 2021 Craig Edwards and D++ contributors
* (https://github.com/brainboxdotcc/DPP/graphs/contributors)
*
* Licensed 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.
*
************************************************************************************/

#include <dpp/utility.h>
#include <ssod/thread_pool.h>
#include <shared_mutex>

thread_pool::thread_pool(size_t num_threads) {
for (size_t i = 0; i < num_threads; ++i) {
threads.emplace_back([this, i]() {
dpp::utility::set_thread_name("pool/exec/" + std::to_string(i));
while (true) {
thread_pool_task task;
{
std::unique_lock<std::mutex> lock(queue_mutex);

cv.wait(lock, [this] {
return !tasks.empty() || stop;
});

if (stop && tasks.empty()) {
return;
}

task = std::move(tasks.front());
tasks.pop();
}

task();
}
});
}
}

thread_pool::~thread_pool()
{
{
std::unique_lock<std::mutex> lock(queue_mutex);
stop = true;
}

cv.notify_all();
for (auto& thread : threads) {
thread.join();
}
}

void thread_pool::enqueue(thread_pool_task task)
{
{
std::unique_lock<std::mutex> lock(queue_mutex);
tasks.emplace(std::move(task));
}
cv.notify_one();
}

0 comments on commit b63492f

Please sign in to comment.