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 
146 template <class Clock>
148 {
149 public:
150  explicit basic_seconds_clock() = default;
151 
152  using rep = typename Clock::rep;
153  using period = typename Clock::period;
154  using duration = typename Clock::duration;
155  using time_point = typename Clock::time_point;
156 
157  static bool const is_steady = Clock::is_steady;
158 
159  static time_point
160  now()
161  {
162  // Make sure the thread is constructed before the
163  // worker otherwise we will crash during destruction
164  // of objects with static storage duration.
165  struct initializer
166  {
167  initializer()
168  {
170  }
171  };
172  static initializer init;
173 
174  struct worker : detail::seconds_clock_worker
175  {
176  time_point m_now;
177  std::mutex mutex_;
178 
179  worker() : m_now(Clock::now())
180  {
182  }
183 
184  ~worker()
185  {
187  }
188 
189  time_point
190  now()
191  {
192  std::lock_guard lock(mutex_);
193  return m_now;
194  }
195 
196  void
197  sample() override
198  {
199  std::lock_guard lock(mutex_);
200  m_now = Clock::now();
201  }
202  };
203 
204  static worker w;
205 
206  return w.now();
207  }
208 };
209 
210 } // namespace beast
211 
212 #endif
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:154
beast::basic_seconds_clock::now
static time_point now()
Definition: basic_seconds_clock.h:160
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:147
thread
chrono
beast::detail::seconds_clock_thread::remove
void remove(seconds_clock_worker &w)
Definition: basic_seconds_clock.h:86
std::unique_lock
STL class.
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:153
beast::basic_seconds_clock::rep
typename Clock::rep rep
Definition: basic_seconds_clock.h:152
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:155
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:585
std::chrono
std::chrono::steady_clock::now
T now(T... args)