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 sample () = 0;
40  virtual ~seconds_clock_worker() = default;
41  seconds_clock_worker() = default;
44 };
45 
46 //------------------------------------------------------------------------------
47 
48 // Updates the clocks
50 {
51 public:
52  using mutex = std::mutex;
59 
60  bool stop_;
65 
67  : stop_ (false)
68  {
70  }
71 
73  {
74  stop();
75  }
76 
78  {
79  std::lock_guard lock (mutex_);
80  workers_.push_back (&w);
81  }
82 
84  {
85  std::lock_guard lock (mutex_);
87  workers_.begin (), workers_.end(), &w));
88  }
89 
90  void stop()
91  {
92  if (thread_.joinable())
93  {
94  {
95  std::lock_guard lock (mutex_);
96  stop_ = true;
97  }
98  cond_.notify_all();
99  thread_.join();
100  }
101  }
102 
103  void run()
104  {
105  unique_lock lock (mutex_);;
106 
107  for (;;)
108  {
109  for (auto iter : workers_)
110  iter->sample();
111 
112  using namespace std::chrono;
113  clock_type::time_point const when (
114  date::floor <seconds> (
115  clock_type::now().time_since_epoch()) +
116  seconds (1));
117 
118  if (cond_.wait_until (lock, when, [this]{ return stop_; }))
119  return;
120  }
121  }
122 
124  {
125  static seconds_clock_thread singleton;
126  return singleton;
127  }
128 };
129 
130 }
131 
132 //------------------------------------------------------------------------------
133 
139 inline
140 void
142 {
143 #ifdef _MSC_VER
145 #endif
146 }
147 
157 template <class Clock>
159 {
160 public:
161  explicit basic_seconds_clock() = default;
162 
163  using rep = typename Clock::rep;
164  using period = typename Clock::period;
165  using duration = typename Clock::duration;
166  using time_point = typename Clock::time_point;
167 
168  static bool const is_steady = Clock::is_steady;
169 
170  static time_point now()
171  {
172  // Make sure the thread is constructed before the
173  // worker otherwise we will crash during destruction
174  // of objects with static storage duration.
175  struct initializer
176  {
177  initializer ()
178  {
180  }
181  };
182  static initializer init;
183 
184  struct worker : detail::seconds_clock_worker
185  {
186  time_point m_now;
187  std::mutex mutex_;
188 
189  worker()
190  : m_now(Clock::now())
191  {
193  }
194 
195  ~worker()
196  {
198  }
199 
200  time_point now()
201  {
202  std::lock_guard lock (mutex_);
203  return m_now;
204  }
205 
206  void sample() override
207  {
208  std::lock_guard lock (mutex_);
209  m_now = Clock::now();
210  }
211  };
212 
213  static worker w;
214 
215  return w.now();
216  }
217 };
218 
219 }
220 
221 #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:141
beast::detail::seconds_clock_thread::run
void run()
Definition: basic_seconds_clock.h:103
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:61
beast::detail::seconds_clock_thread::add
void add(seconds_clock_worker &w)
Definition: basic_seconds_clock.h:77
beast::detail::seconds_clock_thread::cond_
cond_var cond_
Definition: basic_seconds_clock.h:62
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:90
beast::detail::seconds_clock_thread::~seconds_clock_thread
~seconds_clock_thread()
Definition: basic_seconds_clock.h:72
beast::basic_seconds_clock::duration
typename Clock::duration duration
Definition: basic_seconds_clock.h:165
beast::basic_seconds_clock::now
static time_point now()
Definition: basic_seconds_clock.h:170
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:66
beast::detail::seconds_clock_thread::stop_
bool stop_
Definition: basic_seconds_clock.h:60
beast::detail::seconds_clock_thread::workers_
workers workers_
Definition: basic_seconds_clock.h:63
beast::basic_seconds_clock
A clock whose minimum resolution is one second.
Definition: basic_seconds_clock.h:158
thread
chrono
beast::detail::seconds_clock_thread::remove
void remove(seconds_clock_worker &w)
Definition: basic_seconds_clock.h:83
std::unique_lock< mutex >
beast::detail::seconds_clock_thread
Definition: basic_seconds_clock.h:49
std::vector::erase
T erase(T... args)
beast::basic_seconds_clock::period
typename Clock::period period
Definition: basic_seconds_clock.h:164
beast::detail::init
void init(ripemd160_context &ctx) noexcept
Definition: ripemd_context.h:343
beast::basic_seconds_clock::rep
typename Clock::rep rep
Definition: basic_seconds_clock.h:163
beast::detail::seconds_clock_thread::instance
static seconds_clock_thread & instance()
Definition: basic_seconds_clock.h:123
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:64
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:166
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:57
beast
Definition: base_uint.h:582
std::chrono
std::chrono::steady_clock::now
T now(T... args)