File indexing completed on 2025-09-17 08:35:10
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 #ifndef BOOST_LOG_SOURCES_EXCEPTION_HANDLER_FEATURE_HPP_INCLUDED_
0016 #define BOOST_LOG_SOURCES_EXCEPTION_HANDLER_FEATURE_HPP_INCLUDED_
0017
0018 #include <boost/move/core.hpp>
0019 #include <boost/move/utility_core.hpp>
0020 #include <boost/type_traits/is_same.hpp>
0021 #include <boost/type_traits/is_nothrow_move_constructible.hpp>
0022 #include <boost/type_traits/conditional.hpp>
0023 #include <boost/log/detail/config.hpp>
0024 #include <boost/log/detail/light_function.hpp>
0025 #include <boost/log/detail/locks.hpp>
0026 #include <boost/log/core/record.hpp>
0027 #include <boost/log/sources/threading_models.hpp>
0028 #include <boost/log/utility/strictest_lock.hpp>
0029 #include <boost/log/detail/header.hpp>
0030
0031 #ifdef BOOST_HAS_PRAGMA_ONCE
0032 #pragma once
0033 #endif
0034
0035 namespace boost {
0036
0037 BOOST_LOG_OPEN_NAMESPACE
0038
0039 namespace sources {
0040
0041
0042
0043
0044 template< typename BaseT >
0045 class basic_exception_handler_logger :
0046 public BaseT
0047 {
0048
0049 typedef BaseT base_type;
0050 typedef basic_exception_handler_logger this_type;
0051 BOOST_COPYABLE_AND_MOVABLE_ALT(this_type)
0052
0053 public:
0054
0055 typedef typename base_type::threading_model threading_model;
0056
0057 typedef typename base_type::final_type final_type;
0058
0059 typedef boost::log::aux::light_function< void () > exception_handler_type;
0060
0061 #if defined(BOOST_LOG_DOXYGEN_PASS)
0062
0063 typedef typename strictest_lock<
0064 typename base_type::open_record_lock,
0065 no_lock< threading_model >
0066 >::type open_record_lock;
0067
0068 typedef typename strictest_lock<
0069 typename base_type::push_record_lock,
0070 no_lock< threading_model >
0071 >::type push_record_lock;
0072 #endif
0073
0074
0075 typedef typename strictest_lock<
0076 typename base_type::swap_lock,
0077 #ifndef BOOST_LOG_NO_THREADS
0078 boost::log::aux::multiple_unique_lock2< threading_model, threading_model >
0079 #else
0080 no_lock< threading_model >
0081 #endif
0082 >::type swap_lock;
0083
0084 private:
0085
0086 exception_handler_type m_ExceptionHandler;
0087
0088 public:
0089
0090
0091
0092 basic_exception_handler_logger() : base_type()
0093 {
0094 }
0095
0096
0097
0098 basic_exception_handler_logger(basic_exception_handler_logger const& that) :
0099 base_type(static_cast< base_type const& >(that)),
0100 m_ExceptionHandler(that.m_ExceptionHandler)
0101 {
0102 }
0103
0104
0105
0106 basic_exception_handler_logger(BOOST_RV_REF(basic_exception_handler_logger) that) BOOST_NOEXCEPT_IF(boost::is_nothrow_move_constructible< base_type >::value && boost::is_nothrow_move_constructible< exception_handler_type >::value) :
0107 base_type(boost::move(static_cast< base_type& >(that))),
0108 m_ExceptionHandler(boost::move(that.m_ExceptionHandler))
0109 {
0110 }
0111
0112
0113
0114 template< typename ArgsT >
0115 explicit basic_exception_handler_logger(ArgsT const& args) :
0116 base_type(args)
0117 {
0118 }
0119
0120
0121
0122
0123
0124
0125
0126
0127
0128
0129
0130
0131
0132
0133
0134
0135 template< typename HandlerT >
0136 void set_exception_handler(HandlerT const& handler)
0137 {
0138 #ifndef BOOST_LOG_NO_THREADS
0139 boost::log::aux::exclusive_lock_guard< threading_model > lock(this->get_threading_model());
0140 #endif
0141 m_ExceptionHandler = handler;
0142 }
0143
0144 protected:
0145
0146
0147
0148 template< typename ArgsT >
0149 record open_record_unlocked(ArgsT const& args)
0150 {
0151 try
0152 {
0153 return base_type::open_record_unlocked(args);
0154 }
0155 catch (...)
0156 {
0157 handle_exception();
0158 return record();
0159 }
0160 }
0161
0162
0163
0164
0165 void push_record_unlocked(BOOST_RV_REF(record) rec)
0166 {
0167 try
0168 {
0169 base_type::push_record_unlocked(boost::move(rec));
0170 }
0171 catch (...)
0172 {
0173 handle_exception();
0174 }
0175 }
0176
0177
0178
0179
0180 void swap_unlocked(basic_exception_handler_logger& that)
0181 {
0182 base_type::swap_unlocked(static_cast< base_type& >(that));
0183 m_ExceptionHandler.swap(that.m_ExceptionHandler);
0184 }
0185
0186 private:
0187 #if !defined(BOOST_LOG_DOXYGEN_PASS)
0188
0189 void handle_exception()
0190 {
0191 #ifndef BOOST_LOG_NO_THREADS
0192
0193
0194
0195
0196
0197
0198
0199 typedef typename boost::conditional<
0200 is_same< no_lock< threading_model >, typename final_type::push_record_lock >::value,
0201 boost::log::aux::shared_lock_guard< threading_model >,
0202 no_lock< threading_model >
0203 >::type lock_type;
0204 lock_type lock(base_type::get_threading_model());
0205 #endif
0206
0207 if (m_ExceptionHandler.empty())
0208 throw;
0209 m_ExceptionHandler();
0210 }
0211 #endif
0212 };
0213
0214
0215
0216
0217
0218
0219
0220
0221
0222 struct exception_handler
0223 {
0224 template< typename BaseT >
0225 struct apply
0226 {
0227 typedef basic_exception_handler_logger< BaseT > type;
0228 };
0229 };
0230
0231 }
0232
0233 BOOST_LOG_CLOSE_NAMESPACE
0234
0235 }
0236
0237 #include <boost/log/detail/footer.hpp>
0238
0239 #endif