rippled
basic_seconds_clock.h
1 //------------------------------------------------------------------------------
2 /*
3  This file is part of Beast: https://github.com/vinniefalco/Beast
4  Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
5 
6  Permission to use, copy, modify, and/or distribute this software for any
7  purpose with or without fee is hereby granted, provided that the above
8  copyright notice and this permission notice appear in all copies.
9 
10  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18 //==============================================================================
19 
20 #ifndef BEAST_CHRONO_BASIC_SECONDS_CLOCK_H_INCLUDED
21 #define BEAST_CHRONO_BASIC_SECONDS_CLOCK_H_INCLUDED
22 
23 #include <date/date.h>
24 
25 #include <algorithm>
26 #include <chrono>
27 #include <condition_variable>
28 #include <mutex>
29 #include <thread>
30 #include <vector>
31 
32 namespace beast {
33 
34 namespace detail {
35 
37 {
38 public:
39  virtual void
40  sample() = 0;
41  virtual ~seconds_clock_worker() = default;
42  seconds_clock_worker() = default;
45  operator=(seconds_clock_worker const&) = delete;
46 };
47 
48 //------------------------------------------------------------------------------
49 
50 // Updates the clocks
52 {
53 public:
54  using mutex = std::mutex;
61 
62  bool stop_;
67 
69  {
71  }
72 
74  {
75  stop();
76  }
77 
78  void
80  {
81  std::lock_guard lock(mutex_);
82  workers_.push_back(&w);
83  }
84 
85  void
87  {
88  std::lock_guard lock(mutex_);
90  }
91 
92  void
93  stop()
94  {
95  if (thread_.joinable())
96  {
97  {
98  std::lock_guard lock(mutex_);
99  stop_ = true;
100  }
101  cond_.notify_all();
102  thread_.join();
103  }
104  }
105 
106  void
107  run()
108  {
109  unique_lock lock(mutex_);
110  ;
111 
112  for (;;)
113  {
114  for (auto iter : workers_)
115  iter->sample();
116 
117  using namespace std::chrono;
118  clock_type::time_point const when(
119  date::floor<seconds>(clock_type::now().time_since_epoch()) +
120  seconds(1));
121 
122  if (cond_.wait_until(lock, when, [this] { return stop_; }))
123  return;
124  }
125  }
126 
127  static seconds_clock_thread&
129  {
130  static seconds_clock_thread singleton;
131  return singleton;
132  }
133 };
134 
135 } // namespace detail
136 
137 //------------------------------------------------------------------------------
138 
144 inline void
146 {
147 #ifdef _MSC_VER
149 #endif
150 }
151 
161 template <class Clock>
163 {
164 public:
165  explicit basic_seconds_clock() = default;
166 
167  using rep = typename Clock::rep;
168  using period = typename Clock::period;
169  using duration = typename Clock::duration;
170  using time_point = typename Clock::time_point;
171 
172  static bool const is_steady = Clock::is_steady;
173 
174  static time_point
175  now()
176  {
177  // Make sure the thread is constructed before the
178  // worker otherwise we will crash during destruction
179  // of objects with static storage duration.
180  struct initializer
181  {
182  initializer()
183  {
185  }
186  };
187  static initializer init;
188 
189  struct worker : detail::seconds_clock_worker
190  {
191  time_point m_now;
192  std::mutex mutex_;
193 
194  worker() : m_now(Clock::now())
195  {
197  }
198 
199  ~worker()
200  {
202  }
203 
204  time_point
205  now()
206  {
207  std::lock_guard lock(mutex_);
208  return m_now;
209  }
210 
211  void
212  sample() override
213  {
214  std::lock_guard lock(mutex_);
215  m_now = Clock::now();
216  }
217  };
218 
219  static worker w;
220 
221  return w.now();
222  }
223 };
224 
225 } // namespace beast
226 
227 #endif
beast::basic_seconds_clock_main_hook
void basic_seconds_clock_main_hook()
Called before main exits to terminate the utility thread.
Definition: basic_seconds_clock.h:145
beast::detail::seconds_clock_thread::run
void run()
Definition: basic_seconds_clock.h:107
beast::detail::seconds_clock_worker
Definition: basic_seconds_clock.h:36
std::chrono::steady_clock
beast::detail::seconds_clock_thread::mutex_
mutex mutex_
Definition: basic_seconds_clock.h:63
beast::detail::seconds_clock_thread::add
void add(seconds_clock_worker &w)
Definition: basic_seconds_clock.h:79
beast::detail::seconds_clock_thread::cond_
cond_var cond_
Definition: basic_seconds_clock.h:64
vector
std::find
T find(T... args)
std::chrono::seconds
beast::detail::seconds_clock_worker::operator=
seconds_clock_worker & operator=(seconds_clock_worker const &)=delete
std::lock_guard
STL class.
beast::detail::seconds_clock_thread::stop
void stop()
Definition: basic_seconds_clock.h:93
beast::detail::seconds_clock_thread::~seconds_clock_thread
~seconds_clock_thread()
Definition: basic_seconds_clock.h:73
beast::basic_seconds_clock::duration
typename Clock::duration duration
Definition: basic_seconds_clock.h:169
beast::basic_seconds_clock::now
static time_point now()
Definition: basic_seconds_clock.h:175
algorithm
std::vector::push_back
T push_back(T... args)
std::thread::joinable
T joinable(T... args)
beast::detail::seconds_clock_thread::seconds_clock_thread
seconds_clock_thread()
Definition: basic_seconds_clock.h:68
beast::detail::seconds_clock_thread::stop_
bool stop_
Definition: basic_seconds_clock.h:62
beast::detail::seconds_clock_thread::workers_
workers workers_
Definition: basic_seconds_clock.h:65
beast::basic_seconds_clock
A clock whose minimum resolution is one second.
Definition: basic_seconds_clock.h:162
thread
chrono
beast::detail::seconds_clock_thread::remove
void remove(seconds_clock_worker &w)
Definition: basic_seconds_clock.h:86
std::unique_lock< mutex >
beast::detail::seconds_clock_thread
Definition: basic_seconds_clock.h:51
beast::detail::seconds_clock_thread::seconds
std::chrono::seconds seconds
Definition: basic_seconds_clock.h:58
std::vector::erase
T erase(T... args)
beast::basic_seconds_clock::period
typename Clock::period period
Definition: basic_seconds_clock.h:168
beast::detail::init
void init(ripemd160_context &ctx) noexcept
Definition: ripemd_context.h:364
beast::basic_seconds_clock::rep
typename Clock::rep rep
Definition: basic_seconds_clock.h:167
beast::detail::seconds_clock_thread::instance
static seconds_clock_thread & instance()
Definition: basic_seconds_clock.h:128
std::condition_variable::wait_until
T wait_until(T... args)
std::vector::begin
T begin(T... args)
condition_variable
mutex
std::vector::end
T end(T... args)
beast::detail::seconds_clock_thread::thread_
thread thread_
Definition: basic_seconds_clock.h:66
beast::detail::seconds_clock_worker::seconds_clock_worker
seconds_clock_worker()=default
beast::detail::seconds_clock_worker::~seconds_clock_worker
virtual ~seconds_clock_worker()=default
std::condition_variable::notify_all
T notify_all(T... args)
beast::basic_seconds_clock::time_point
typename Clock::time_point time_point
Definition: basic_seconds_clock.h:170
beast::detail::seconds_clock_worker::sample
virtual void sample()=0
std::thread::join
T join(T... args)
beast::detail::seconds_clock_thread::thread
std::thread thread
Definition: basic_seconds_clock.h:59
beast
Definition: base_uint.h:646
std::chrono
std::chrono::steady_clock::now
T now(T... args)