Bitcoin ABC  0.26.3
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 
12 #include <chrono>
13 #include <condition_variable>
14 #include <cstddef>
15 #include <functional>
16 #include <list>
17 #include <map>
18 #include <thread>
19 #include <utility>
20 
41 class CScheduler {
42 public:
43  CScheduler();
44  ~CScheduler();
45 
46  std::thread m_service_thread;
47 
48  typedef std::function<void()> Function;
49  typedef std::function<bool()> Predicate;
50 
52  void schedule(Function f, std::chrono::steady_clock::time_point t);
53 
55  void scheduleFromNow(Function f, std::chrono::milliseconds delta) {
56  schedule(std::move(f), std::chrono::steady_clock::now() + delta);
57  }
58 
66  void scheduleEvery(Predicate p, std::chrono::milliseconds delta);
67 
73  void MockForward(std::chrono::seconds delta_seconds);
74 
78  void serviceQueue();
79 
84  void stop() {
85  WITH_LOCK(newTaskMutex, stopRequested = true);
86  newTaskScheduled.notify_all();
87  if (m_service_thread.joinable()) {
88  m_service_thread.join();
89  }
90  }
91 
96  void StopWhenDrained() {
97  WITH_LOCK(newTaskMutex, stopWhenEmpty = true);
98  newTaskScheduled.notify_all();
99  if (m_service_thread.joinable()) {
100  m_service_thread.join();
101  }
102  }
103 
108  size_t getQueueInfo(std::chrono::steady_clock::time_point &first,
109  std::chrono::steady_clock::time_point &last) const;
110 
112  bool AreThreadsServicingQueue() const;
113 
114 private:
116  std::condition_variable newTaskScheduled;
117  std::multimap<std::chrono::steady_clock::time_point, Function>
119  int nThreadsServicingQueue GUARDED_BY(newTaskMutex){0};
120  bool stopRequested GUARDED_BY(newTaskMutex){false};
121  bool stopWhenEmpty GUARDED_BY(newTaskMutex){false};
123  return stopRequested || (stopWhenEmpty && taskQueue.empty());
124  }
125 };
126 
138 private:
140 
142  std::list<std::function<void()>>
143  m_callbacks_pending GUARDED_BY(m_cs_callbacks_pending);
144  bool m_are_callbacks_running GUARDED_BY(m_cs_callbacks_pending) = false;
145 
147  void ProcessQueue();
148 
149 public:
151  : m_scheduler{scheduler} {}
152 
159  void AddToProcessQueue(std::function<void()> func);
160 
166  void EmptyQueue();
167 
168  size_t CallbacksPending();
169 };
170 
171 #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:41
bool stopWhenEmpty GUARDED_BY(newTaskMutex)
Definition: scheduler.h:121
void serviceQueue()
Services the queue 'forever'.
Definition: scheduler.cpp:23
std::function< bool()> Predicate
Definition: scheduler.h:49
bool stopRequested GUARDED_BY(newTaskMutex)
Definition: scheduler.h:120
size_t getQueueInfo(std::chrono::steady_clock::time_point &first, std::chrono::steady_clock::time_point &last) const
Returns number of tasks waiting to be serviced, and first and last task times.
Definition: scheduler.cpp:120
void scheduleFromNow(Function f, std::chrono::milliseconds delta)
Call f once after the delta has passed.
Definition: scheduler.h:55
void schedule(Function f, std::chrono::steady_clock::time_point t)
Call func at/after time t.
Definition: scheduler.cpp:74
std::multimap< std::chrono::steady_clock::time_point, Function > taskQueue GUARDED_BY(newTaskMutex)
int nThreadsServicingQueue GUARDED_BY(newTaskMutex)
Definition: scheduler.h:119
void StopWhenDrained()
Tell any threads running serviceQueue to stop when there is no work left to be done.
Definition: scheduler.h:96
std::function< void()> Function
Definition: scheduler.h:48
void MockForward(std::chrono::seconds delta_seconds)
Mock the scheduler to fast forward in time.
Definition: scheduler.cpp:83
std::thread m_service_thread
Definition: scheduler.h:46
bool shouldStop() const EXCLUSIVE_LOCKS_REQUIRED(newTaskMutex)
Definition: scheduler.h:122
void stop()
Tell any threads running serviceQueue to stop as soon as the current task is done.
Definition: scheduler.h:84
void scheduleEvery(Predicate p, std::chrono::milliseconds delta)
Repeat p until it return false.
Definition: scheduler.cpp:114
bool AreThreadsServicingQueue() const
Returns true if there are threads actively running in serviceQueue()
Definition: scheduler.cpp:131
std::condition_variable newTaskScheduled
Definition: scheduler.h:116
Mutex newTaskMutex
Definition: scheduler.h:115
Class used by CScheduler clients which may schedule multiple jobs which are required to be run serial...
Definition: scheduler.h:137
void EmptyQueue()
Processes all remaining queue members on the calling thread, blocking until queue is empty.
Definition: scheduler.cpp:197
std::list< std::function< void()> > m_callbacks_pending GUARDED_BY(m_cs_callbacks_pending)
void AddToProcessQueue(std::function< void()> func)
Add a callback to be executed.
Definition: scheduler.cpp:188
bool m_are_callbacks_running GUARDED_BY(m_cs_callbacks_pending)
SingleThreadedSchedulerClient(CScheduler &scheduler LIFETIMEBOUND)
Definition: scheduler.h:150
RecursiveMutex m_cs_callbacks_pending
Definition: scheduler.h:141
#define WITH_LOCK(cs, code)
Run code while locking a mutex.
Definition: sync.h:276
#define EXCLUSIVE_LOCKS_REQUIRED(...)
Definition: threadsafety.h:56