Bitcoin Core  24.99.0
P2P Digital Currency
scheduler.h
Go to the documentation of this file.
1 // Copyright (c) 2015-2022 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 
39 {
40 public:
42  ~CScheduler();
43 
44  std::thread m_service_thread;
45 
46  typedef std::function<void()> Function;
47 
49  void schedule(Function f, std::chrono::steady_clock::time_point t) EXCLUSIVE_LOCKS_REQUIRED(!newTaskMutex);
50 
52  void scheduleFromNow(Function f, std::chrono::milliseconds delta) EXCLUSIVE_LOCKS_REQUIRED(!newTaskMutex)
53  {
54  schedule(std::move(f), std::chrono::steady_clock::now() + delta);
55  }
56 
63  void scheduleEvery(Function f, std::chrono::milliseconds delta) EXCLUSIVE_LOCKS_REQUIRED(!newTaskMutex);
64 
70  void MockForward(std::chrono::seconds delta_seconds) EXCLUSIVE_LOCKS_REQUIRED(!newTaskMutex);
71 
76 
79  {
80  WITH_LOCK(newTaskMutex, stopRequested = true);
81  newTaskScheduled.notify_all();
82  if (m_service_thread.joinable()) m_service_thread.join();
83  }
86  {
87  WITH_LOCK(newTaskMutex, stopWhenEmpty = true);
88  newTaskScheduled.notify_all();
89  if (m_service_thread.joinable()) m_service_thread.join();
90  }
91 
96  size_t getQueueInfo(std::chrono::steady_clock::time_point& first,
97  std::chrono::steady_clock::time_point& last) const
99 
102 
103 private:
105  std::condition_variable newTaskScheduled;
106  std::multimap<std::chrono::steady_clock::time_point, Function> taskQueue GUARDED_BY(newTaskMutex);
107  int nThreadsServicingQueue GUARDED_BY(newTaskMutex){0};
108  bool stopRequested GUARDED_BY(newTaskMutex){false};
109  bool stopWhenEmpty GUARDED_BY(newTaskMutex){false};
110  bool shouldStop() const EXCLUSIVE_LOCKS_REQUIRED(newTaskMutex) { return stopRequested || (stopWhenEmpty && taskQueue.empty()); }
111 };
112 
124 {
125 private:
127 
129  std::list<std::function<void()>> m_callbacks_pending GUARDED_BY(m_callbacks_mutex);
130  bool m_are_callbacks_running GUARDED_BY(m_callbacks_mutex) = false;
131 
134 
135 public:
137 
144  void AddToProcessQueue(std::function<void()> func) EXCLUSIVE_LOCKS_REQUIRED(!m_callbacks_mutex);
145 
151 
153 };
154 
155 #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:39
void MockForward(std::chrono::seconds delta_seconds) EXCLUSIVE_LOCKS_REQUIRED(!newTaskMutex)
Mock the scheduler to fast forward in time.
Definition: scheduler.cpp:82
bool stopWhenEmpty GUARDED_BY(newTaskMutex)
Definition: scheduler.h:109
void serviceQueue() EXCLUSIVE_LOCKS_REQUIRED(!newTaskMutex)
Services the queue 'forever'.
Definition: scheduler.cpp:24
bool stopRequested GUARDED_BY(newTaskMutex)
Definition: scheduler.h:108
void scheduleEvery(Function f, std::chrono::milliseconds delta) EXCLUSIVE_LOCKS_REQUIRED(!newTaskMutex)
Repeat f until the scheduler is stopped.
Definition: scheduler.cpp:110
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:115
std::function< void()> Function
Definition: scheduler.h:46
std::thread m_service_thread
Definition: scheduler.h:44
bool AreThreadsServicingQueue() const EXCLUSIVE_LOCKS_REQUIRED(!newTaskMutex)
Returns true if there are threads actively running in serviceQueue()
Definition: scheduler.cpp:127
bool shouldStop() const EXCLUSIVE_LOCKS_REQUIRED(newTaskMutex)
Definition: scheduler.h:110
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:85
std::condition_variable newTaskScheduled
Definition: scheduler.h:105
void stop() EXCLUSIVE_LOCKS_REQUIRED(!newTaskMutex)
Tell any threads running serviceQueue to stop as soon as the current task is done.
Definition: scheduler.h:78
Mutex newTaskMutex
Definition: scheduler.h:104
void scheduleFromNow(Function f, std::chrono::milliseconds delta) EXCLUSIVE_LOCKS_REQUIRED(!newTaskMutex)
Call f once after the delta has passed.
Definition: scheduler.h:52
void schedule(Function f, std::chrono::steady_clock::time_point t) EXCLUSIVE_LOCKS_REQUIRED(!newTaskMutex)
Call func at/after time t.
Definition: scheduler.cpp:73
Class used by CScheduler clients which may schedule multiple jobs which are required to be run serial...
Definition: scheduler.h:124
void AddToProcessQueue(std::function< void()> func) EXCLUSIVE_LOCKS_REQUIRED(!m_callbacks_mutex)
Add a callback to be executed.
Definition: scheduler.cpp:178
void ProcessQueue() EXCLUSIVE_LOCKS_REQUIRED(!m_callbacks_mutex)
Definition: scheduler.cpp:147
size_t CallbacksPending() EXCLUSIVE_LOCKS_REQUIRED(!m_callbacks_mutex)
Definition: scheduler.cpp:198
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 Must be ca...
Definition: scheduler.cpp:187
void MaybeScheduleProcessQueue() EXCLUSIVE_LOCKS_REQUIRED(!m_callbacks_mutex)
Definition: scheduler.cpp:134
std::list< std::function< void()> > m_callbacks_pending GUARDED_BY(m_callbacks_mutex)
#define WITH_LOCK(cs, code)
Run code while locking a mutex.
Definition: sync.h:302
#define EXCLUSIVE_LOCKS_REQUIRED(...)
Definition: threadsafety.h:49