File indexing completed on 2025-09-16 08:37:52
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016 #ifndef BOOST_LOG_SINKS_BOUNDED_FIFO_QUEUE_HPP_INCLUDED_
0017 #define BOOST_LOG_SINKS_BOUNDED_FIFO_QUEUE_HPP_INCLUDED_
0018
0019 #include <boost/log/detail/config.hpp>
0020
0021 #ifdef BOOST_HAS_PRAGMA_ONCE
0022 #pragma once
0023 #endif
0024
0025 #if defined(BOOST_LOG_NO_THREADS)
0026 #error Boost.Log: This header content is only supported in multithreaded environment
0027 #endif
0028
0029 #include <cstddef>
0030 #include <queue>
0031 #include <mutex>
0032 #include <condition_variable>
0033 #include <boost/log/core/record_view.hpp>
0034 #include <boost/log/detail/header.hpp>
0035
0036 namespace boost {
0037
0038 BOOST_LOG_OPEN_NAMESPACE
0039
0040 namespace sinks {
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059 template< std::size_t MaxQueueSizeV, typename OverflowStrategyT >
0060 class bounded_fifo_queue :
0061 private OverflowStrategyT
0062 {
0063 private:
0064 typedef OverflowStrategyT overflow_strategy;
0065 typedef std::queue< record_view > queue_type;
0066 typedef std::mutex mutex_type;
0067
0068 private:
0069
0070 mutex_type m_mutex;
0071
0072 std::condition_variable m_cond;
0073
0074 queue_type m_queue;
0075
0076 bool m_interruption_requested;
0077
0078 protected:
0079
0080 bounded_fifo_queue() : m_interruption_requested(false)
0081 {
0082 }
0083
0084 template< typename ArgsT >
0085 explicit bounded_fifo_queue(ArgsT const&) : m_interruption_requested(false)
0086 {
0087 }
0088
0089
0090 void enqueue(record_view const& rec)
0091 {
0092 std::unique_lock< mutex_type > lock(m_mutex);
0093 std::size_t size = m_queue.size();
0094 for (; size >= MaxQueueSizeV; size = m_queue.size())
0095 {
0096 if (!overflow_strategy::on_overflow(rec, lock))
0097 return;
0098 }
0099
0100 m_queue.push(rec);
0101 if (size == 0)
0102 m_cond.notify_one();
0103 }
0104
0105
0106 bool try_enqueue(record_view const& rec)
0107 {
0108 std::unique_lock< mutex_type > lock(m_mutex, std::try_to_lock);
0109 if (lock.owns_lock())
0110 {
0111 const std::size_t size = m_queue.size();
0112
0113
0114 if (size < MaxQueueSizeV)
0115 {
0116 m_queue.push(rec);
0117 if (size == 0)
0118 m_cond.notify_one();
0119 return true;
0120 }
0121 }
0122
0123 return false;
0124 }
0125
0126
0127 bool try_dequeue_ready(record_view& rec)
0128 {
0129 return try_dequeue(rec);
0130 }
0131
0132
0133 bool try_dequeue(record_view& rec)
0134 {
0135 std::lock_guard< mutex_type > lock(m_mutex);
0136 const std::size_t size = m_queue.size();
0137 if (size > 0)
0138 {
0139 rec.swap(m_queue.front());
0140 m_queue.pop();
0141 overflow_strategy::on_queue_space_available();
0142 return true;
0143 }
0144
0145 return false;
0146 }
0147
0148
0149 bool dequeue_ready(record_view& rec)
0150 {
0151 std::unique_lock< mutex_type > lock(m_mutex);
0152
0153 while (!m_interruption_requested)
0154 {
0155 const std::size_t size = m_queue.size();
0156 if (size > 0)
0157 {
0158 rec.swap(m_queue.front());
0159 m_queue.pop();
0160 overflow_strategy::on_queue_space_available();
0161 return true;
0162 }
0163 else
0164 {
0165 m_cond.wait(lock);
0166 }
0167 }
0168 m_interruption_requested = false;
0169
0170 return false;
0171 }
0172
0173
0174 void interrupt_dequeue()
0175 {
0176 std::lock_guard< mutex_type > lock(m_mutex);
0177 m_interruption_requested = true;
0178 overflow_strategy::interrupt();
0179 m_cond.notify_one();
0180 }
0181 };
0182
0183 }
0184
0185 BOOST_LOG_CLOSE_NAMESPACE
0186
0187 }
0188
0189 #include <boost/log/detail/footer.hpp>
0190
0191 #endif