1 /* 2 * Copyright Andrey Semashev 2007 - 2015. 3 * Distributed under the Boost Software License, Version 1.0. 4 * (See accompanying file LICENSE_1_0.txt or copy at 5 * http://www.boost.org/LICENSE_1_0.txt) 6 */ 7 /*! 8 * \file current_thread_id.hpp 9 * \author Andrey Semashev 10 * \date 12.09.2009 11 * 12 * The header contains implementation of a current thread id attribute 13 */ 14 15 #ifndef BOOST_LOG_ATTRIBUTES_CURRENT_THREAD_ID_HPP_INCLUDED_ 16 #define BOOST_LOG_ATTRIBUTES_CURRENT_THREAD_ID_HPP_INCLUDED_ 17 18 #include <boost/log/detail/config.hpp> 19 20 #ifdef BOOST_HAS_PRAGMA_ONCE 21 #pragma once 22 #endif 23 24 #if defined(BOOST_LOG_NO_THREADS) 25 #error Boost.Log: The current_thread_id attribute is only available in multithreaded builds 26 #endif 27 28 #include <boost/smart_ptr/intrusive_ptr.hpp> 29 #include <boost/log/detail/thread_id.hpp> 30 #include <boost/log/attributes/attribute.hpp> 31 #include <boost/log/attributes/attribute_cast.hpp> 32 #include <boost/log/attributes/attribute_value_impl.hpp> 33 #include <boost/log/detail/header.hpp> 34 35 namespace boost { 36 37 BOOST_LOG_OPEN_NAMESPACE 38 39 //! Thread identifier type 40 typedef boost::log::aux::thread::id thread_id; 41 42 namespace attributes { 43 44 /*! 45 * \brief A class of an attribute that always returns the current thread identifier 46 * 47 * \note This attribute can be registered globally, it will still return the correct 48 * thread identifier, no matter which thread emits the log record. 49 */ 50 class current_thread_id : 51 public attribute 52 { 53 public: 54 //! A held attribute value type 55 typedef thread_id value_type; 56 57 protected: 58 //! Factory implementation 59 class BOOST_SYMBOL_VISIBLE impl : 60 public attribute_value::impl 61 { 62 public: dispatch(type_dispatcher & dispatcher)63 bool dispatch(type_dispatcher& dispatcher) 64 { 65 type_dispatcher::callback< value_type > callback = 66 dispatcher.get_callback< value_type >(); 67 if (callback) 68 { 69 callback(boost::log::aux::this_thread::get_id()); 70 return true; 71 } 72 else 73 return false; 74 } 75 detach_from_thread()76 intrusive_ptr< attribute_value::impl > detach_from_thread() 77 { 78 typedef attribute_value_impl< value_type > detached_value; 79 return new detached_value(boost::log::aux::this_thread::get_id()); 80 } 81 get_type() const82 typeindex::type_index get_type() const { return typeindex::type_id< value_type >(); } 83 }; 84 85 public: 86 /*! 87 * Default constructor 88 */ current_thread_id()89 current_thread_id() : attribute(new impl()) 90 { 91 } 92 /*! 93 * Constructor for casting support 94 */ current_thread_id(cast_source const & source)95 explicit current_thread_id(cast_source const& source) : 96 attribute(source.as< impl >()) 97 { 98 } 99 }; 100 101 } // namespace attributes 102 103 BOOST_LOG_CLOSE_NAMESPACE // namespace log 104 105 } // namespace boost 106 107 #include <boost/log/detail/footer.hpp> 108 109 #endif // BOOST_LOG_ATTRIBUTES_CURRENT_THREAD_ID_HPP_INCLUDED_ 110