thread_specific.hpp 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  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 thread_specific.hpp
  9. * \author Andrey Semashev
  10. * \date 01.03.2008
  11. *
  12. * \brief This header is the Boost.Log library implementation, see the library documentation
  13. * at http://www.boost.org/doc/libs/release/libs/log/doc/html/index.html.
  14. */
  15. #ifndef BOOST_LOG_DETAIL_THREAD_SPECIFIC_HPP_INCLUDED_
  16. #define BOOST_LOG_DETAIL_THREAD_SPECIFIC_HPP_INCLUDED_
  17. #include <boost/type_traits/is_pod.hpp>
  18. #include <boost/log/detail/config.hpp>
  19. #ifdef BOOST_HAS_PRAGMA_ONCE
  20. #pragma once
  21. #endif
  22. #if !defined(BOOST_LOG_NO_THREADS)
  23. #include <boost/log/detail/header.hpp>
  24. namespace boost {
  25. BOOST_LOG_OPEN_NAMESPACE
  26. namespace aux {
  27. //! Base class for TLS to hide platform-specific storage management
  28. class thread_specific_base
  29. {
  30. private:
  31. #if defined(BOOST_THREAD_PLATFORM_WIN32)
  32. typedef unsigned long key_storage;
  33. #else
  34. typedef void* key_storage;
  35. #endif
  36. key_storage m_Key;
  37. protected:
  38. BOOST_LOG_API thread_specific_base();
  39. BOOST_LOG_API ~thread_specific_base();
  40. BOOST_LOG_API void* get_content() const;
  41. BOOST_LOG_API void set_content(void* value) const;
  42. // Copying prohibited
  43. BOOST_DELETED_FUNCTION(thread_specific_base(thread_specific_base const&))
  44. BOOST_DELETED_FUNCTION(thread_specific_base& operator= (thread_specific_base const&))
  45. };
  46. //! A TLS wrapper for small POD types with least possible overhead
  47. template< typename T >
  48. class thread_specific :
  49. public thread_specific_base
  50. {
  51. static_assert(sizeof(T) <= sizeof(void*) && is_pod< T >::value, "Boost.Log: Thread-specific values must be PODs and must not exceed the size of a pointer");
  52. //! Union to perform type casting
  53. union value_storage
  54. {
  55. void* as_pointer;
  56. T as_value;
  57. };
  58. public:
  59. //! Default constructor
  60. BOOST_DEFAULTED_FUNCTION(thread_specific(), {})
  61. //! Initializing constructor
  62. thread_specific(T const& value)
  63. {
  64. set(value);
  65. }
  66. //! Assignment
  67. thread_specific& operator= (T const& value)
  68. {
  69. set(value);
  70. return *this;
  71. }
  72. //! Accessor
  73. T get() const
  74. {
  75. value_storage cast = {};
  76. cast.as_pointer = thread_specific_base::get_content();
  77. return cast.as_value;
  78. }
  79. //! Setter
  80. void set(T const& value)
  81. {
  82. value_storage cast = {};
  83. cast.as_value = value;
  84. thread_specific_base::set_content(cast.as_pointer);
  85. }
  86. };
  87. } // namespace aux
  88. BOOST_LOG_CLOSE_NAMESPACE // namespace log
  89. } // namespace boost
  90. #include <boost/log/detail/footer.hpp>
  91. #endif // !defined(BOOST_LOG_NO_THREADS)
  92. #endif // BOOST_LOG_DETAIL_THREAD_SPECIFIC_HPP_INCLUDED_