Skip to content

Commit ce87d56

Browse files
author
MarcoFalke
committed
Merge #18289: refactor: Make scheduler methods type safe
fa36f3a refactor: move DUMP_BANS_INTERVAL to banman.h (MarcoFalke) fadafb8 scheduler: Make schedule* methods type safe (MarcoFalke) fa70ccc scheduler: Use C++11 member initialization, add shutdown assert (MarcoFalke) Pull request description: Main benefit is that stuff like `15 * 60 * 1000` is replaced by `minutes{15}` ACKs for top commit: vasild: ACK fa36f3a (code review, not tested) ajtowns: ACK fa36f3a jonatack: ACK fa36f3a Tree-SHA512: f35f1a1d643dfa676bd47474659f6492ed05cca04cdb556064b126f654a6a44a4b93fcaddcdcd41faf81b8f11439c11e5c7ab88685ba2eef12f7188843d17ad8
2 parents 39497d1 + fa36f3a commit ce87d56

File tree

8 files changed

+43
-44
lines changed

8 files changed

+43
-44
lines changed

src/banman.h

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,19 @@
55
#ifndef BITCOIN_BANMAN_H
66
#define BITCOIN_BANMAN_H
77

8-
#include <cstdint>
9-
#include <memory>
10-
118
#include <addrdb.h>
129
#include <fs.h>
1310
#include <net_types.h> // For banmap_t
1411
#include <sync.h>
1512

13+
#include <chrono>
14+
#include <cstdint>
15+
#include <memory>
16+
1617
// NOTE: When adjusting this, update rpcnet:setban's help ("24h")
1718
static constexpr unsigned int DEFAULT_MISBEHAVING_BANTIME = 60 * 60 * 24; // Default 24-hour ban
19+
// How often to dump addresses to banlist.dat
20+
static constexpr std::chrono::minutes DUMP_BANS_INTERVAL{15};
1821

1922
class CClientUIInterface;
2023
class CNetAddr;

src/init.cpp

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -86,10 +86,6 @@ static const bool DEFAULT_PROXYRANDOMIZE = true;
8686
static const bool DEFAULT_REST_ENABLE = false;
8787
static const bool DEFAULT_STOPAFTERBLOCKIMPORT = false;
8888

89-
// Dump addresses to banlist.dat every 15 minutes (900s)
90-
static constexpr int DUMP_BANS_INTERVAL = 60 * 15;
91-
92-
9389
#ifdef WIN32
9490
// Win32 LevelDB doesn't use filedescriptors, and the ones used for
9591
// accessing block files don't count towards the fd_set size limit
@@ -1278,7 +1274,7 @@ bool AppInitMain(NodeContext& node)
12781274
// Gather some entropy once per minute.
12791275
node.scheduler->scheduleEvery([]{
12801276
RandAddPeriodic();
1281-
}, 60000);
1277+
}, std::chrono::minutes{1});
12821278

12831279
GetMainSignals().RegisterBackgroundSignalScheduler(*node.scheduler);
12841280

@@ -1862,7 +1858,7 @@ bool AppInitMain(NodeContext& node)
18621858
BanMan* banman = node.banman.get();
18631859
node.scheduler->scheduleEvery([banman]{
18641860
banman->DumpBanlist();
1865-
}, DUMP_BANS_INTERVAL * 1000);
1861+
}, DUMP_BANS_INTERVAL);
18661862

18671863
return true;
18681864
}

src/net.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,8 @@ static_assert(MINIUPNPC_API_VERSION >= 10, "miniUPnPc API version >= 10 assumed"
4545

4646
#include <math.h>
4747

48-
// Dump addresses to peers.dat every 15 minutes (900s)
49-
static constexpr int DUMP_PEERS_INTERVAL = 15 * 60;
48+
// How often to dump addresses to peers.dat
49+
static constexpr std::chrono::minutes DUMP_PEERS_INTERVAL{15};
5050

5151
/** Number of DNS seeds to query when the number of connections is low. */
5252
static constexpr int DNSSEEDS_TO_QUERY_AT_ONCE = 3;
@@ -2343,7 +2343,7 @@ bool CConnman::Start(CScheduler& scheduler, const Options& connOptions)
23432343
threadMessageHandler = std::thread(&TraceThread<std::function<void()> >, "msghand", std::function<void()>(std::bind(&CConnman::ThreadMessageHandler, this)));
23442344

23452345
// Dump network addresses
2346-
scheduler.scheduleEvery(std::bind(&CConnman::DumpAddresses, this), DUMP_PEERS_INTERVAL * 1000);
2346+
scheduler.scheduleEvery([this] { DumpAddresses(); }, DUMP_PEERS_INTERVAL);
23472347

23482348
return true;
23492349
}

