Fast RTPS  Version 2.8.0
Fast RTPS
DBQueue.h
1 // Copyright 2016 Proyectos y Sistemas de Mantenimiento SL (eProsima).
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 //
15 #ifndef DBQUEUE_H
16 #define DBQUEUE_H
17 
18 #include <queue>
19 #include <mutex>
20 #include <memory>
21 #include <condition_variable>
22 
23 namespace eprosima {
24 namespace fastrtps {
25 
29 template<class T>
30 class DBQueue
31 {
32 
33 public:
34 
36  : mForegroundQueue(&mQueueAlpha)
37  , mBackgroundQueue(&mQueueBeta)
38  {
39  }
40 
42  void Swap()
43  {
44  std::unique_lock<std::mutex> fgGuard(mForegroundMutex);
45  std::unique_lock<std::mutex> bgGuard(mBackgroundMutex);
46 
47  // Clear the foreground queue.
48  std::queue<T>().swap(*mForegroundQueue);
49 
50  auto* swap = mBackgroundQueue;
51  mBackgroundQueue = mForegroundQueue;
52  mForegroundQueue = swap;
53  }
54 
56  void Push(
57  const T& item)
58  {
59  std::unique_lock<std::mutex> guard(mBackgroundMutex);
60  mBackgroundQueue->push(item);
61  }
62 
64  void Push(
65  T&& item)
66  {
67  std::unique_lock<std::mutex> guard(mBackgroundMutex);
68  mBackgroundQueue->push(std::move(item));
69  }
70 
73  T& Front()
74  {
75  std::unique_lock<std::mutex> guard(mForegroundMutex);
76  return mForegroundQueue->front();
77  }
78 
79  const T& Front() const
80  {
81  std::unique_lock<std::mutex> guard(mForegroundMutex);
82  return mForegroundQueue->front();
83  }
84 
86  void Pop()
87  {
88  std::unique_lock<std::mutex> guard(mForegroundMutex);
89  mForegroundQueue->pop();
90  }
91 
94  {
95  std::unique_lock<std::mutex> guard(mForegroundMutex);
96 
97  // Get value by moving the internal queue reference to a new value
98  T value = std::move(mForegroundQueue->front());
99  // At this point mForegroundQueue contains a non valid element, but mutex is taken and next instruction erase it
100 
101  // Pop value from queue
102  mForegroundQueue->pop();
103 
104  // Return value (as it has been created in this scope, it will not be copied but moved or directly forwarded)
105  return value;
106  }
107 
109  bool Empty() const
110  {
111  std::unique_lock<std::mutex> guard(mForegroundMutex);
112  return mForegroundQueue->empty();
113  }
114 
116  bool BothEmpty() const
117  {
118  std::unique_lock<std::mutex> guard(mForegroundMutex);
119  std::unique_lock<std::mutex> bgGuard(mBackgroundMutex);
120  return mForegroundQueue->empty() && mBackgroundQueue->empty();
121  }
122 
124  size_t Size() const
125  {
126  std::unique_lock<std::mutex> guard(mForegroundMutex);
127  return mForegroundQueue->size();
128  }
129 
131  void Clear()
132  {
133  std::unique_lock<std::mutex> fgGuard(mForegroundMutex);
134  std::unique_lock<std::mutex> bgGuard(mBackgroundMutex);
135  std::queue<T>().swap(*mForegroundQueue);
136  std::queue<T>().swap(*mBackgroundQueue);
137  }
138 
139 private:
140 
141  // Underlying queues
142  std::queue<T> mQueueAlpha;
143  std::queue<T> mQueueBeta;
144 
145  // Front and background queue references (double buffering)
146  std::queue<T>* mForegroundQueue;
147  std::queue<T>* mBackgroundQueue;
148 
149  mutable std::mutex mForegroundMutex;
150  mutable std::mutex mBackgroundMutex;
151 };
152 
153 
154 } // namespace fastrtps
155 } // namespace eprosima
156 
157 #endif // ifndef DBQUEUE_H
Double buffered, threadsafe queue for MPSC (multi-producer, single-consumer) comms.
Definition: DBQueue.h:31
void Swap()
Clears foreground queue and swaps queues.
Definition: DBQueue.h:42
void Push(T &&item)
Pushes to the background queue. Move constructor.
Definition: DBQueue.h:64
DBQueue()
Definition: DBQueue.h:35
size_t Size() const
Reports the size of the foreground queue.
Definition: DBQueue.h:124
void Pop()
Pops from the foreground queue.
Definition: DBQueue.h:86
T & Front()
Returns a reference to the front element in the foregrund queue.
Definition: DBQueue.h:73
void Push(const T &item)
Pushes to the background queue. Copy constructor.
Definition: DBQueue.h:56
void Clear()
Clears foreground and background.
Definition: DBQueue.h:131
bool Empty() const
Reports whether the foreground queue is empty.
Definition: DBQueue.h:109
T FrontAndPop()
Return the front element in the foreground queue by moving it and erase it from the queue.
Definition: DBQueue.h:93
bool BothEmpty() const
Reports whether the both queues are empty.
Definition: DBQueue.h:116
const T & Front() const
Definition: DBQueue.h:79
eProsima namespace.
Definition: LibrarySettingsAttributes.h:23