Bitcoin ABC 0.33.11
P2P Digital Currency
scheduler.h
Go to the documentation of this file.
1// Copyright (c) 2015 The Bitcoin Core developers
2// Distributed under the MIT software license, see the accompanying
3// file COPYING or http://www.opensource.org/licenses/mit-license.php.
4
5#ifndef BITCOIN_SCHEDULER_H
6#define BITCOIN_SCHEDULER_H
7
8#include <attributes.h>
9#include <sync.h>
10#include <threadsafety.h>
11#include <util/task_runner.h>
12
13#include <chrono>
14#include <condition_variable>
15#include <cstddef>
16#include <functional>
17#include <list>
18#include <map>
19#include <thread>
20#include <utility>
21
43public:
46
47 std::thread m_service_thread;
48
49 typedef std::function<void()> Function;
50 typedef std::function<bool()> Predicate;
51
53 void schedule(Function f, std::chrono::steady_clock::time_point t)
55
57 void scheduleFromNow(Function f, std::chrono::milliseconds delta)
59 schedule(std::move(f), std::chrono::steady_clock::now() + delta);
60 }
61
69 void scheduleEvery(Predicate p, std::chrono::milliseconds delta)
71
77 void MockForward(std::chrono::seconds delta_seconds)
79
84
90 WITH_LOCK(newTaskMutex, stopRequested = true);
91 newTaskScheduled.notify_all();
92 if (m_service_thread.joinable()) {
93 m_service_thread.join();
94 }
95 }
96
102 WITH_LOCK(newTaskMutex, stopWhenEmpty = true);
103 newTaskScheduled.notify_all();
104 if (m_service_thread.joinable()) {
105 m_service_thread.join();
106 }
107 }
108
113 size_t getQueueInfo(std::chrono::steady_clock::time_point &first,
114 std::chrono::steady_clock::time_point &last) const
116
118 bool AreThreadsServicingQueue() const
120
121private:
123 std::condition_variable newTaskScheduled;
124 std::multimap<std::chrono::steady_clock::time_point, Function>
126 int nThreadsServicingQueue GUARDED_BY(newTaskMutex){0};
127 bool stopRequested GUARDED_BY(newTaskMutex){false};
128 bool stopWhenEmpty GUARDED_BY(newTaskMutex){false};
130 return stopRequested || (stopWhenEmpty && taskQueue.empty());
131 }
132};
133
145private:
147
149
150 // We are not allowed to assume the scheduler only runs in one thread,
151 // but must ensure all callbacks happen in-order, so we end up creating
152 // our own queue here :(
153 std::list<std::function<void()>>
154 m_callbacks_pending GUARDED_BY(m_callbacks_mutex);
155 bool m_are_callbacks_running GUARDED_BY(m_callbacks_mutex) = false;
156
160
161public:
163 : m_scheduler{scheduler} {}
164
171 void insert(std::function<void()> func) override
173
180
182};
183
184#endif // BITCOIN_SCHEDULER_H
#define LIFETIMEBOUND
Definition: attributes.h:16
Simple class for background tasks that should be run periodically or once "after a while".
Definition: scheduler.h:42
void MockForward(std::chrono::seconds delta_seconds) EXCLUSIVE_LOCKS_REQUIRED(!newTaskMutex)
Mock the scheduler to fast forward in time.
Definition: scheduler.cpp:84
bool stopWhenEmpty GUARDED_BY(newTaskMutex)
Definition: scheduler.h:128
void serviceQueue() EXCLUSIVE_LOCKS_REQUIRED(!newTaskMutex)
Services the queue 'forever'.
Definition: scheduler.cpp:24
std::function< bool()> Predicate
Definition: scheduler.h:50
bool stopRequested GUARDED_BY(newTaskMutex)
Definition: scheduler.h:127
void scheduleEvery(Predicate p, std::chrono::milliseconds delta) EXCLUSIVE_LOCKS_REQUIRED(!newTaskMutex)
Repeat p until it return false.
Definition: scheduler.cpp:115
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.
Definition: scheduler.cpp:121
std::function< void()> Function
Definition: scheduler.h:49
std::thread m_service_thread
Definition: scheduler.h:47
std::multimap< std::chrono::steady_clock::time_point, Function > taskQueue GUARDED_BY(newTaskMutex)
bool AreThreadsServicingQueue() const EXCLUSIVE_LOCKS_REQUIRED(!newTaskMutex)
Returns true if there are threads actively running in serviceQueue()
Definition: scheduler.cpp:132
bool shouldStop() const EXCLUSIVE_LOCKS_REQUIRED(newTaskMutex)
Definition: scheduler.h:129
void StopWhenDrained() EXCLUSIVE_LOCKS_REQUIRED(!newTaskMutex)
Tell any threads running serviceQueue to stop when there is no work left to be done.
Definition: scheduler.h:101
std::condition_variable newTaskScheduled
Definition: scheduler.h:123
void stop() EXCLUSIVE_LOCKS_REQUIRED(!newTaskMutex)
Tell any threads running serviceQueue to stop as soon as the current task is done.
Definition: scheduler.h:89
Mutex newTaskMutex
Definition: scheduler.h:122
void scheduleFromNow(Function f, std::chrono::milliseconds delta) EXCLUSIVE_LOCKS_REQUIRED(!newTaskMutex)
Call f once after the delta has passed.
Definition: scheduler.h:57
void schedule(Function f, std::chrono::steady_clock::time_point t) EXCLUSIVE_LOCKS_REQUIRED(!newTaskMutex)
Call func at/after time t.
Definition: scheduler.cpp:75
Class used by CScheduler clients which may schedule multiple jobs which are required to be run serial...
Definition: scheduler.h:144
bool m_are_callbacks_running GUARDED_BY(m_callbacks_mutex)
void MaybeScheduleProcessQueue() EXCLUSIVE_LOCKS_REQUIRED(!m_callbacks_mutex)
Definition: scheduler.cpp:137
void ProcessQueue() EXCLUSIVE_LOCKS_REQUIRED(!m_callbacks_mutex)
Definition: scheduler.cpp:154
size_t size() override EXCLUSIVE_LOCKS_REQUIRED(!m_callbacks_mutex)
Returns the number of currently pending events.
Definition: scheduler.cpp:207
void insert(std::function< void()> func) override EXCLUSIVE_LOCKS_REQUIRED(!m_callbacks_mutex)
Add a callback to be executed.
Definition: scheduler.cpp:189
std::list< std::function< void()> > m_callbacks_pending GUARDED_BY(m_callbacks_mutex)
Mutex m_callbacks_mutex
Definition: scheduler.h:148
CScheduler & m_scheduler
Definition: scheduler.h:146
void flush() override EXCLUSIVE_LOCKS_REQUIRED(!m_callbacks_mutex)
Processes all remaining queue members on the calling thread, blocking until queue is empty.
Definition: scheduler.cpp:197
Implement std::hash so RCUPtr can be used as a key for maps or sets.
Definition: rcu.h:259
#define WITH_LOCK(cs, code)
Run code while locking a mutex.
Definition: sync.h:357
This header provides an interface and simple implementation for a task runner.
#define EXCLUSIVE_LOCKS_REQUIRED(...)
Definition: threadsafety.h:56