DUNE-DAQ
DUNE Trigger and Data Acquisition software
Loading...
Searching...
No Matches
FollyQueue.hpp
Go to the documentation of this file.
1#ifndef IOMANAGER_INCLUDE_IOMANAGER_QUEUE_FOLLYQUEUE_HPP_
2#define IOMANAGER_INCLUDE_IOMANAGER_QUEUE_FOLLYQUEUE_HPP_
3
17
19
20#include "folly/concurrency/DynamicBoundedQueue.h"
21#include "logging/Logging.hpp"
22
23#include <string>
24#include <utility> // For std::move
25
26namespace dunedaq::iomanager {
27
28template<class T, template<typename, bool> class FollyQueueType>
29class FollyQueue : public Queue<T>
30{
31public:
32 using value_t = T;
34
35 explicit FollyQueue(const std::string& name, size_t capacity)
36 : Queue<T>(name)
37 , m_queue(capacity)
38 , m_capacity(capacity)
39 {
40 }
41
42 size_t get_capacity() const noexcept override { return m_capacity; }
43
44 size_t get_num_elements() const noexcept override { return m_queue.size(); }
45
46 bool can_pop() const noexcept override { return !m_queue.empty(); }
47
48 void pop(value_t& val, const duration_t& dur) override
49 {
50 if (dur == std::chrono::milliseconds::max()) {
51 // try_dequeue_for adds the dur to now(), which overflows and causes 0 duration
52 // Use base dequeue which blocks indefinitely until it can pop
53 m_queue.dequeue(val);
54 return;
55 }
56 if (!m_queue.try_dequeue_for(val, dur)) {
57 throw QueueTimeoutExpired(
58 ERS_HERE, this->get_name(), "pop", std::chrono::duration_cast<std::chrono::milliseconds>(dur).count());
59 }
60 }
61 bool try_pop(value_t& val, const duration_t& dur) override
62 {
63 if (dur == std::chrono::milliseconds::max()) {
64 // try_dequeue_for adds the dur to now(), which overflows and causes 0 duration
65 // Use base dequeue which blocks indefinitely until it can pop
66 m_queue.dequeue(val);
67 return true;
68 }
69 if (!m_queue.try_dequeue_for(val, dur)) {
70 return false;
71 }
72 return true;
73 }
74
75 bool can_push() const noexcept override { return m_queue.size() < this->get_capacity(); }
76
77 void push(value_t&& t, const duration_t& dur) override
78 {
79 if (dur == std::chrono::milliseconds::max()) {
80 // try_enqueue_for adds the dur to now(), which overflows and causes 0 duration
81 // Use base enqueue which blocks indefinitely until it can push
82 m_queue.enqueue(std::move(t));
83 return;
84 }
85 if (!m_queue.try_enqueue_for(std::move(t), dur)) {
86 throw QueueTimeoutExpired(
87 ERS_HERE, this->get_name(), "push", std::chrono::duration_cast<std::chrono::milliseconds>(dur).count());
88 }
89 }
90 bool try_push(value_t&& t, const duration_t& dur) override
91 {
92 if (dur == std::chrono::milliseconds::max()) {
93 // try_enqueue_for adds the dur to now(), which overflows and causes 0 duration
94 // Use base enqueue which blocks indefinitely until it can push
95 m_queue.enqueue(std::move(t));
96 return true;
97 }
98 if (!m_queue.try_enqueue_for(std::move(t), dur)) {
99 ers::error(QueueTimeoutExpired(
100 ERS_HERE, this->get_name(), "push", std::chrono::duration_cast<std::chrono::milliseconds>(dur).count()));
101 return false;
102 }
103 return true;
104 }
105
106 // Delete the copy and move operations
107 FollyQueue(const FollyQueue&) = delete;
108 FollyQueue& operator=(const FollyQueue&) = delete;
111
112private:
113 // The boolean argument is `MayBlock`, where "block" appears to mean
114 // "make a system call". With `MayBlock` set to false, the queue
115 // just spin-waits, so we want true
116 FollyQueueType<T, true> m_queue;
118};
119
120template<typename T>
122
123template<typename T>
125
126} // namespace dunedaq::iomanager
127
128#endif // IOMANAGER_INCLUDE_IOMANAGER_QUEUE_FOLLYQUEUE_HPP_
#define ERS_HERE
void pop(value_t &val, const duration_t &dur) override
Pop the first value off of the queue.
bool try_pop(value_t &val, const duration_t &dur) override
typename Queue< T >::duration_t duration_t
bool can_pop() const noexcept override
Determine whether the Queue may be popped from.
FollyQueue(const FollyQueue &)=delete
bool can_push() const noexcept override
Determine whether the Queue may be pushed onto.
bool try_push(value_t &&t, const duration_t &dur) override
size_t get_num_elements() const noexcept override
void push(value_t &&t, const duration_t &dur) override
Push a value onto the Queue.
FollyQueue & operator=(FollyQueue &&)=delete
FollyQueue(const std::string &name, size_t capacity)
FollyQueue(FollyQueue &&)=delete
FollyQueue & operator=(const FollyQueue &)=delete
size_t get_capacity() const noexcept override
Get the capacity (max size) of the queue.
std::chrono::milliseconds duration_t
Base duration type for timeouts.
Definition Queue.hpp:40
Queue(const std::string &name)
Queue Constructor.
Definition Queue.hpp:46
const std::string & get_name() const final
Get the name of this NamedObejct.
FollyQueue< T, folly::DMPMCQueue > FollyMPMCQueue
FollyQueue< T, folly::DSPSCQueue > FollySPSCQueue
void error(const Issue &issue)
Definition ers.hpp:92