annotate DEPENDENCIES/generic/include/boost/log/sinks/unbounded_fifo_queue.hpp @ 133:4acb5d8d80b6 tip

Don't fail environmental check if README.md exists (but .txt and no-suffix don't)
author Chris Cannam
date Tue, 30 Jul 2019 12:25:44 +0100
parents c530137014c0
children
rev   line source
Chris@16 1 /*
Chris@101 2 * Copyright Andrey Semashev 2007 - 2015.
Chris@16 3 * Distributed under the Boost Software License, Version 1.0.
Chris@16 4 * (See accompanying file LICENSE_1_0.txt or copy at
Chris@16 5 * http://www.boost.org/LICENSE_1_0.txt)
Chris@16 6 */
Chris@16 7 /*!
Chris@16 8 * \file unbounded_fifo_queue.hpp
Chris@16 9 * \author Andrey Semashev
Chris@16 10 * \date 24.07.2011
Chris@16 11 *
Chris@16 12 * The header contains implementation of unbounded FIFO queueing strategy for
Chris@16 13 * the asynchronous sink frontend.
Chris@16 14 */
Chris@16 15
Chris@16 16 #ifndef BOOST_LOG_SINKS_UNBOUNDED_FIFO_QUEUE_HPP_INCLUDED_
Chris@16 17 #define BOOST_LOG_SINKS_UNBOUNDED_FIFO_QUEUE_HPP_INCLUDED_
Chris@16 18
Chris@16 19 #include <boost/log/detail/config.hpp>
Chris@16 20
Chris@16 21 #ifdef BOOST_HAS_PRAGMA_ONCE
Chris@16 22 #pragma once
Chris@16 23 #endif
Chris@16 24
Chris@16 25 #if defined(BOOST_LOG_NO_THREADS)
Chris@16 26 #error Boost.Log: This header content is only supported in multithreaded environment
Chris@16 27 #endif
Chris@16 28
Chris@16 29 #include <boost/log/detail/event.hpp>
Chris@16 30 #include <boost/log/detail/threadsafe_queue.hpp>
Chris@16 31 #include <boost/log/core/record_view.hpp>
Chris@16 32 #include <boost/log/detail/header.hpp>
Chris@16 33
Chris@16 34 namespace boost {
Chris@16 35
Chris@16 36 BOOST_LOG_OPEN_NAMESPACE
Chris@16 37
Chris@16 38 namespace sinks {
Chris@16 39
Chris@16 40 /*!
Chris@16 41 * \brief Unbounded FIFO log record queueing strategy
Chris@16 42 *
Chris@16 43 * The \c unbounded_fifo_queue class is intended to be used with
Chris@16 44 * the \c asynchronous_sink frontend as a log record queueing strategy.
Chris@16 45 *
Chris@16 46 * This strategy implements the simplest logic of log record buffering between
Chris@16 47 * threads: the queue has no limits and imposes no ordering over the queued
Chris@16 48 * elements aside from the order in which they are enqueued.
Chris@16 49 * Because of this the queue provides decent performance and scalability,
Chris@16 50 * however if sink backends can't consume log records fast enough the queue
Chris@16 51 * may grow uncontrollably. When this is an issue, it is recommended to
Chris@16 52 * use one of the bounded strategies.
Chris@16 53 */
Chris@16 54 class unbounded_fifo_queue
Chris@16 55 {
Chris@16 56 private:
Chris@16 57 typedef boost::log::aux::threadsafe_queue< record_view > queue_type;
Chris@16 58
Chris@16 59 private:
Chris@16 60 //! Thread-safe queue
Chris@16 61 queue_type m_queue;
Chris@16 62 //! Event object to block on
Chris@16 63 boost::log::aux::event m_event;
Chris@16 64 //! Interruption flag
Chris@16 65 volatile bool m_interruption_requested; // TODO: make it atomic
Chris@16 66
Chris@16 67 protected:
Chris@16 68 //! Default constructor
Chris@16 69 unbounded_fifo_queue() : m_interruption_requested(false)
Chris@16 70 {
Chris@16 71 }
Chris@16 72 //! Initializing constructor
Chris@16 73 template< typename ArgsT >
Chris@16 74 explicit unbounded_fifo_queue(ArgsT const&) : m_interruption_requested(false)
Chris@16 75 {
Chris@16 76 }
Chris@16 77
Chris@16 78 //! Enqueues log record to the queue
Chris@16 79 void enqueue(record_view const& rec)
Chris@16 80 {
Chris@16 81 m_queue.push(rec);
Chris@16 82 m_event.set_signalled();
Chris@16 83 }
Chris@16 84
Chris@16 85 //! Attempts to enqueue log record to the queue
Chris@16 86 bool try_enqueue(record_view const& rec)
Chris@16 87 {
Chris@16 88 // Assume the call never blocks
Chris@16 89 enqueue(rec);
Chris@16 90 return true;
Chris@16 91 }
Chris@16 92
Chris@16 93 //! Attempts to dequeue a log record ready for processing from the queue, does not block if the queue is empty
Chris@16 94 bool try_dequeue_ready(record_view& rec)
Chris@16 95 {
Chris@16 96 return m_queue.try_pop(rec);
Chris@16 97 }
Chris@16 98
Chris@16 99 //! Attempts to dequeue log record from the queue, does not block if the queue is empty
Chris@16 100 bool try_dequeue(record_view& rec)
Chris@16 101 {
Chris@16 102 return m_queue.try_pop(rec);
Chris@16 103 }
Chris@16 104
Chris@16 105 //! Dequeues log record from the queue, blocks if the queue is empty
Chris@16 106 bool dequeue_ready(record_view& rec)
Chris@16 107 {
Chris@16 108 // Try the fast way first
Chris@16 109 if (m_queue.try_pop(rec))
Chris@16 110 return true;
Chris@16 111
Chris@16 112 // Ok, we probably have to wait for new records
Chris@16 113 while (true)
Chris@16 114 {
Chris@16 115 m_event.wait();
Chris@16 116 if (m_interruption_requested)
Chris@16 117 {
Chris@16 118 m_interruption_requested = false;
Chris@16 119 return false;
Chris@16 120 }
Chris@16 121 if (m_queue.try_pop(rec))
Chris@16 122 return true;
Chris@16 123 }
Chris@16 124 }
Chris@16 125
Chris@16 126 //! Wakes a thread possibly blocked in the \c dequeue method
Chris@16 127 void interrupt_dequeue()
Chris@16 128 {
Chris@16 129 m_interruption_requested = true;
Chris@16 130 m_event.set_signalled();
Chris@16 131 }
Chris@16 132 };
Chris@16 133
Chris@16 134 } // namespace sinks
Chris@16 135
Chris@16 136 BOOST_LOG_CLOSE_NAMESPACE // namespace log
Chris@16 137
Chris@16 138 } // namespace boost
Chris@16 139
Chris@16 140 #include <boost/log/detail/footer.hpp>
Chris@16 141
Chris@16 142 #endif // BOOST_LOG_SINKS_UNBOUNDED_FIFO_QUEUE_HPP_INCLUDED_