Bitcoin ABC  0.28.12
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)
54 
56  void scheduleFromNow(Function f, std::chrono::milliseconds delta)
58  schedule(std::move(f), std::chrono::steady_clock::now() + delta);
59  }
60 
68  void scheduleEvery(Predicate p, std::chrono::milliseconds delta)
70 
76  void MockForward(std::chrono::seconds delta_seconds)
78 
83 
89  WITH_LOCK(newTaskMutex, stopRequested = true);
90  newTaskScheduled.notify_all();
91  if (m_service_thread.joinable()) {
92  m_service_thread.join();
93  }
94  }
95 
101  WITH_LOCK(newTaskMutex, stopWhenEmpty = true);
102  newTaskScheduled.notify_all();
103  if (m_service_thread.joinable()) {
104  m_service_thread.join();
105  }
106  }
107 
112  size_t getQueueInfo(std::chrono::steady_clock::time_point &first,
113  std::chrono::steady_clock::time_point &last) const
115 
117  bool AreThreadsServicingQueue() const
119 
120 private:
122  std::condition_variable newTaskScheduled;
123  std::multimap<std::chrono::steady_clock::time_point, Function>
125  int nThreadsServicingQueue GUARDED_BY(newTaskMutex){0};
126  bool stopRequested GUARDED_BY(newTaskMutex){false};
127  bool stopWhenEmpty GUARDED_BY(newTaskMutex){false};
129  return stopRequested || (stopWhenEmpty && taskQueue.empty());
130  }
131 };
132 
144 private:
146 
148  std::list<std::function<void()>>
149  m_callbacks_pending GUARDED_BY(m_callbacks_mutex);
150  bool m_are_callbacks_running GUARDED_BY(m_callbacks_mutex) = false;
151 
155 
156 public:
158  : m_scheduler{scheduler} {}
159 
166  void AddToProcessQueue(std::function<void()> func)
168 
175 
177 };
178 
179 #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
void MockForward(std::chrono::seconds delta_seconds) EXCLUSIVE_LOCKS_REQUIRED(!newTaskMutex)
Mock the scheduler to fast forward in time.
Definition: scheduler.cpp:83
bool stopWhenEmpty GUARDED_BY(newTaskMutex)
Definition: scheduler.h:127
void serviceQueue() EXCLUSIVE_LOCKS_REQUIRED(!newTaskMutex)
Services the queue 'forever'.
Definition: scheduler.cpp:23
std::function< bool()> Predicate
Definition: scheduler.h:49
bool stopRequested GUARDED_BY(newTaskMutex)
Definition: scheduler.h:126
void scheduleEvery(Predicate p, std::chrono::milliseconds delta) EXCLUSIVE_LOCKS_REQUIRED(!newTaskMutex)
Repeat p until it return false.
Definition: scheduler.cpp:114
std::multimap< std::chrono::steady_clock::time_point, Function > taskQueue GUARDED_BY(newTaskMutex)
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:120
std::function< void()> Function
Definition: scheduler.h:48
std::thread m_service_thread
Definition: scheduler.h:46
bool AreThreadsServicingQueue() const EXCLUSIVE_LOCKS_REQUIRED(!newTaskMutex)
Returns true if there are threads actively running in serviceQueue()
Definition: scheduler.cpp:131
bool shouldStop() const EXCLUSIVE_LOCKS_REQUIRED(newTaskMutex)
Definition: scheduler.h:128
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:100
std::condition_variable newTaskScheduled
Definition: scheduler.h:122
void stop() EXCLUSIVE_LOCKS_REQUIRED(!newTaskMutex)
Tell any threads running serviceQueue to stop as soon as the current task is done.
Definition: scheduler.h:88
Mutex newTaskMutex
Definition: scheduler.h:121
void scheduleFromNow(Function f, std::chrono::milliseconds delta) EXCLUSIVE_LOCKS_REQUIRED(!newTaskMutex)
Call f once after the delta has passed.
Definition: scheduler.h:56
void schedule(Function f, std::chrono::steady_clock::time_point t) EXCLUSIVE_LOCKS_REQUIRED(!newTaskMutex)
Call func at/after time t.
Definition: scheduler.cpp:74
Class used by CScheduler clients which may schedule multiple jobs which are required to be run serial...
Definition: scheduler.h:143
void AddToProcessQueue(std::function< void()> func) EXCLUSIVE_LOCKS_REQUIRED(!m_callbacks_mutex)
Add a callback to be executed.
Definition: scheduler.cpp:188
void ProcessQueue() EXCLUSIVE_LOCKS_REQUIRED(!m_callbacks_mutex)
Definition: scheduler.cpp:153
size_t CallbacksPending() EXCLUSIVE_LOCKS_REQUIRED(!m_callbacks_mutex)
Definition: scheduler.cpp:207
bool m_are_callbacks_running GUARDED_BY(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.
Definition: scheduler.cpp:197
void MaybeScheduleProcessQueue() EXCLUSIVE_LOCKS_REQUIRED(!m_callbacks_mutex)
Definition: scheduler.cpp:136
std::list< std::function< void()> > m_callbacks_pending GUARDED_BY(m_callbacks_mutex)
Implement std::hash so RCUPtr can be used as a key for maps or sets.
Definition: rcu.h:257
#define WITH_LOCK(cs, code)
Run code while locking a mutex.
Definition: sync.h:357
#define EXCLUSIVE_LOCKS_REQUIRED(...)
Definition: threadsafety.h:56