19 assert(nThreadsServicingQueue == 0);
20 if (stopWhenEmpty)
assert(taskQueue.empty());
28 ++nThreadsServicingQueue;
44 std::chrono::steady_clock::time_point timeToWaitFor = taskQueue.begin()->first;
45 if (
newTaskScheduled.wait_until(lock, timeToWaitFor) == std::cv_status::timeout) {
55 Function f = taskQueue.begin()->second;
56 taskQueue.erase(taskQueue.begin());
65 --nThreadsServicingQueue;
69 --nThreadsServicingQueue;
77 taskQueue.insert(std::make_pair(
t, f));
84 assert(delta_seconds > 0s && delta_seconds <= 1h);
90 std::multimap<std::chrono::steady_clock::time_point, Function> temp_queue;
92 for (
const auto& element : taskQueue) {
93 temp_queue.emplace_hint(temp_queue.cend(), element.first - delta_seconds, element.second);
97 taskQueue = std::move(temp_queue);
116 std::chrono::steady_clock::time_point& last)
const 119 size_t result = taskQueue.size();
120 if (!taskQueue.empty()) {
121 first = taskQueue.begin()->first;
122 last = taskQueue.rbegin()->first;
130 return nThreadsServicingQueue;
141 if (m_are_callbacks_running)
return;
142 if (m_callbacks_pending.empty())
return;
149 std::function<void()> callback;
152 if (m_are_callbacks_running)
return;
153 if (m_callbacks_pending.empty())
return;
154 m_are_callbacks_running =
true;
156 callback = std::move(m_callbacks_pending.front());
157 m_callbacks_pending.pop_front();
162 struct RAIICallbacksRunning {
165 ~RAIICallbacksRunning()
169 instance->m_are_callbacks_running =
false;
173 } raiicallbacksrunning(
this);
182 m_callbacks_pending.emplace_back(std::move(func));
190 bool should_continue =
true;
191 while (should_continue) {
194 should_continue = !m_callbacks_pending.empty();
201 return m_callbacks_pending.size();
Class used by CScheduler clients which may schedule multiple jobs which are required to be run serial...
void ProcessQueue() EXCLUSIVE_LOCKS_REQUIRED(!m_callbacks_mutex)
void EmptyQueue() EXCLUSIVE_LOCKS_REQUIRED(!m_callbacks_mutex)
Processes all remaining queue members on the calling thread, blocking until queue is empty Must be ca...
static void Repeat(CScheduler &s, CScheduler::Function f, std::chrono::milliseconds delta)
size_t CallbacksPending() EXCLUSIVE_LOCKS_REQUIRED(!m_callbacks_mutex)
std::function< void()> Function
size_t getQueueInfo(std::chrono::steady_clock::time_point &first, std::chrono::steady_clock::time_point &last) const EXCLUSIVE_LOCKS_REQUIRED(!newTaskMutex)
Returns number of tasks waiting to be serviced, and first and last task times.
std::condition_variable newTaskScheduled
void MockForward(std::chrono::seconds delta_seconds) EXCLUSIVE_LOCKS_REQUIRED(!newTaskMutex)
Mock the scheduler to fast forward in time.
void serviceQueue() EXCLUSIVE_LOCKS_REQUIRED(!newTaskMutex)
Services the queue 'forever'.
#define WAIT_LOCK(cs, name)
void SetSyscallSandboxPolicy(SyscallSandboxPolicy syscall_policy)
Force the current thread (and threads created from the current thread) into a restricted-service oper...
void MaybeScheduleProcessQueue() EXCLUSIVE_LOCKS_REQUIRED(!m_callbacks_mutex)
void scheduleFromNow(Function f, std::chrono::milliseconds delta) EXCLUSIVE_LOCKS_REQUIRED(!newTaskMutex)
Call f once after the delta has passed.
void schedule(Function f, std::chrono::steady_clock::time_point t) EXCLUSIVE_LOCKS_REQUIRED(!newTaskMutex)
Call func at/after time t.
bool AreThreadsServicingQueue() const EXCLUSIVE_LOCKS_REQUIRED(!newTaskMutex)
Returns true if there are threads actively running in serviceQueue()
Simple class for background tasks that should be run periodically or once "after a while"...
void AddToProcessQueue(std::function< void()> func) EXCLUSIVE_LOCKS_REQUIRED(!m_callbacks_mutex)
Add a callback to be executed.
void scheduleEvery(Function f, std::chrono::milliseconds delta) EXCLUSIVE_LOCKS_REQUIRED(!newTaskMutex)
Repeat f until the scheduler is stopped.
bool shouldStop() const EXCLUSIVE_LOCKS_REQUIRED(newTaskMutex)