FOSSredder 0.5.0
Loading...
Searching...
No Matches
Scheduler.cpp
Go to the documentation of this file.
1
5
7
9
10#include <algorithm>
11#include <utility>
12
13namespace core::jobs {
14
15namespace {
16
17constexpr std::size_t kMinimumWorkerCount = 1;
18
19} // namespace
20
21SlotLimiter::SlotLimiter(std::size_t slots)
22 : slots_(std::max<std::size_t>(kMinimumWorkerCount, slots))
23 , available_(std::max<std::size_t>(kMinimumWorkerCount, slots))
24{
25}
26
28{
29 std::unique_lock<std::mutex> lk(m_);
30 cv_.wait(lk, [&]() { return available_ > 0; });
31 --available_;
32}
33
35{
36 {
37 std::lock_guard<std::mutex> g(m_);
38 available_ = std::min(slots_, available_ + 1);
39 }
40 cv_.notify_one();
41}
42
44 std::size_t workers, std::size_t queueCapacity,
45 std::shared_ptr<core::ports::diagnostics::IErrorReporter> errorReporter)
46 : cap_(std::max<std::size_t>(kMinimumWorkerCount, queueCapacity))
47 , errorReporter_(std::move(errorReporter))
48{
49 workers = std::max<std::size_t>(kMinimumWorkerCount, workers);
50 workers_.reserve(workers);
51 for (std::size_t i = 0; i < workers; ++i) {
52 workers_.emplace_back([this]() { workerLoop(); });
53 }
54}
55
60
62{
63 {
64 std::lock_guard<std::mutex> g(m_);
65 if (stopping_) return;
66 stopping_ = true;
67 }
68
69 cvNotEmpty_.notify_all();
70 cvNotFull_.notify_all();
71
72 for (auto& w : workers_) {
73 try {
74 if (w.joinable()) w.join();
75 } catch (...) {
76 core::errors::reportException(errorReporter_.get(),
78 "core::jobs::Scheduler::stop::join",
79 std::current_exception());
80 }
81 }
82 workers_.clear();
83}
84
86{
87 if (!t) return;
88
89 std::unique_lock<std::mutex> lk(m_);
90 cvNotFull_.wait(lk, [&]() { return stopping_ || q_.size() < cap_; });
91 if (stopping_) return;
92 q_.push_back(std::move(t));
93 lk.unlock();
94 cvNotEmpty_.notify_one();
95}
96
97void Scheduler::workerLoop()
98{
99 while (true) {
100 Task t;
101 {
102 std::unique_lock<std::mutex> lk(m_);
103 cvNotEmpty_.wait(lk, [&]() { return stopping_ || !q_.empty(); });
104 if (stopping_ && q_.empty()) return;
105 t = std::move(q_.front());
106 q_.pop_front();
107 }
108 cvNotFull_.notify_one();
109
110 try {
111 if (t) t();
112 } catch (...) {
113 core::errors::reportException(errorReporter_.get(),
115 "core::jobs::Scheduler::workerLoop::task",
116 std::current_exception());
117 }
118 }
119}
120
121}
Provides shared helpers for reporting structured errors and exceptions.
Declares a bounded worker queue and a simple slot limiter for import tasks.
void enqueue(Task t)
Enqueue a task, blocking when the queue is full.
Definition Scheduler.cpp:85
std::function< void()> Task
Definition Scheduler.h:57
Scheduler(std::size_t workers, std::size_t queueCapacity, std::shared_ptr< core::ports::diagnostics::IErrorReporter > errorReporter)
Create a scheduler with bounded workers and queue capacity.
Definition Scheduler.cpp:43
void stop()
Stop accepting new tasks and join all worker threads.
Definition Scheduler.cpp:61
~Scheduler()
Stop workers and destroy the scheduler.
Definition Scheduler.cpp:56
void release()
Release one acquired slot and wake a waiting caller.
Definition Scheduler.cpp:34
SlotLimiter(std::size_t slots)
Create a limiter with at least one available slot.
Definition Scheduler.cpp:21
void acquire()
Block until a slot is available and acquire it.
Definition Scheduler.cpp:27
void reportException(core::ports::diagnostics::IErrorReporter *reporter, ErrorSeverity severity, const char *origin, std::exception_ptr exception)
Report an exception through the reporter's default exception handling.