GNSS-SDR  0.0.21
An Open Source GNSS Software Defined Receiver
concurrent_queue.h
Go to the documentation of this file.
1 /*!
2  * \file concurrent_queue.h
3  * \brief Interface of a thread-safe std::queue
4  * \author Javier Arribas, 2011. jarribas(at)cttc.es
5  *
6  * -----------------------------------------------------------------------------
7  *
8  * GNSS-SDR is a Global Navigation Satellite System software-defined receiver.
9  * This file is part of GNSS-SDR.
10  *
11  * Copyright (C) 2010-2020 (see AUTHORS file for a list of contributors)
12  * SPDX-License-Identifier: GPL-3.0-or-later
13  *
14  * -----------------------------------------------------------------------------
15  */
16 
17 #ifndef GNSS_SDR_CONCURRENT_QUEUE_H
18 #define GNSS_SDR_CONCURRENT_QUEUE_H
19 
20 #include <chrono>
21 #include <condition_variable>
22 #include <cstddef>
23 #include <mutex>
24 #include <queue>
25 #include <utility>
26 
27 /** \addtogroup Core
28  * \{ */
29 /** \addtogroup Core_Receiver
30  * \{ */
31 
32 
33 template <typename Data>
34 
35 /*!
36  * \brief This class implements a thread-safe std::queue
37  */
38 class Concurrent_Queue
39 {
40 public:
41  void push(const Data& data)
42  {
43  {
44  std::lock_guard<std::mutex> lock(the_mutex);
45  the_queue.push(data);
46  }
47  the_condition_variable.notify_one();
48  }
49 
50  void push(Data&& data)
51  {
52  {
53  std::lock_guard<std::mutex> lock(the_mutex);
54  the_queue.push(std::move(data));
55  }
56  the_condition_variable.notify_one();
57  }
58 
59  bool empty() const noexcept
60  {
61  return size() == 0;
62  }
63 
64  size_t size() const noexcept
65  {
66  std::lock_guard<std::mutex> lock(the_mutex);
67  return the_queue.size();
68  }
69 
70  void clear()
71  {
72  std::lock_guard<std::mutex> lock(the_mutex);
73  std::queue<Data>().swap(the_queue);
74  }
75 
76  bool try_pop(Data& popped_value)
77  {
78  std::lock_guard<std::mutex> lock(the_mutex);
79  if (the_queue.empty())
80  {
81  return false;
82  }
83  popped_value = std::move(the_queue.front());
84  the_queue.pop();
85  return true;
86  }
87 
88  void wait_and_pop(Data& popped_value)
89  {
90  std::unique_lock<std::mutex> lock(the_mutex);
91  the_condition_variable.wait(lock, [this] { return !the_queue.empty(); });
92  popped_value = std::move(the_queue.front());
93  the_queue.pop();
94  }
95 
96  bool timed_wait_and_pop(Data& popped_value, int wait_ms)
97  {
98  std::unique_lock<std::mutex> lock(the_mutex);
99  if (!the_condition_variable.wait_for(lock,
100  std::chrono::milliseconds(wait_ms),
101  [this] { return !the_queue.empty(); }))
102  {
103  return false;
104  }
105  popped_value = std::move(the_queue.front());
106  the_queue.pop();
107  return true;
108  }
109 
110 private:
111  std::queue<Data> the_queue;
112  mutable std::mutex the_mutex;
113  std::condition_variable the_condition_variable;
114 };
115 
116 
117 /** \} */
118 /** \} */
119 #endif // GNSS_SDR_CONCURRENT_QUEUE_H
This class implements a thread-safe std::queue.