Go to the documentation of this file.
9 #ifndef EAGINE_WORKSHOP_HPP
10 #define EAGINE_WORKSHOP_HPP
17 #include <condition_variable>
27 struct work_unit : interface<work_unit> {
28 virtual auto do_it() ->
bool = 0;
29 virtual void deliver() = 0;
34 std::vector<std::thread> _workers{};
36 std::condition_variable _cond{};
37 std::queue<work_unit*> _work_queue{};
38 bool _shutdown{
false};
40 auto _fetch() -> std::tuple<work_unit*, bool> {
41 std::unique_lock lock{_mutex};
42 work_unit* work =
nullptr;
45 lock, [
this] {
return !_work_queue.empty() || _shutdown; });
46 if(!_work_queue.empty()) {
47 work = _work_queue.front();
51 return {work, _shutdown};
56 auto [opt_work, shutdown] = _fetch();
60 std::unique_lock lock{_mutex};
75 workshop(workshop&&) =
delete;
76 workshop(
const workshop&) =
delete;
77 auto operator=(workshop&&) =
delete;
78 auto operator=(
const workshop&) =
delete;
79 ~workshop() noexcept {
87 auto shutdown() -> workshop& {
88 std::unique_lock lock{_mutex};
94 auto wait_until_closed() -> workshop& {
95 for(
auto& worker : _workers) {
101 auto wait_until_idle() -> workshop& {
102 std::unique_lock lock{_mutex};
103 _cond.wait(lock, [
this]() {
return _work_queue.empty(); });
107 auto add_worker() -> workshop& {
108 _workers.emplace_back([
this]() { this->_employ(); });
113 _workers.reserve(_workers.size() +
std_size(n));
115 EAGINE_MAYBE_UNUSED(i);
122 const auto c =
span_size(_workers.size());
129 auto populate() -> workshop& {
130 return ensure_workers(
span_size(std::thread::hardware_concurrency()));
133 auto release_worker() -> workshop& {
138 auto enqueue(work_unit& work) -> workshop& {
139 std::unique_lock lock{_mutex};
140 if(EAGINE_UNLIKELY(_workers.empty())) {
143 _work_queue.push(&work);
151 #endif // EAGINE_WORKSHOP_HPP
std::ptrdiff_t span_size_t
Signed span size type used by eagine.
Definition: types.hpp:36
static constexpr auto span_size(T v) noexcept
Converts argument to span size type.
Definition: types.hpp:59
Common code is placed in this namespace.
Definition: eagine.hpp:21
static constexpr auto extract(api_result_value< Result, api_result_validity::never > &) noexcept -> Result &
Overload of extract for api_result_value.
Definition: c_api_wrap.hpp:270
static constexpr auto std_size(T v) noexcept
Converts argument to std size type.
Definition: types.hpp:52
integer_range(B, E) -> integer_range< std::common_type_t< B, E >>
Deduction guide for integer_range.