|
- #pragma once
-
- #include <ecs/core/utils/thread_pool/worker.h>
- #include <ecs/core/utils/thread_pool/task_queue.inl>
-
- namespace ecs {
- namespace core {
- namespace utils {
-
- inline thread_pool_worker
- ::thread_pool_worker(concurrent_task_queue& all_tasks, size_t thread_id) noexcept
- : _all_tasks(all_tasks)
- , _thread_id(thread_id)
- { }
-
- template<typename T_rep, typename T_period>
- inline bool thread_pool_worker
- ::pop(task& t, const std::chrono::duration<T_rep, T_period>& timeout)
- {
- std::unique_lock<std::mutex> lock(_mutex);
- do
- {
- if (_state != state::running)
- {
- return false;
- }
- if (!_own_tasks.empty())
- {
- t = std::move(_own_tasks.front());
- _own_tasks.pop();
- return true;
- }
- if (!_all_tasks.empty() && _all_tasks.pop(t)) // TODO: this will sometimes return false, even if the queue is not yet empty
- {
- return true;
- }
- } while(_conditional.wait_for(lock, timeout) != std::cv_status::timeout);
- return false;
- }
-
- template<typename T_counter>
- inline void thread_pool_worker
- ::start(T_counter& remaining_inits)
- {
- _thread = std::thread([this, &remaining_inits]{
- --remaining_inits;
- run();
- });
- }
-
- inline void thread_pool_worker
- ::stop() noexcept
- {
- assert(_state == state::running);
- _state = state::stopped;
- }
-
- inline void thread_pool_worker
- ::join() noexcept
- {
- assert(_thread.joinable());
- _thread.join();
- }
-
- inline bool thread_pool_worker
- ::finished() const noexcept
- {
- return _state == state::finished;
- }
-
- template<typename T_task>
- inline void thread_pool_worker
- ::post(T_task&& task)
- {
- std::unique_lock<std::mutex> lock(_mutex);
- _own_tasks.emplace(std::forward<T_task>(task));
- signal();
- }
-
- inline void thread_pool_worker
- ::signal()
- {
- _conditional.notify_all();
- }
-
- } } }
|