rippled
ripple
beast
clock
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
36
class
seconds_clock_worker
37
{
38
public
:
39
virtual
void
40
sample
() = 0;
41
virtual
~seconds_clock_worker
() =
default
;
42
seconds_clock_worker
() =
default
;
43
seconds_clock_worker
(
seconds_clock_worker
const
&) =
delete
;
44
seconds_clock_worker
&
45
operator=
(
seconds_clock_worker
const
&) =
delete
;
46
};
47
48
//------------------------------------------------------------------------------
49
50
// Updates the clocks
51
class
seconds_clock_thread
52
{
53
public
:
54
using
mutex
=
std::mutex
;
55
using
cond_var
=
std::condition_variable
;
56
using
unique_lock
=
std::unique_lock<mutex>
;
57
using
clock_type
=
std::chrono::steady_clock
;
58
using
seconds
=
std::chrono::seconds
;
59
using
thread
=
std::thread
;
60
using
workers
=
std::vector<seconds_clock_worker*>
;
61
62
bool
stop_
;
63
mutex
mutex_
;
64
cond_var
cond_
;
65
workers
workers_
;
66
thread
thread_
;
67
68
seconds_clock_thread
() :
stop_
(false)
69
{
70
thread_
=
thread
(&
seconds_clock_thread::run
,
this
);
71
}
72
73
~seconds_clock_thread
()
74
{
75
stop
();
76
}
77
78
void
79
add
(
seconds_clock_worker
& w)
80
{
81
std::lock_guard
lock(
mutex_
);
82
workers_
.
push_back
(&w);
83
}
84
85
void
86
remove
(
seconds_clock_worker
& w)
87
{
88
std::lock_guard
lock(
mutex_
);
89
workers_
.
erase
(
std::find
(
workers_
.
begin
(),
workers_
.
end
(), &w));
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
&
128
instance
()
129
{
130
static
seconds_clock_thread
singleton;
131
return
singleton;
132
}
133
};
134
135
}
// namespace detail
136
146
template
<
class
Clock>
147
class
basic_seconds_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
{
169
detail::seconds_clock_thread::instance
();
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
{
181
detail::seconds_clock_thread::instance
().
add
(*
this
);
182
}
183
184
~worker()
185
{
186
detail::seconds_clock_thread::instance
().
remove
(*
this
);
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)
Generated by
1.8.17