src/net_processing.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1127,7 +1127,7 @@ PeerLogicValidation::PeerLogicValidation(CConnman* connmanIn, BanMan* banman, CS
11271127
// combine them in one function and schedule at the quicker (peer-eviction)
11281128
// timer.
11291129
static_assert(EXTRA_PEER_CHECK_INTERVAL < STALE_CHECK_INTERVAL, "peer eviction timer should be less than stale tip check timer");
1130-
scheduler.scheduleEvery(std::bind(&PeerLogicValidation::CheckForStaleTipAndEvictPeers, this, consensusParams), EXTRA_PEER_CHECK_INTERVAL * 1000);
1130+
scheduler.scheduleEvery([&] { this->CheckForStaleTipAndEvictPeers(consensusParams); }, std::chrono::seconds{EXTRA_PEER_CHECK_INTERVAL});
11311131
}
11321132

11331133
/**

src/scheduler.cpp

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,14 @@
99
#include <assert.h>
1010
#include <utility>
1111

12-
CScheduler::CScheduler() : nThreadsServicingQueue(0), stopRequested(false), stopWhenEmpty(false)
12+
CScheduler::CScheduler()
1313
{
1414
}
1515

1616
CScheduler::~CScheduler()
1717
{
1818
assert(nThreadsServicingQueue == 0);
19+
if (stopWhenEmpty) assert(taskQueue.empty());
1920
}
2021

2122

@@ -91,11 +92,6 @@ void CScheduler::schedule(CScheduler::Function f, std::chrono::system_clock::tim
9192
newTaskScheduled.notify_one();
9293
}
9394

94-
void CScheduler::scheduleFromNow(CScheduler::Function f, int64_t deltaMilliSeconds)
95-
{
96-
schedule(f, std::chrono::system_clock::now() + std::chrono::milliseconds(deltaMilliSeconds));
97-
}
98-
9995
void CScheduler::MockForward(std::chrono::seconds delta_seconds)
10096
{
10197
assert(delta_seconds.count() > 0 && delta_seconds < std::chrono::hours{1});
@@ -118,15 +114,15 @@ void CScheduler::MockForward(std::chrono::seconds delta_seconds)
118114
newTaskScheduled.notify_one();
119115
}
120116

121-
static void Repeat(CScheduler* s, CScheduler::Function f, int64_t deltaMilliSeconds)
117+
static void Repeat(CScheduler& s, CScheduler::Function f, std::chrono::milliseconds delta)
122118
{
123119
f();
124-
s->scheduleFromNow(std::bind(&Repeat, s, f, deltaMilliSeconds), deltaMilliSeconds);
120+
s.scheduleFromNow([=, &s] { Repeat(s, f, delta); }, delta);
125121
}
126122

127-
void CScheduler::scheduleEvery(CScheduler::Function f, int64_t deltaMilliSeconds)
123+
void CScheduler::scheduleEvery(CScheduler::Function f, std::chrono::milliseconds delta)
128124
{
129-
scheduleFromNow(std::bind(&Repeat, this, f, deltaMilliSeconds), deltaMilliSeconds);
125+
scheduleFromNow([=] { Repeat(*this, f, delta); }, delta);
130126
}
131127

132128
size_t CScheduler::getQueueInfo(std::chrono::system_clock::time_point &first,

src/scheduler.h

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@
2424
// Usage:
2525
//
2626
// CScheduler* s = new CScheduler();
27-
// s->scheduleFromNow(doSomething, 11); // Assuming a: void doSomething() { }
28-
// s->scheduleFromNow(std::bind(Class::func, this, argument), 3);
27+
// s->scheduleFromNow(doSomething, std::chrono::milliseconds{11}); // Assuming a: void doSomething() { }
28+
// s->scheduleFromNow([=] { this->func(argument); }, std::chrono::milliseconds{3});
2929
// boost::thread* t = new boost::thread(std::bind(CScheduler::serviceQueue, s));
3030
//
3131
// ... then at program shutdown, make sure to call stop() to clean up the thread(s) running serviceQueue:
@@ -46,15 +46,19 @@ class CScheduler
4646
// Call func at/after time t
4747
void schedule(Function f, std::chrono::system_clock::time_point t);
4848

49-
// Convenience method: call f once deltaMilliSeconds from now
50-
void scheduleFromNow(Function f, int64_t deltaMilliSeconds);
49+
/** Call f once after the delta has passed */
50+
void scheduleFromNow(Function f, std::chrono::milliseconds delta)
51+
{
52+
schedule(std::move(f), std::chrono::system_clock::now() + delta);
53+
}
5154

