annotate DEPENDENCIES/generic/include/boost/log/sources/exception_handler_feature.hpp @ 94:12a7ba9fa2b4

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