xrpld
Loading...
Searching...
No Matches
basic_seconds_clock.cpp
1#include <xrpl/beast/clock/basic_seconds_clock.h>
2
3#include <xrpl/beast/utility/instrumentation.h>
4
5#include <atomic>
6#include <chrono>
7#include <condition_variable>
8#include <mutex>
9#include <thread>
10
11namespace beast {
12
13namespace {
14
15// Updates the clock
16class SecondsClockThread
17{
18 using Clock = BasicSecondsClock::Clock;
19
20 bool stop_{false};
21 std::mutex mut_;
22 std::condition_variable cv_;
23 std::thread thread_;
24 std::atomic<Clock::time_point::rep> tp_;
25
26public:
27 ~SecondsClockThread();
28 SecondsClockThread();
29
30 Clock::time_point
31 now();
32
33private:
34 void
35 run();
36};
37
38static_assert(std::atomic<std::chrono::steady_clock::rep>::is_always_lock_free);
39
40SecondsClockThread::~SecondsClockThread()
41{
42 XRPL_ASSERT(
43 thread_.joinable(), "beast::SecondsClockThread::~SecondsClockThread : thread joinable");
44 {
45 std::scoped_lock const lock(mut_);
46 stop_ = true;
47 } // publish stop_ asap so if waiting thread times-out, it will see it
48 cv_.notify_one();
49 thread_.join();
50}
51
52SecondsClockThread::SecondsClockThread() : tp_{Clock::now().time_since_epoch().count()}
53{
54 thread_ = std::thread(&SecondsClockThread::run, this);
55}
56
57SecondsClockThread::Clock::time_point
58SecondsClockThread::now()
59{
60 return Clock::time_point{Clock::duration{tp_.load()}};
61}
62
63void
64SecondsClockThread::run()
65{
67 while (true)
68 {
69 using namespace std::chrono;
70
71 auto now = Clock::now();
72 tp_ = now.time_since_epoch().count();
73 auto const when = floor<seconds>(now) + 1s;
74 if (cv_.wait_until(lock, when, [this] { return stop_; }))
75 return;
76 }
77}
78
79} // unnamed namespace
80
81BasicSecondsClock::time_point
83{
84 static SecondsClockThread kClk;
85 return kClk.now();
86}
87
88} // namespace beast
std::chrono::steady_clock Clock
T count(T... args)
T floor(T... args)
T join(T... args)
T joinable(T... args)
T lock(T... args)
int run(int argc, char **argv)
Definition Main.cpp:354