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