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)
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_LOG_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
block_on_overflow(block_on_overflow const&);
80
block_on_overflow& operator= (block_on_overflow const&);
84
* Default constructor.
86
block_on_overflow() {}
89
* This method is called by the queue when overflow is detected.
91
* \param lock An internal lock that protects the queue
93
* \retval true Attempt to enqueue the record again.
94
* \retval false Discard the record.
96
template< typename LockT >
97
bool on_overflow(record_view const&, LockT& lock)
99
thread_context context;
100
m_thread_contexts.push_back(context);
103
context.cond.wait(lock);
105
while (context.is_linked());
107
return context.result;
111
* This method is called by the queue when there appears a free space.
112
* The internal lock protecting the queue is locked when calling this method.
114
void on_queue_space_available()
116
if (!m_thread_contexts.empty())
118
m_thread_contexts.front().cond.notify_one();
119
m_thread_contexts.pop_front();
124
* This method is called by the queue to interrupt any possible waits in \c on_overflow.
125
* The internal lock protecting the queue is locked when calling this method.
129
while (!m_thread_contexts.empty())
131
thread_context& context = m_thread_contexts.front();
132
context.result = false;
133
context.cond.notify_one();
134
m_thread_contexts.pop_front();
137
#endif // BOOST_LOG_DOXYGEN_PASS
142
BOOST_LOG_CLOSE_NAMESPACE // namespace log
146
#include <boost/log/detail/footer.hpp>
148
#endif // BOOST_LOG_SINKS_BLOCK_ON_OVERFLOW_HPP_INCLUDED_