DUNE-DAQ
DUNE Trigger and Data Acquisition software
Toggle main menu visibility
Loading...
Searching...
No Matches
dunedaq
sourcecode
iomanager
include
iomanager
queue
detail
StdDeQueue.hxx
Go to the documentation of this file.
1
2
#include "
ers/ers.hpp
"
3
4
namespace
dunedaq::iomanager
{
5
6
template
<
class
T>
7
StdDeQueue<T>::StdDeQueue
(
const
std::string& name,
size_t
capacity)
8
:
Queue
<T>(name)
9
,
m_deque
()
10
,
m_capacity
(capacity)
11
,
m_size
(0)
12
{
13
assert(
m_deque
.max_size() > this->get_capacity());
14
}
15
16
template
<
class
T>
17
void
18
StdDeQueue<T>::push
(
value_t
&& object_to_push,
const
duration_t
& timeout)
19
{
20
21
auto
start_time
= std::chrono::steady_clock::now();
22
std::unique_lock<std::mutex> lk(
m_mutex
, std::defer_lock);
23
24
this->
try_lock_for
(lk, timeout);
25
26
auto
time_to_wait_for_space = (
start_time
+ timeout) - std::chrono::steady_clock::now();
27
28
if
(time_to_wait_for_space.count() > 0) {
29
m_no_longer_full
.wait_for(lk, time_to_wait_for_space, [&]() {
return
this->
can_push
(); });
30
}
31
32
if
(this->
can_push
()) {
33
m_deque
.push_back(std::move(object_to_push));
34
m_size
++;
35
m_no_longer_empty
.notify_one();
36
}
else
{
37
throw
QueueTimeoutExpired(
38
ERS_HERE
, this->
get_name
(),
"push"
, std::chrono::duration_cast<std::chrono::milliseconds>(timeout).count());
39
}
40
}
41
42
template
<
class
T>
43
void
44
StdDeQueue<T>::pop
(T& val,
const
duration_t
& timeout)
45
{
46
47
auto
start_time
= std::chrono::steady_clock::now();
48
std::unique_lock<std::mutex> lk(
m_mutex
, std::defer_lock);
49
50
this->
try_lock_for
(lk, timeout);
51
52
auto
time_to_wait_for_data = (
start_time
+ timeout) - std::chrono::steady_clock::now();
53
54
if
(time_to_wait_for_data.count() > 0) {
55
m_no_longer_empty
.wait_for(lk, time_to_wait_for_data, [&]() {
return
this->
can_pop
(); });
56
}
57
58
if
(this->
can_pop
()) {
59
val = std::move(
m_deque
.front());
60
m_size
--;
61
m_deque
.pop_front();
62
m_no_longer_full
.notify_one();
63
}
else
{
64
throw
QueueTimeoutExpired(
65
ERS_HERE
, this->
get_name
(),
"pop"
, std::chrono::duration_cast<std::chrono::milliseconds>(timeout).count());
66
}
67
}
68
69
template
<
class
T>
70
bool
71
StdDeQueue<T>::try_push
(
value_t
&& object_to_push,
const
duration_t
& timeout)
72
{
73
74
auto
start_time
= std::chrono::steady_clock::now();
75
std::unique_lock<std::mutex> lk(
m_mutex
, std::defer_lock);
76
77
this->
try_lock_for
(lk, timeout);
78
79
auto
time_to_wait_for_space = (
start_time
+ timeout) - std::chrono::steady_clock::now();
80
81
if
(time_to_wait_for_space.count() > 0) {
82
m_no_longer_full
.wait_for(lk, time_to_wait_for_space, [&]() {
return
this->
can_push
(); });
83
}
84
85
if
(this->
can_push
()) {
86
m_deque
.push_back(std::move(object_to_push));
87
m_size
++;
88
m_no_longer_empty
.notify_one();
89
return
true
;
90
}
else
{
91
ers::error
(QueueTimeoutExpired(
92
ERS_HERE
, this->
get_name
(),
"push"
, std::chrono::duration_cast<std::chrono::milliseconds>(timeout).count()));
93
return
false
;
94
}
95
}
96
97
template
<
class
T>
98
bool
99
StdDeQueue<T>::try_pop
(T& val,
const
duration_t
& timeout)
100
{
101
102
auto
start_time
= std::chrono::steady_clock::now();
103
std::unique_lock<std::mutex> lk(
m_mutex
, std::defer_lock);
104
105
this->
try_lock_for
(lk, timeout);
106
107
auto
time_to_wait_for_data = (
start_time
+ timeout) - std::chrono::steady_clock::now();
108
109
if
(time_to_wait_for_data.count() > 0) {
110
m_no_longer_empty
.wait_for(lk, time_to_wait_for_data, [&]() {
return
this->
can_pop
(); });
111
}
112
113
if
(this->
can_pop
()) {
114
val = std::move(
m_deque
.front());
115
m_size
--;
116
m_deque
.pop_front();
117
m_no_longer_full
.notify_one();
118
return
true
;
119
}
else
{
120
ers::error
(QueueTimeoutExpired(
121
ERS_HERE
, this->
get_name
(),
"pop"
, std::chrono::duration_cast<std::chrono::milliseconds>(timeout).count()));
122
return
false
;
123
}
124
}
125
126
// This try_lock_for() function was written because while objects of
127
// type std::timed_mutex have their own try_lock_for functions, the
128
// std::condition_variable::wait_for functions used in this class's push
129
// and pop operations require an std::mutex
130
131
template
<
class
T>
132
void
133
StdDeQueue<T>::try_lock_for
(std::unique_lock<std::mutex>& lk,
const
duration_t
& timeout)
134
{
135
assert(!lk.owns_lock());
136
137
auto
start_time
= std::chrono::steady_clock::now();
138
auto
ret = lk.try_lock();
139
140
if
((!ret || !lk.owns_lock()) && timeout.count() > 0) {
141
142
int
approximate_number_of_retries = 5;
143
duration_t
pause_between_tries =
duration_t
(timeout.count() / approximate_number_of_retries);
144
145
while
(std::chrono::steady_clock::now() <
start_time
+ timeout) {
146
std::this_thread::sleep_for(pause_between_tries);
147
ret = lk.try_lock();
148
if
(ret && lk.owns_lock()) {
149
break
;
150
}
151
}
152
}
153
154
if
(!lk.owns_lock()) {
155
throw
QueueTimeoutExpired(
156
ERS_HERE
, this->
get_name
(),
"lock mutex"
, std::chrono::duration_cast<std::chrono::milliseconds>(timeout).count());
157
}
158
}
159
160
}
// namespace dunedaq::iomanager
ERS_HERE
#define ERS_HERE
Definition
LocalContext.hpp:141
dunedaq::iomanager::Queue::Queue
Queue(const std::string &name)
Queue Constructor.
Definition
Queue.hpp:46
dunedaq::iomanager::StdDeQueue::pop
void pop(value_t &val, const duration_t &) override
Pop the first value off of the queue.
Definition
StdDeQueue.hxx:44
dunedaq::iomanager::StdDeQueue::m_mutex
std::mutex m_mutex
Definition
StdDeQueue.hpp:76
dunedaq::iomanager::StdDeQueue::m_deque
std::deque< value_t > m_deque
Definition
StdDeQueue.hpp:72
dunedaq::iomanager::StdDeQueue::push
void push(value_t &&, const duration_t &) override
Push a value onto the Queue.
Definition
StdDeQueue.hxx:18
dunedaq::iomanager::StdDeQueue::try_lock_for
void try_lock_for(std::unique_lock< std::mutex > &, const duration_t &)
Definition
StdDeQueue.hxx:133
dunedaq::iomanager::StdDeQueue::m_size
std::atomic< size_t > m_size
Definition
StdDeQueue.hpp:74
dunedaq::iomanager::StdDeQueue::can_pop
bool can_pop() const noexcept override
Determine whether the Queue may be popped from.
Definition
StdDeQueue.hpp:49
dunedaq::iomanager::StdDeQueue::StdDeQueue
StdDeQueue(const std::string &name, size_t capacity)
StdDeQueue Constructor.
Definition
StdDeQueue.hxx:7
dunedaq::iomanager::StdDeQueue::can_push
bool can_push() const noexcept override
Determine whether the Queue may be pushed onto.
Definition
StdDeQueue.hpp:53
dunedaq::iomanager::StdDeQueue::try_pop
bool try_pop(value_t &val, const duration_t &) override
Definition
StdDeQueue.hxx:99
dunedaq::iomanager::StdDeQueue::duration_t
typename Queue< T >::duration_t duration_t
Type used for expressing timeouts.
Definition
StdDeQueue.hpp:41
dunedaq::iomanager::StdDeQueue::m_no_longer_full
std::condition_variable m_no_longer_full
Definition
StdDeQueue.hpp:77
dunedaq::iomanager::StdDeQueue::try_push
bool try_push(value_t &&, const duration_t &) override
Definition
StdDeQueue.hxx:71
dunedaq::iomanager::StdDeQueue::m_no_longer_empty
std::condition_variable m_no_longer_empty
Definition
StdDeQueue.hpp:78
dunedaq::iomanager::StdDeQueue::value_t
T value_t
Type of data stored in the StdDeQueue.
Definition
StdDeQueue.hpp:40
dunedaq::iomanager::StdDeQueue::m_capacity
size_t m_capacity
Definition
StdDeQueue.hpp:73
dunedaq::utilities::NamedObject::get_name
const std::string & get_name() const final
Get the name of this NamedObejct.
Definition
NamedObject.hpp:65
ers.hpp
dunedaq::iomanager
Definition
IOManager.hxx:19
dunedaq::start_time
Cannot add TPSet with start_time
Definition
TPBundleHandler.hpp:41
ers::error
void error(const Issue &issue)
Definition
ers.hpp:92
Generated on
for DUNE-DAQ by
1.17.0