Bitcoin Core 31.99.0
P2P Digital Currency
scheduler.h
Go to the documentation of this file.
1// Copyright (c) 2015-present 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 <util/task_runner.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{
40public:
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
103private:
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{
125private:
127
129
130 // We are not allowed to assume the scheduler only runs in one thread,
131 // but must ensure all callbacks happen in-order, so we end up creating
132 // our own queue here :(
133 std::list<std::function<void()>> m_callbacks_pending GUARDED_BY(m_callbacks_mutex);
134 bool m_are_callbacks_running GUARDED_BY(m_callbacks_mutex) = false;
135
138
139public:
140 explicit SerialTaskRunner(CScheduler& scheduler LIFETIMEBOUND) : m_scheduler{scheduler} {}
141
148 void insert(std::function<void()> func) override EXCLUSIVE_LOCKS_REQUIRED(!m_callbacks_mutex);
149
155
157};
158
159#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:80
bool stopWhenEmpty GUARDED_BY(newTaskMutex)
Definition: scheduler.h:109
void serviceQueue() EXCLUSIVE_LOCKS_REQUIRED(!newTaskMutex)
Services the queue 'forever'.
Definition: scheduler.cpp:23
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:108
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:113
std::function< void()> Function
Definition: scheduler.h:46
std::thread m_service_thread
Definition: scheduler.h:44
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:125
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:71
Class used by CScheduler clients which may schedule multiple jobs which are required to be run serial...
Definition: scheduler.h:124
bool m_are_callbacks_running GUARDED_BY(m_callbacks_mutex)
void MaybeScheduleProcessQueue() EXCLUSIVE_LOCKS_REQUIRED(!m_callbacks_mutex)
Definition: scheduler.cpp:132
void ProcessQueue() EXCLUSIVE_LOCKS_REQUIRED(!m_callbacks_mutex)
Definition: scheduler.cpp:145
size_t size() override EXCLUSIVE_LOCKS_REQUIRED(!m_callbacks_mutex)
Returns the number of currently pending events.
Definition: scheduler.cpp:196
void insert(std::function< void()> func) override EXCLUSIVE_LOCKS_REQUIRED(!m_callbacks_mutex)
Add a callback to be executed.
Definition: scheduler.cpp:176
std::list< std::function< void()> > m_callbacks_pending GUARDED_BY(m_callbacks_mutex)
Mutex m_callbacks_mutex
Definition: scheduler.h:128
CScheduler & m_scheduler
Definition: scheduler.h:126
void flush() override 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:185
Definition: common.h:29
#define WITH_LOCK(cs, code)
Run code while locking a mutex.
Definition: sync.h:299
This header provides an interface and simple implementation for a task runner.
#define EXCLUSIVE_LOCKS_REQUIRED(...)
Definition: threadsafety.h:49