GNSS-SDR  0.0.19
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 <mutex>
23 #include <queue>
24 #include <thread>
25 
26 /** \addtogroup Core
27  * \{ */
28 /** \addtogroup Core_Receiver
29  * \{ */
30 
31 
32 template <typename Data>
33 
34 /*!
35  * \brief This class implements a thread-safe std::queue
36  *
37  * Thread-safe object queue which uses the library
38  * boost_thread to perform MUTEX based on the code available at
39  * https://www.justsoftwaresolutions.co.uk/threading/implementing-a-thread-safe-queue-using-condition-variables.html
40  */
41 class Concurrent_Queue
42 {
43 public:
44  void push(Data const& data)
45  {
46  std::unique_lock<std::mutex> lock(the_mutex);
47  the_queue.push(data);
48  lock.unlock();
49  the_condition_variable.notify_one();
50  }
51 
52  bool empty() const
53  {
54  std::unique_lock<std::mutex> lock(the_mutex);
55  return the_queue.empty();
56  }
57 
58  size_t size() const
59  {
60  std::unique_lock<std::mutex> lock(the_mutex);
61  return the_queue.size();
62  }
63 
64  void clear()
65  {
66  std::unique_lock<std::mutex> lock(the_mutex);
67  the_queue = std::queue<Data>();
68  }
69 
70  bool try_pop(Data& popped_value)
71  {
72  std::unique_lock<std::mutex> lock(the_mutex);
73  if (the_queue.empty())
74  {
75  return false;
76  }
77  popped_value = the_queue.front();
78  the_queue.pop();
79  return true;
80  }
81 
82  void wait_and_pop(Data& popped_value)
83  {
84  std::unique_lock<std::mutex> lock(the_mutex);
85  while (the_queue.empty())
86  {
87  the_condition_variable.wait(lock);
88  }
89  popped_value = the_queue.front();
90  the_queue.pop();
91  }
92 
93  bool timed_wait_and_pop(Data& popped_value, int wait_ms)
94  {
95  std::unique_lock<std::mutex> lock(the_mutex);
96  if (the_queue.empty())
97  {
98  the_condition_variable.wait_for(lock, std::chrono::milliseconds(wait_ms));
99  if (the_queue.empty())
100  {
101  return false;
102  }
103  }
104  popped_value = the_queue.front();
105  the_queue.pop();
106  return true;
107  }
108 
109 private:
110  std::queue<Data> the_queue;
111  mutable std::mutex the_mutex;
112  std::condition_variable the_condition_variable;
113 };
114 
115 
116 /** \} */
117 /** \} */
118 #endif // GNSS_SDR_CONCURRENT_QUEUE_H
This class implements a thread-safe std::queue.