2 * Copyright Andrey Semashev 2007 - 2015.
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)
8 * \file bounded_fifo_queue.hpp
9 * \author Andrey Semashev
12 * The header contains implementation of bounded FIFO queueing strategy for
13 * the asynchronous sink frontend.
16 #ifndef BOOST_LOG_SINKS_BOUNDED_FIFO_QUEUE_HPP_INCLUDED_
17 #define BOOST_LOG_SINKS_BOUNDED_FIFO_QUEUE_HPP_INCLUDED_
19 #include <boost/log/detail/config.hpp>
21 #ifdef BOOST_HAS_PRAGMA_ONCE
25 #if defined(BOOST_LOG_NO_THREADS)
26 #error Boost.Log: This header content is only supported in multithreaded environment
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>
39 BOOST_LOG_OPEN_NAMESPACE
44 * \brief Bounded FIFO log record queueing strategy
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.
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
57 * The log record queue imposes no ordering over the queued
58 * elements aside from the order in which they are enqueued.
60 template< std::size_t MaxQueueSizeV, typename OverflowStrategyT >
61 class bounded_fifo_queue :
62 private OverflowStrategyT
65 typedef OverflowStrategyT overflow_strategy;
66 typedef std::queue< record_view > queue_type;
67 typedef boost::mutex mutex_type;
70 //! Synchronization primitive
72 //! Condition to block the consuming thread on
73 condition_variable m_cond;
77 bool m_interruption_requested;
80 //! Default constructor
81 bounded_fifo_queue() : m_interruption_requested(false)
84 //! Initializing constructor
85 template< typename ArgsT >
86 explicit bounded_fifo_queue(ArgsT const&) : m_interruption_requested(false)
90 //! Enqueues log record to the queue
91 void enqueue(record_view const& rec)
93 unique_lock< mutex_type > lock(m_mutex);
94 std::size_t size = m_queue.size();
95 for (; size >= MaxQueueSizeV; size = m_queue.size())
97 if (!overflow_strategy::on_overflow(rec, lock))
106 //! Attempts to enqueue log record to the queue
107 bool try_enqueue(record_view const& rec)
109 unique_lock< mutex_type > lock(m_mutex, try_to_lock);
110 if (lock.owns_lock())
112 const std::size_t size = m_queue.size();
114 // Do not invoke the bounding strategy in case of overflow as it may block
115 if (size < MaxQueueSizeV)
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)
130 return try_dequeue(rec);
133 //! Attempts to dequeue log record from the queue, does not block if the queue is empty
134 bool try_dequeue(record_view& rec)
136 lock_guard< mutex_type > lock(m_mutex);
137 const std::size_t size = m_queue.size();
140 rec.swap(m_queue.front());
142 overflow_strategy::on_queue_space_available();
149 //! Dequeues log record from the queue, blocks if the queue is empty
150 bool dequeue_ready(record_view& rec)
152 unique_lock< mutex_type > lock(m_mutex);
154 while (!m_interruption_requested)
156 const std::size_t size = m_queue.size();
159 rec.swap(m_queue.front());
161 overflow_strategy::on_queue_space_available();
169 m_interruption_requested = false;
174 //! Wakes a thread possibly blocked in the \c dequeue method
175 void interrupt_dequeue()
177 lock_guard< mutex_type > lock(m_mutex);
178 m_interruption_requested = true;
179 overflow_strategy::interrupt();
186 BOOST_LOG_CLOSE_NAMESPACE // namespace log
190 #include <boost/log/detail/footer.hpp>
192 #endif // BOOST_LOG_SINKS_BOUNDED_FIFO_QUEUE_HPP_INCLUDED_