LinkedBlockingQueue.h
Go to the documentation of this file.
1 #ifndef _RMS_LINKEDBLOCKINGQUEUE_H
2 #define _RMS_LINKEDBLOCKINGQUEUE_H
3 
4 #include <boost/thread/mutex.hpp>
5 #include <boost/thread/condition.hpp>
6 #include <boost/thread/xtime.hpp>
7 
8 #include <queue>
9 
10 namespace gov {
11 
12 namespace fnal {
13 
14 namespace cd {
15 
16 namespace rms {
17 
18 namespace util {
19 
20 /**
21  * This is a templated thread safe container that is meant to
22  * emulate the LinkedBlockingQueue that is used in the Java
23  * version of RMS.
24  *
25  * @author Kurt Biery
26  * @author Steve Foulkes
27  * @version $Revision: 1.2.14.1 $ $Date: 2019/09/27 00:07:32 $
28  */
29 
30 template <class QueueType> class LinkedBlockingQueue {
31  public:
32  /**
33  * Add an element to the queue. After obtaining the queue lock,
34  * push an object onto the stack and notify the condition variable
35  * that the queue is not empty.
36  *
37  * @param object The object that is to be inserted into the queue.
38  */
39  void add(QueueType object) {
40  boost::mutex::scoped_lock lk(_queueLock);
41 
42  _queue.push(object);
43  _queueCondition.notify_one();
44 
45  return;
46  }
47 
48  /**
49  * Take an element off the queue. If the queue is empty,
50  * this will block until an element is added to the queue.
51  *
52  * @return An object from the queue.
53  */
54  QueueType take() {
55  QueueType queueEntry;
56 
57  boost::mutex::scoped_lock lk(_queueLock);
58 
59  while (_queue.size() == 0) {
60  _queueCondition.wait(lk);
61  }
62 
63  queueEntry = _queue.front();
64  _queue.pop();
65 
66  return queueEntry;
67  }
68 
69  /**
70  * Take an element off the queue. If the queue is empty,
71  * this will wait at most timeout seconds before returning.
72  *
73  * @param timeout The amount of time to wait, in seconds,
74  * before returning if the queue is empty.
75  *
76  * @return An object from the queue if one be can retrieved
77  * before the timeout. An object created with its befault
78  * constructor will be returned otherwise.
79  */
80  QueueType poll(long timeout) {
81  QueueType queueEntry;
82 
83  boost::xtime xt;
84 
85 #if BOOST_VERSION >= 105000
86  boost::xtime_get(&xt, boost::TIME_UTC_);
87 #else
88  boost::xtime_get(&xt, boost::TIME_UTC);
89 #endif
90 
91  xt.sec += timeout;
92 
93  boost::mutex::scoped_lock lk(_queueLock);
94 
95  while (_queue.size() == 0) {
96  if (!_queueCondition.timed_wait(lk, xt)) {
97  return queueEntry;
98  }
99  }
100 
101  queueEntry = _queue.front();
102  _queue.pop();
103 
104  return queueEntry;
105  }
106 
107  /**
108  * Take an element off the queue. This function will not
109  * block if the queue is empty.
110  *
111  * @return An object from the queue if the queue is not
112  * empty. An object created with its befault constructor
113  * will be returned otherwise.
114  */
115  QueueType poll() {
116  QueueType queueEntry;
117  boost::mutex::scoped_lock lk(_queueLock);
118 
119  while (_queue.size() == 0) {
120  return queueEntry;
121  }
122 
123  queueEntry = _queue.front();
124  _queue.pop();
125 
126  return queueEntry;
127  }
128 
129  private:
130  /**
131  * Mutex for protecting the queue. A process can only read or write
132  * to the queue if it holds this lock.
133  */
135 
136  /** Condition variabled that allows the queue to block a process if the
137  * queue is empty.
138  */
139  boost::condition _queueCondition;
140 
141  /**
142  * An STL queue is used as the actual data container.
143  */
144  std::queue<QueueType> _queue;
145 
146 };
147 
148 } // end of namespace util
149 
150 } // end of namespace rms
151 
152 } // end of namespace cd
153 
154 } // end of namespace fnal
155 
156 } // end of namespace gov
157 
158 #endif
Filter events based on their run/event numbers.
Definition: fnal.py:1
c cd(1)