Mercurial > hg > vamp-build-and-test
comparison DEPENDENCIES/generic/include/boost/log/sinks/bounded_fifo_queue.hpp @ 16:2665513ce2d3
Add boost headers
author | Chris Cannam |
---|---|
date | Tue, 05 Aug 2014 11:11:38 +0100 |
parents | |
children | c530137014c0 |
comparison
equal
deleted
inserted
replaced
15:663ca0da4350 | 16:2665513ce2d3 |
---|---|
1 /* | |
2 * Copyright Andrey Semashev 2007 - 2013. | |
3 * Distributed under the Boost Software License, Version 1.0. | |
4 * (See accompanying file LICENSE_1_0.txt or copy at | |
5 * http://www.boost.org/LICENSE_1_0.txt) | |
6 */ | |
7 /*! | |
8 * \file bounded_fifo_queue.hpp | |
9 * \author Andrey Semashev | |
10 * \date 04.01.2012 | |
11 * | |
12 * The header contains implementation of bounded FIFO queueing strategy for | |
13 * the asynchronous sink frontend. | |
14 */ | |
15 | |
16 #ifndef BOOST_LOG_SINKS_BOUNDED_FIFO_QUEUE_HPP_INCLUDED_ | |
17 #define BOOST_LOG_SINKS_BOUNDED_FIFO_QUEUE_HPP_INCLUDED_ | |
18 | |
19 #include <boost/log/detail/config.hpp> | |
20 | |
21 #ifdef BOOST_HAS_PRAGMA_ONCE | |
22 #pragma once | |
23 #endif | |
24 | |
25 #if defined(BOOST_LOG_NO_THREADS) | |
26 #error Boost.Log: This header content is only supported in multithreaded environment | |
27 #endif | |
28 | |
29 #include <cstddef> | |
30 #include <queue> | |
31 #include <boost/thread/locks.hpp> | |
32 #include <boost/thread/mutex.hpp> | |
33 #include <boost/thread/condition_variable.hpp> | |
34 #include <boost/log/core/record_view.hpp> | |
35 #include <boost/log/detail/header.hpp> | |
36 | |
37 namespace boost { | |
38 | |
39 BOOST_LOG_OPEN_NAMESPACE | |
40 | |
41 namespace sinks { | |
42 | |
43 /*! | |
44 * \brief Bounded FIFO log record queueing strategy | |
45 * | |
46 * The \c bounded_fifo_queue class is intended to be used with | |
47 * the \c asynchronous_sink frontend as a log record queueing strategy. | |
48 * | |
49 * This strategy describes log record queueing logic. | |
50 * The queue has a limited capacity, upon reaching which the enqueue operation will | |
51 * invoke the overflow handling strategy specified in the \c OverflowStrategyT | |
52 * template parameter to handle the situation. The library provides overflow handling | |
53 * strategies for most common cases: \c drop_on_overflow will silently discard the log record, | |
54 * and \c block_on_overflow will put the enqueueing thread to wait until there is space | |
55 * in the queue. | |
56 * | |
57 * The log record queue imposes no ordering over the queued | |
58 * elements aside from the order in which they are enqueued. | |
59 */ | |
60 template< std::size_t MaxQueueSizeV, typename OverflowStrategyT > | |
61 class bounded_fifo_queue : | |
62 private OverflowStrategyT | |
63 { | |
64 private: | |
65 typedef OverflowStrategyT overflow_strategy; | |
66 typedef std::queue< record_view > queue_type; | |
67 typedef boost::mutex mutex_type; | |
68 | |
69 private: | |
70 //! Synchronization primitive | |
71 mutex_type m_mutex; | |
72 //! Condition to block the consuming thread on | |
73 condition_variable m_cond; | |
74 //! Log record queue | |
75 queue_type m_queue; | |
76 //! Interruption flag | |
77 bool m_interruption_requested; | |
78 | |
79 protected: | |
80 //! Default constructor | |
81 bounded_fifo_queue() : m_interruption_requested(false) | |
82 { | |
83 } | |
84 //! Initializing constructor | |
85 template< typename ArgsT > | |
86 explicit bounded_fifo_queue(ArgsT const&) : m_interruption_requested(false) | |
87 { | |
88 } | |
89 | |
90 //! Enqueues log record to the queue | |
91 void enqueue(record_view const& rec) | |
92 { | |
93 unique_lock< mutex_type > lock(m_mutex); | |
94 std::size_t size = m_queue.size(); | |
95 for (; size >= MaxQueueSizeV; size = m_queue.size()) | |
96 { | |
97 if (!overflow_strategy::on_overflow(rec, lock)) | |
98 return; | |
99 } | |
100 | |
101 m_queue.push(rec); | |
102 if (size == 0) | |
103 m_cond.notify_one(); | |
104 } | |
105 | |
106 //! Attempts to enqueue log record to the queue | |
107 bool try_enqueue(record_view const& rec) | |
108 { | |
109 unique_lock< mutex_type > lock(m_mutex, try_to_lock); | |
110 if (lock.owns_lock()) | |
111 { | |
112 const std::size_t size = m_queue.size(); | |
113 | |
114 // Do not invoke the bounding strategy in case of overflow as it may block | |
115 if (size < MaxQueueSizeV) | |
116 { | |
117 m_queue.push(rec); | |
118 if (size == 0) | |
119 m_cond.notify_one(); | |
120 return true; | |
121 } | |
122 } | |
123 | |
124 return false; | |
125 } | |
126 | |
127 //! Attempts to dequeue a log record ready for processing from the queue, does not block if the queue is empty | |
128 bool try_dequeue_ready(record_view& rec) | |
129 { | |
130 return try_dequeue(rec); | |
131 } | |
132 | |
133 //! Attempts to dequeue log record from the queue, does not block if the queue is empty | |
134 bool try_dequeue(record_view& rec) | |
135 { | |
136 lock_guard< mutex_type > lock(m_mutex); | |
137 const std::size_t size = m_queue.size(); | |
138 if (size > 0) | |
139 { | |
140 rec.swap(m_queue.front()); | |
141 m_queue.pop(); | |
142 if (size == MaxQueueSizeV) | |
143 overflow_strategy::on_queue_space_available(); | |
144 return true; | |
145 } | |
146 | |
147 return false; | |
148 } | |
149 | |
150 //! Dequeues log record from the queue, blocks if the queue is empty | |
151 bool dequeue_ready(record_view& rec) | |
152 { | |
153 unique_lock< mutex_type > lock(m_mutex); | |
154 | |
155 while (!m_interruption_requested) | |
156 { | |
157 const std::size_t size = m_queue.size(); | |
158 if (size > 0) | |
159 { | |
160 rec.swap(m_queue.front()); | |
161 m_queue.pop(); | |
162 if (size == MaxQueueSizeV) | |
163 overflow_strategy::on_queue_space_available(); | |
164 return true; | |
165 } | |
166 else | |
167 { | |
168 m_cond.wait(lock); | |
169 } | |
170 } | |
171 m_interruption_requested = false; | |
172 | |
173 return false; | |
174 } | |
175 | |
176 //! Wakes a thread possibly blocked in the \c dequeue method | |
177 void interrupt_dequeue() | |
178 { | |
179 lock_guard< mutex_type > lock(m_mutex); | |
180 m_interruption_requested = true; | |
181 overflow_strategy::interrupt(); | |
182 m_cond.notify_one(); | |
183 } | |
184 }; | |
185 | |
186 } // namespace sinks | |
187 | |
188 BOOST_LOG_CLOSE_NAMESPACE // namespace log | |
189 | |
190 } // namespace boost | |
191 | |
192 #include <boost/log/detail/footer.hpp> | |
193 | |
194 #endif // BOOST_LOG_SINKS_BOUNDED_FIFO_QUEUE_HPP_INCLUDED_ |