21 assert(nThreadsServicingQueue == 0);
22 if (stopWhenEmpty)
assert(taskQueue.empty());
30 ++nThreadsServicingQueue;
46 std::chrono::system_clock::time_point timeToWaitFor = taskQueue.begin()->first;
47 if (
newTaskScheduled.wait_until(lock, timeToWaitFor) == std::cv_status::timeout) {
57 Function f = taskQueue.begin()->second;
58 taskQueue.erase(taskQueue.begin());
67 --nThreadsServicingQueue;
71 --nThreadsServicingQueue;
79 taskQueue.insert(std::make_pair(t, f));
86 assert(delta_seconds > 0s && delta_seconds <= 1h);
92 std::multimap<std::chrono::system_clock::time_point, Function> temp_queue;
94 for (
const auto& element : taskQueue) {
95 temp_queue.emplace_hint(temp_queue.cend(), element.first - delta_seconds, element.second);
99 taskQueue = std::move(temp_queue);
118 std::chrono::system_clock::time_point& last)
const
121 size_t result = taskQueue.size();
122 if (!taskQueue.empty()) {
123 first = taskQueue.begin()->first;
124 last = taskQueue.rbegin()->first;
132 return nThreadsServicingQueue;
143 if (m_are_callbacks_running)
return;
144 if (m_callbacks_pending.empty())
return;
151 std::function<void()> callback;
154 if (m_are_callbacks_running)
return;
155 if (m_callbacks_pending.empty())
return;
156 m_are_callbacks_running =
true;
158 callback = std::move(m_callbacks_pending.front());
159 m_callbacks_pending.pop_front();
164 struct RAIICallbacksRunning {
167 ~RAIICallbacksRunning()
171 instance->m_are_callbacks_running =
false;
175 } raiicallbacksrunning(
this);
186 m_callbacks_pending.emplace_back(std::move(func));
194 bool should_continue =
true;
195 while (should_continue) {
198 should_continue = !m_callbacks_pending.empty();
205 return m_callbacks_pending.size();
Simple class for background tasks that should be run periodically or once "after a while".
void serviceQueue()
Services the queue 'forever'.
void scheduleFromNow(Function f, std::chrono::milliseconds delta)
Call f once after the delta has passed.
void schedule(Function f, std::chrono::system_clock::time_point t)
Call func at/after time t.
void scheduleEvery(Function f, std::chrono::milliseconds delta)
Repeat f until the scheduler is stopped.
std::function< void()> Function
void MockForward(std::chrono::seconds delta_seconds)
Mock the scheduler to fast forward in time.
size_t getQueueInfo(std::chrono::system_clock::time_point &first, std::chrono::system_clock::time_point &last) const
Returns number of tasks waiting to be serviced, and first and last task times.
bool shouldStop() const EXCLUSIVE_LOCKS_REQUIRED(newTaskMutex)
bool AreThreadsServicingQueue() const
Returns true if there are threads actively running in serviceQueue()
std::condition_variable newTaskScheduled
Class used by CScheduler clients which may schedule multiple jobs which are required to be run serial...
void EmptyQueue()
Processes all remaining queue members on the calling thread, blocking until queue is empty Must be ca...
void MaybeScheduleProcessQueue()
void AddToProcessQueue(std::function< void()> func)
Add a callback to be executed.
size_t CallbacksPending()
RecursiveMutex m_cs_callbacks_pending
CScheduler * m_pscheduler
static void Repeat(CScheduler &s, CScheduler::Function f, std::chrono::milliseconds delta)
#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...