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 block_on_overflow.hpp
9 * \author Andrey Semashev
12 * The header contains implementation of \c block_on_overflow strategy for handling
13 * queue overflows in bounded queues for the asynchronous sink frontend.
16 #ifndef BOOST_LOG_SINKS_BLOCK_ON_OVERFLOW_HPP_INCLUDED_
17 #define BOOST_LOG_SINKS_BLOCK_ON_OVERFLOW_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
29 #include <boost/intrusive/options.hpp>
30 #include <boost/intrusive/list.hpp>
31 #include <boost/intrusive/list_hook.hpp>
32 #include <boost/thread/condition_variable.hpp>
33 #include <boost/log/core/record_view.hpp>
34 #include <boost/log/detail/header.hpp>
38 BOOST_LOG_OPEN_NAMESPACE
43 * \brief Blocking strategy for handling log record queue overflows
45 * This strategy will cause enqueueing threads to block when the
46 * log record queue overflows. The blocked threads will be woken as
47 * soon as there appears free space in the queue, in the same order
48 * they attempted to enqueue records.
50 class block_on_overflow
52 #ifndef BOOST_LOG_DOXYGEN_PASS
54 typedef intrusive::list_base_hook<
55 intrusive::link_mode< intrusive::auto_unlink >
56 > thread_context_hook_t;
58 struct thread_context :
59 public thread_context_hook_t
61 condition_variable cond;
64 thread_context() : result(true) {}
67 typedef intrusive::list<
69 intrusive::base_hook< thread_context_hook_t >,
70 intrusive::constant_time_size< false >
75 thread_contexts m_thread_contexts;
79 * Default constructor.
81 BOOST_DEFAULTED_FUNCTION(block_on_overflow(), {})
84 * This method is called by the queue when overflow is detected.
86 * \param lock An internal lock that protects the queue
88 * \retval true Attempt to enqueue the record again.
89 * \retval false Discard the record.
91 template< typename LockT >
92 bool on_overflow(record_view const&, LockT& lock)
94 thread_context context;
95 m_thread_contexts.push_back(context);
98 context.cond.wait(lock);
100 while (context.is_linked());
102 return context.result;
106 * This method is called by the queue when there appears a free space.
107 * The internal lock protecting the queue is locked when calling this method.
109 void on_queue_space_available()
111 if (!m_thread_contexts.empty())
113 m_thread_contexts.front().cond.notify_one();
114 m_thread_contexts.pop_front();
119 * This method is called by the queue to interrupt any possible waits in \c on_overflow.
120 * The internal lock protecting the queue is locked when calling this method.
124 while (!m_thread_contexts.empty())
126 thread_context& context = m_thread_contexts.front();
127 context.result = false;
128 context.cond.notify_one();
129 m_thread_contexts.pop_front();
133 // Copying prohibited
134 BOOST_DELETED_FUNCTION(block_on_overflow(block_on_overflow const&))
135 BOOST_DELETED_FUNCTION(block_on_overflow& operator= (block_on_overflow const&))
136 #endif // BOOST_LOG_DOXYGEN_PASS
141 BOOST_LOG_CLOSE_NAMESPACE // namespace log
145 #include <boost/log/detail/footer.hpp>
147 #endif // BOOST_LOG_SINKS_BLOCK_ON_OVERFLOW_HPP_INCLUDED_