annotate DEPENDENCIES/generic/include/boost/log/sinks/block_on_overflow.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 block_on_overflow.hpp
Chris@16 9 * \author Andrey Semashev
Chris@16 10 * \date 04.01.2012
Chris@16 11 *
Chris@16 12 * The header contains implementation of \c block_on_overflow strategy for handling
Chris@16 13 * queue overflows in bounded queues for the asynchronous sink frontend.
Chris@16 14 */
Chris@16 15
Chris@16 16 #ifndef BOOST_LOG_SINKS_BLOCK_ON_OVERFLOW_HPP_INCLUDED_
Chris@16 17 #define BOOST_LOG_SINKS_BLOCK_ON_OVERFLOW_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/intrusive/options.hpp>
Chris@16 30 #include <boost/intrusive/list.hpp>
Chris@16 31 #include <boost/intrusive/list_hook.hpp>
Chris@16 32 #include <boost/thread/condition_variable.hpp>
Chris@16 33 #include <boost/log/core/record_view.hpp>
Chris@16 34 #include <boost/log/detail/header.hpp>
Chris@16 35
Chris@16 36 namespace boost {
Chris@16 37
Chris@16 38 BOOST_LOG_OPEN_NAMESPACE
Chris@16 39
Chris@16 40 namespace sinks {
Chris@16 41
Chris@16 42 /*!
Chris@16 43 * \brief Blocking strategy for handling log record queue overflows
Chris@16 44 *
Chris@16 45 * This strategy will cause enqueueing threads to block when the
Chris@16 46 * log record queue overflows. The blocked threads will be woken as
Chris@16 47 * soon as there appears free space in the queue, in the same order
Chris@16 48 * they attempted to enqueue records.
Chris@16 49 */
Chris@16 50 class block_on_overflow
Chris@16 51 {
Chris@16 52 #ifndef BOOST_LOG_DOXYGEN_PASS
Chris@16 53 private:
Chris@16 54 typedef intrusive::list_base_hook<
Chris@16 55 intrusive::link_mode< intrusive::auto_unlink >
Chris@16 56 > thread_context_hook_t;
Chris@16 57
Chris@16 58 struct thread_context :
Chris@16 59 public thread_context_hook_t
Chris@16 60 {
Chris@16 61 condition_variable cond;
Chris@16 62 bool result;
Chris@16 63
Chris@16 64 thread_context() : result(true) {}
Chris@16 65 };
Chris@16 66
Chris@16 67 typedef intrusive::list<
Chris@16 68 thread_context,
Chris@16 69 intrusive::base_hook< thread_context_hook_t >,
Chris@16 70 intrusive::constant_time_size< false >
Chris@16 71 > thread_contexts;
Chris@16 72
Chris@16 73 private:
Chris@16 74 //! Blocked threads
Chris@16 75 thread_contexts m_thread_contexts;
Chris@16 76
Chris@16 77 public:
Chris@16 78 /*!
Chris@16 79 * Default constructor.
Chris@16 80 */
Chris@101 81 BOOST_DEFAULTED_FUNCTION(block_on_overflow(), {})
Chris@16 82
Chris@16 83 /*!
Chris@16 84 * This method is called by the queue when overflow is detected.
Chris@16 85 *
Chris@16 86 * \param lock An internal lock that protects the queue
Chris@16 87 *
Chris@16 88 * \retval true Attempt to enqueue the record again.
Chris@16 89 * \retval false Discard the record.
Chris@16 90 */
Chris@16 91 template< typename LockT >
Chris@16 92 bool on_overflow(record_view const&, LockT& lock)
Chris@16 93 {
Chris@16 94 thread_context context;
Chris@16 95 m_thread_contexts.push_back(context);
Chris@16 96 do
Chris@16 97 {
Chris@16 98 context.cond.wait(lock);
Chris@16 99 }
Chris@16 100 while (context.is_linked());
Chris@16 101
Chris@16 102 return context.result;
Chris@16 103 }
Chris@16 104
Chris@16 105 /*!
Chris@16 106 * This method is called by the queue when there appears a free space.
Chris@16 107 * The internal lock protecting the queue is locked when calling this method.
Chris@16 108 */
Chris@16 109 void on_queue_space_available()
Chris@16 110 {
Chris@16 111 if (!m_thread_contexts.empty())
Chris@16 112 {
Chris@16 113 m_thread_contexts.front().cond.notify_one();
Chris@16 114 m_thread_contexts.pop_front();
Chris@16 115 }
Chris@16 116 }
Chris@16 117
Chris@16 118 /*!
Chris@16 119 * This method is called by the queue to interrupt any possible waits in \c on_overflow.
Chris@16 120 * The internal lock protecting the queue is locked when calling this method.
Chris@16 121 */
Chris@16 122 void interrupt()
Chris@16 123 {
Chris@16 124 while (!m_thread_contexts.empty())
Chris@16 125 {
Chris@16 126 thread_context& context = m_thread_contexts.front();
Chris@16 127 context.result = false;
Chris@16 128 context.cond.notify_one();
Chris@16 129 m_thread_contexts.pop_front();
Chris@16 130 }
Chris@16 131 }
Chris@101 132
Chris@101 133 // Copying prohibited
Chris@101 134 BOOST_DELETED_FUNCTION(block_on_overflow(block_on_overflow const&))
Chris@101 135 BOOST_DELETED_FUNCTION(block_on_overflow& operator= (block_on_overflow const&))
Chris@16 136 #endif // BOOST_LOG_DOXYGEN_PASS
Chris@16 137 };
Chris@16 138
Chris@16 139 } // namespace sinks
Chris@16 140
Chris@16 141 BOOST_LOG_CLOSE_NAMESPACE // namespace log
Chris@16 142
Chris@16 143 } // namespace boost
Chris@16 144
Chris@16 145 #include <boost/log/detail/footer.hpp>
Chris@16 146
Chris@16 147 #endif // BOOST_LOG_SINKS_BLOCK_ON_OVERFLOW_HPP_INCLUDED_