annotate DEPENDENCIES/generic/include/boost/log/sources/exception_handler_feature.hpp @ 133:4acb5d8d80b6 tip

Don't fail environmental check if README.md exists (but .txt and no-suffix don't)
author Chris Cannam
date Tue, 30 Jul 2019 12:25:44 +0100
parents c530137014c0
children
rev   line source
Chris@16 1 /*
Chris@101 2 * Copyright Andrey Semashev 2007 - 2015.
Chris@16 3 * Distributed under the Boost Software License, Version 1.0.
Chris@16 4 * (See accompanying file LICENSE_1_0.txt or copy at
Chris@16 5 * http://www.boost.org/LICENSE_1_0.txt)
Chris@16 6 */
Chris@16 7 /*!
Chris@16 8 * \file exception_handler_feature.hpp
Chris@16 9 * \author Andrey Semashev
Chris@16 10 * \date 17.07.2009
Chris@16 11 *
Chris@16 12 * The header contains implementation of an exception handler support feature.
Chris@16 13 */
Chris@16 14
Chris@16 15 #ifndef BOOST_LOG_SOURCES_EXCEPTION_HANDLER_FEATURE_HPP_INCLUDED_
Chris@16 16 #define BOOST_LOG_SOURCES_EXCEPTION_HANDLER_FEATURE_HPP_INCLUDED_
Chris@16 17
Chris@16 18 #include <boost/mpl/if.hpp>
Chris@16 19 #include <boost/move/core.hpp>
Chris@16 20 #include <boost/move/utility.hpp>
Chris@16 21 #include <boost/type_traits/is_same.hpp>
Chris@16 22 #include <boost/log/detail/config.hpp>
Chris@16 23 #include <boost/log/detail/light_function.hpp>
Chris@16 24 #include <boost/log/detail/locks.hpp>
Chris@101 25 #include <boost/log/core/record.hpp>
Chris@16 26 #include <boost/log/sources/threading_models.hpp>
Chris@16 27 #include <boost/log/utility/strictest_lock.hpp>
Chris@16 28 #if !defined(BOOST_LOG_NO_THREADS)
Chris@16 29 #include <boost/thread/exceptions.hpp>
Chris@16 30 #endif
Chris@16 31 #include <boost/log/detail/header.hpp>
Chris@16 32
Chris@16 33 #ifdef BOOST_HAS_PRAGMA_ONCE
Chris@16 34 #pragma once
Chris@16 35 #endif
Chris@16 36
Chris@16 37 namespace boost {
Chris@16 38
Chris@16 39 BOOST_LOG_OPEN_NAMESPACE
Chris@16 40
Chris@16 41 namespace sources {
Chris@16 42
Chris@16 43 /*!
Chris@16 44 * \brief Exception handler feature implementation
Chris@16 45 */
Chris@16 46 template< typename BaseT >
Chris@16 47 class basic_exception_handler_logger :
Chris@16 48 public BaseT
Chris@16 49 {
Chris@16 50 //! Base type
Chris@16 51 typedef BaseT base_type;
Chris@16 52 typedef basic_exception_handler_logger this_type;
Chris@16 53 BOOST_COPYABLE_AND_MOVABLE_ALT(this_type)
Chris@16 54
Chris@16 55 public:
Chris@16 56 //! Threading model being used
Chris@16 57 typedef typename base_type::threading_model threading_model;
Chris@16 58 //! Final logger type
Chris@16 59 typedef typename base_type::final_type final_type;
Chris@16 60 //! Exception handler function type
Chris@16 61 typedef boost::log::aux::light_function< void () > exception_handler_type;
Chris@16 62
Chris@16 63 #if defined(BOOST_LOG_DOXYGEN_PASS)
Chris@16 64 //! Lock requirement for the open_record_unlocked method
Chris@16 65 typedef typename strictest_lock<
Chris@16 66 typename base_type::open_record_lock,
Chris@16 67 no_lock< threading_model >
Chris@16 68 >::type open_record_lock;
Chris@16 69 //! Lock requirement for the push_record_unlocked method
Chris@16 70 typedef typename strictest_lock<
Chris@16 71 typename base_type::push_record_lock,
Chris@16 72 no_lock< threading_model >
Chris@16 73 >::type push_record_lock;
Chris@16 74 #endif // defined(BOOST_LOG_DOXYGEN_PASS)
Chris@16 75
Chris@16 76 //! Lock requirement for the swap_unlocked method
Chris@16 77 typedef typename strictest_lock<
Chris@16 78 typename base_type::swap_lock,
Chris@16 79 #ifndef BOOST_LOG_NO_THREADS
Chris@16 80 boost::log::aux::exclusive_lock_guard< threading_model >
Chris@16 81 #else
Chris@16 82 no_lock< threading_model >
Chris@16 83 #endif // !defined(BOOST_LOG_NO_THREADS)
Chris@16 84 >::type swap_lock;
Chris@16 85
Chris@16 86 private:
Chris@16 87 //! Exception handler
Chris@16 88 exception_handler_type m_ExceptionHandler;
Chris@16 89
Chris@16 90 public:
Chris@16 91 /*!
Chris@16 92 * Default constructor. The constructed logger does not have an exception handler.
Chris@16 93 */
Chris@16 94 basic_exception_handler_logger() : base_type()
Chris@16 95 {
Chris@16 96 }
Chris@16 97 /*!
Chris@16 98 * Copy constructor
Chris@16 99 */
Chris@16 100 basic_exception_handler_logger(basic_exception_handler_logger const& that) :
Chris@16 101 base_type(static_cast< base_type const& >(that)),
Chris@16 102 m_ExceptionHandler(that.m_ExceptionHandler)
Chris@16 103 {
Chris@16 104 }
Chris@16 105 /*!
Chris@16 106 * Move constructor
Chris@16 107 */
Chris@16 108 basic_exception_handler_logger(BOOST_RV_REF(basic_exception_handler_logger) that) :
Chris@16 109 base_type(boost::move(static_cast< base_type& >(that))),
Chris@16 110 m_ExceptionHandler(boost::move(that.m_ExceptionHandler))
Chris@16 111 {
Chris@16 112 }
Chris@16 113 /*!
Chris@16 114 * Constructor with arguments. Passes arguments to other features.
Chris@16 115 */
Chris@16 116 template< typename ArgsT >
Chris@16 117 explicit basic_exception_handler_logger(ArgsT const& args) :
Chris@16 118 base_type(args)
Chris@16 119 {
Chris@16 120 }
Chris@16 121
Chris@16 122 /*!
Chris@16 123 * The method sets exception handler function. The function will be called with no arguments
Chris@16 124 * in case if an exception occurs during either \c open_record or \c push_record method
Chris@16 125 * execution. Since exception handler is called from a \c catch statement, the exception
Chris@16 126 * can be rethrown in order to determine its type.
Chris@16 127 *
Chris@16 128 * By default no handler is installed, thus any exception is propagated as usual.
Chris@16 129 *
Chris@16 130 * \sa <tt>utility/exception_handler.hpp</tt>
Chris@16 131 * \param handler Exception handling function
Chris@16 132 *
Chris@16 133 * \note The exception handler can be invoked in several threads concurrently.
Chris@16 134 *
Chris@16 135 * \note Thread interruptions are not affected by exception handlers.
Chris@16 136 */
Chris@16 137 template< typename HandlerT >
Chris@16 138 void set_exception_handler(HandlerT const& handler)
Chris@16 139 {
Chris@16 140 #ifndef BOOST_LOG_NO_THREADS
Chris@16 141 boost::log::aux::exclusive_lock_guard< threading_model > lock(this->get_threading_model());
Chris@16 142 #endif
Chris@16 143 m_ExceptionHandler = handler;
Chris@16 144 }
Chris@16 145
Chris@16 146 protected:
Chris@16 147 /*!
Chris@16 148 * Unlocked \c open_record
Chris@16 149 */
Chris@16 150 template< typename ArgsT >
Chris@16 151 record open_record_unlocked(ArgsT const& args)
Chris@16 152 {
Chris@16 153 try
Chris@16 154 {
Chris@16 155 return base_type::open_record_unlocked(args);
Chris@16 156 }
Chris@16 157 #ifndef BOOST_LOG_NO_THREADS
Chris@16 158 catch (thread_interrupted&)
Chris@16 159 {
Chris@16 160 throw;
Chris@16 161 }
Chris@16 162 #endif
Chris@16 163 catch (...)
Chris@16 164 {
Chris@16 165 handle_exception();
Chris@16 166 return record();
Chris@16 167 }
Chris@16 168 }
Chris@16 169
Chris@16 170 /*!
Chris@16 171 * Unlocked \c push_record
Chris@16 172 */
Chris@16 173 void push_record_unlocked(BOOST_RV_REF(record) rec)
Chris@16 174 {
Chris@16 175 try
Chris@16 176 {
Chris@16 177 base_type::push_record_unlocked(boost::move(rec));
Chris@16 178 }
Chris@16 179 #ifndef BOOST_LOG_NO_THREADS
Chris@16 180 catch (thread_interrupted&)
Chris@16 181 {
Chris@16 182 throw;
Chris@16 183 }
Chris@16 184 #endif
Chris@16 185 catch (...)
Chris@16 186 {
Chris@16 187 handle_exception();
Chris@16 188 }
Chris@16 189 }
Chris@16 190
Chris@16 191 /*!
Chris@16 192 * Unlocked swap
Chris@16 193 */
Chris@16 194 void swap_unlocked(basic_exception_handler_logger& that)
Chris@16 195 {
Chris@16 196 base_type::swap_unlocked(static_cast< base_type& >(that));
Chris@16 197 m_ExceptionHandler.swap(that.m_ExceptionHandler);
Chris@16 198 }
Chris@16 199
Chris@16 200 private:
Chris@16 201 #if !defined(BOOST_LOG_DOXYGEN_PASS)
Chris@16 202 //! The function handles the intercepted exception
Chris@16 203 void handle_exception()
Chris@16 204 {
Chris@16 205 #ifndef BOOST_LOG_NO_THREADS
Chris@16 206 // Here's the trick with the lock type. Since the lock
Chris@16 207 // is only needed when an exception is caught, we indicate
Chris@16 208 // no locking requirements in the push_record_lock type.
Chris@16 209 // However, if other features don't require locking either,
Chris@16 210 // we shall acquire a read lock here, when an exception is caught.
Chris@16 211 // If other features do require locking, the thread model is
Chris@16 212 // already locked by now, and we don't do locking at all.
Chris@16 213 typedef typename mpl::if_<
Chris@16 214 is_same< no_lock< threading_model >, typename final_type::push_record_lock >,
Chris@16 215 boost::log::aux::shared_lock_guard< threading_model >,
Chris@16 216 no_lock< threading_model >
Chris@16 217 >::type lock_type;
Chris@16 218 lock_type lock(base_type::get_threading_model());
Chris@16 219 #endif // !defined(BOOST_LOG_NO_THREADS)
Chris@16 220
Chris@16 221 if (m_ExceptionHandler.empty())
Chris@16 222 throw;
Chris@16 223 m_ExceptionHandler();
Chris@16 224 }
Chris@16 225 #endif // !defined(BOOST_LOG_DOXYGEN_PASS)
Chris@16 226 };
Chris@16 227
Chris@16 228 /*!
Chris@16 229 * \brief Exception handler support feature
Chris@16 230 *
Chris@16 231 * The logger with this feature will provide an additional method to
Chris@16 232 * install an exception handler functional object. This functional
Chris@16 233 * object will be called if during either opening or pushing a record
Chris@16 234 * an exception is thrown from the logging core.
Chris@16 235 */
Chris@16 236 struct exception_handler
Chris@16 237 {
Chris@16 238 template< typename BaseT >
Chris@16 239 struct apply
Chris@16 240 {
Chris@16 241 typedef basic_exception_handler_logger< BaseT > type;
Chris@16 242 };
Chris@16 243 };
Chris@16 244
Chris@16 245 } // namespace sources
Chris@16 246
Chris@16 247 BOOST_LOG_CLOSE_NAMESPACE // namespace log
Chris@16 248
Chris@16 249 } // namespace boost
Chris@16 250
Chris@16 251 #include <boost/log/detail/footer.hpp>
Chris@16 252
Chris@16 253 #endif // BOOST_LOG_SOURCES_EXCEPTION_HANDLER_FEATURE_HPP_INCLUDED_