Bitcoin Core  0.20.99
P2P Digital Currency
scheduler.h
Go to the documentation of this file.
1 // Copyright (c) 2015-2020 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 <condition_variable>
9 #include <functional>
10 #include <list>
11 #include <map>
12 
13 #include <sync.h>
14 
33 {
34 public:
35  CScheduler();
36  ~CScheduler();
37 
38  typedef std::function<void()> Function;
39 
42 
44  void scheduleFromNow(Function f, std::chrono::milliseconds delta)
45  {
46  schedule(std::move(f), std::chrono::system_clock::now() + delta);
47  }
48 
55  void scheduleEvery(Function f, std::chrono::milliseconds delta);
56 
62  void MockForward(std::chrono::seconds delta_seconds);
63 
68  void serviceQueue();
69 
71  void stop()
72  {
73  WITH_LOCK(newTaskMutex, stopRequested = true);
74  newTaskScheduled.notify_all();
75  }
78  {
79  WITH_LOCK(newTaskMutex, stopWhenEmpty = true);
80  newTaskScheduled.notify_all();
81  }
82 
89 
91  bool AreThreadsServicingQueue() const;
92 
93 private:
95  std::condition_variable newTaskScheduled;
96  std::multimap<std::chrono::system_clock::time_point, Function> taskQueue GUARDED_BY(newTaskMutex);
97  int nThreadsServicingQueue GUARDED_BY(newTaskMutex){0};
98  bool stopRequested GUARDED_BY(newTaskMutex){false};
99  bool stopWhenEmpty GUARDED_BY(newTaskMutex){false};
100  bool shouldStop() const EXCLUSIVE_LOCKS_REQUIRED(newTaskMutex) { return stopRequested || (stopWhenEmpty && taskQueue.empty()); }
101 };
102 
114 {
115 private:
117 
119  std::list<std::function<void()>> m_callbacks_pending GUARDED_BY(m_cs_callbacks_pending);
120  bool m_are_callbacks_running GUARDED_BY(m_cs_callbacks_pending) = false;
121 
122  void MaybeScheduleProcessQueue();
123  void ProcessQueue();
124 
125 public:
126  explicit SingleThreadedSchedulerClient(CScheduler* pschedulerIn) : m_pscheduler(pschedulerIn) {}
127 
134  void AddToProcessQueue(std::function<void()> func);
135 
140  void EmptyQueue();
141 
142  size_t CallbacksPending();
143 };
144 
145 #endif
Class used by CScheduler clients which may schedule multiple jobs which are required to be run serial...
Definition: scheduler.h:113
void scheduleEvery(Function f, std::chrono::milliseconds delta)
Repeat f until the scheduler is stopped.
Definition: scheduler.cpp:108
void StopWhenDrained()
Tell any threads running serviceQueue to stop when there is no work left to be done.
Definition: scheduler.h:77
void MockForward(std::chrono::seconds delta_seconds)
Mock the scheduler to fast forward in time.
Definition: scheduler.cpp:80
std::function< void()> Function
Definition: scheduler.h:38
bool stopWhenEmpty GUARDED_BY(newTaskMutex)
Definition: scheduler.h:99
Mutex newTaskMutex
Definition: scheduler.h:94
bool stopRequested GUARDED_BY(newTaskMutex)
Definition: scheduler.h:98
void stop()
Tell any threads running serviceQueue to stop as soon as the current task is done.
Definition: scheduler.h:71
std::condition_variable newTaskScheduled
Definition: scheduler.h:95
int nThreadsServicingQueue GUARDED_BY(newTaskMutex)
Definition: scheduler.h:97
void schedule(Function f, std::chrono::system_clock::time_point t)
Call func at/after time t.
Definition: scheduler.cpp:71
RecursiveMutex m_cs_callbacks_pending
Definition: scheduler.h:118
SingleThreadedSchedulerClient(CScheduler *pschedulerIn)
Definition: scheduler.h:126
void serviceQueue()
Services the queue &#39;forever&#39;.
Definition: scheduler.cpp:23
#define WITH_LOCK(cs, code)
Run code while locking a mutex.
Definition: sync.h:253
#define EXCLUSIVE_LOCKS_REQUIRED(...)
Definition: threadsafety.h:53
bool AreThreadsServicingQueue() const
Returns true if there are threads actively running in serviceQueue()
Definition: scheduler.cpp:125
clock::time_point time_point
Definition: bench.h:48
std::multimap< std::chrono::system_clock::time_point, Function > taskQueue GUARDED_BY(newTaskMutex)
Simple class for background tasks that should be run periodically or once "after a while"...
Definition: scheduler.h:32
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.
Definition: scheduler.cpp:113
void scheduleFromNow(Function f, std::chrono::milliseconds delta)
Call f once after the delta has passed.
Definition: scheduler.h:44
bool shouldStop() const EXCLUSIVE_LOCKS_REQUIRED(newTaskMutex)
Definition: scheduler.h:100