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