52-
// Another convenience method: call f approximately
53-
// every deltaMilliSeconds forever, starting deltaMilliSeconds from now.
54-
// To be more precise: every time f is finished, it
55-
// is rescheduled to run deltaMilliSeconds later. If you
56-
// need more accurate scheduling, don't use this method.
57-
void scheduleEvery(Function f, int64_t deltaMilliSeconds);
55+
/**
56+
* Repeat f until the scheduler is stopped. First run is after delta has passed once.
57+
*
58+
* The timing is not exact: Every time f is finished, it is rescheduled to run again after delta. If you need more
59+
* accurate scheduling, don't use this method.
60+
*/
61+
void scheduleEvery(Function f, std::chrono::milliseconds delta);
5862

5963
/**
6064
* Mock the scheduler to fast forward in time.
@@ -86,9 +90,9 @@ class CScheduler
8690
mutable Mutex newTaskMutex;
8791
std::condition_variable newTaskScheduled;
8892
std::multimap<std::chrono::system_clock::time_point, Function> taskQueue GUARDED_BY(newTaskMutex);
89-
int nThreadsServicingQueue GUARDED_BY(newTaskMutex);
90-
bool stopRequested GUARDED_BY(newTaskMutex);
91-
bool stopWhenEmpty GUARDED_BY(newTaskMutex);
93+
int nThreadsServicingQueue GUARDED_BY(newTaskMutex){0};
94+
bool stopRequested GUARDED_BY(newTaskMutex){false};
95+
bool stopWhenEmpty GUARDED_BY(newTaskMutex){false};
9296
bool shouldStop() const EXCLUSIVE_LOCKS_REQUIRED(newTaskMutex) { return stopRequested || (stopWhenEmpty && taskQueue.empty()); }
9397
};
9498

src/test/scheduler_tests.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -168,10 +168,10 @@ BOOST_AUTO_TEST_CASE(mockforward)
168168
CScheduler::Function dummy = [&counter]{counter++;};
169169

170170
// schedule jobs for 2, 5 & 8 minutes into the future
171-
int64_t min_in_milli = 60*1000;
172-
scheduler.scheduleFromNow(dummy, 2*min_in_milli);
173-
scheduler.scheduleFromNow(dummy, 5*min_in_milli);
174-
scheduler.scheduleFromNow(dummy, 8*min_in_milli);
171+
172+
scheduler.scheduleFromNow(dummy, std::chrono::minutes{2});
173+
scheduler.scheduleFromNow(dummy, std::chrono::minutes{5});
174+
scheduler.scheduleFromNow(dummy, std::chrono::minutes{8});
175175

176176
// check taskQueue
177177
std::chrono::system_clock::time_point first, last;
@@ -181,10 +181,10 @@ BOOST_AUTO_TEST_CASE(mockforward)
181181
std::thread scheduler_thread([&]() { scheduler.serviceQueue(); });
182182

183183
// bump the scheduler forward 5 minutes
184-
scheduler.MockForward(std::chrono::seconds(5*60));
184+
scheduler.MockForward(std::chrono::minutes{5});
185185

186186
// ensure scheduler has chance to process all tasks queued for before 1 ms from now.
187-
scheduler.scheduleFromNow([&scheduler]{ scheduler.stop(false); }, 1);
187+
scheduler.scheduleFromNow([&scheduler] { scheduler.stop(false); }, std::chrono::milliseconds{1});
188188
scheduler_thread.join();
189189

190190
// check that the queue only has one job remaining

src/wallet/load.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,8 +88,8 @@ void StartWallets(CScheduler& scheduler)
8888
}
8989

9090
// Schedule periodic wallet flushes and tx rebroadcasts
91-
scheduler.scheduleEvery(MaybeCompactWalletDB, 500);
92-
scheduler.scheduleEvery(MaybeResendWalletTxs, 1000);
91+
scheduler.scheduleEvery(MaybeCompactWalletDB, std::chrono::milliseconds{500});
92+
scheduler.scheduleEvery(MaybeResendWalletTxs, std::chrono::milliseconds{1000});
9393
}
9494

9595
void FlushWallets()

0 commit comments

Comments
 (0)