tss.hpp 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. #ifndef BOOST_THREAD_TSS_HPP
  2. #define BOOST_THREAD_TSS_HPP
  3. // Distributed under the Boost Software License, Version 1.0. (See
  4. // accompanying file LICENSE_1_0.txt or copy at
  5. // http://www.boost.org/LICENSE_1_0.txt)
  6. // (C) Copyright 2007-8 Anthony Williams
  7. #include <boost/thread/detail/config.hpp>
  8. #include <boost/shared_ptr.hpp>
  9. #include <boost/thread/detail/thread_heap_alloc.hpp>
  10. #include <boost/config/abi_prefix.hpp>
  11. namespace boost
  12. {
  13. namespace detail
  14. {
  15. struct tss_cleanup_function
  16. {
  17. virtual ~tss_cleanup_function()
  18. {}
  19. virtual void operator()(void* data)=0;
  20. };
  21. BOOST_THREAD_DECL void set_tss_data(void const* key,boost::shared_ptr<tss_cleanup_function> func,void* tss_data,bool cleanup_existing);
  22. BOOST_THREAD_DECL void* get_tss_data(void const* key);
  23. }
  24. template <typename T>
  25. class thread_specific_ptr
  26. {
  27. private:
  28. thread_specific_ptr(thread_specific_ptr&);
  29. thread_specific_ptr& operator=(thread_specific_ptr&);
  30. struct delete_data:
  31. detail::tss_cleanup_function
  32. {
  33. void operator()(void* data)
  34. {
  35. delete static_cast<T*>(data);
  36. }
  37. };
  38. struct run_custom_cleanup_function:
  39. detail::tss_cleanup_function
  40. {
  41. void (*cleanup_function)(T*);
  42. explicit run_custom_cleanup_function(void (*cleanup_function_)(T*)):
  43. cleanup_function(cleanup_function_)
  44. {}
  45. void operator()(void* data)
  46. {
  47. cleanup_function(static_cast<T*>(data));
  48. }
  49. };
  50. boost::shared_ptr<detail::tss_cleanup_function> cleanup;
  51. public:
  52. typedef T element_type;
  53. thread_specific_ptr():
  54. cleanup(detail::heap_new<delete_data>(),detail::do_heap_delete<delete_data>())
  55. {}
  56. explicit thread_specific_ptr(void (*func_)(T*))
  57. {
  58. if(func_)
  59. {
  60. cleanup.reset(detail::heap_new<run_custom_cleanup_function>(func_),detail::do_heap_delete<run_custom_cleanup_function>());
  61. }
  62. }
  63. ~thread_specific_ptr()
  64. {
  65. detail::set_tss_data(this,boost::shared_ptr<detail::tss_cleanup_function>(),0,true);
  66. }
  67. T* get() const
  68. {
  69. return static_cast<T*>(detail::get_tss_data(this));
  70. }
  71. T* operator->() const
  72. {
  73. return get();
  74. }
  75. T& operator*() const
  76. {
  77. return *get();
  78. }
  79. T* release()
  80. {
  81. T* const temp=get();
  82. detail::set_tss_data(this,boost::shared_ptr<detail::tss_cleanup_function>(),0,false);
  83. return temp;
  84. }
  85. void reset(T* new_value=0)
  86. {
  87. T* const current_value=get();
  88. if(current_value!=new_value)
  89. {
  90. detail::set_tss_data(this,cleanup,new_value,true);
  91. }
  92. }
  93. };
  94. }
  95. #include <boost/config/abi_suffix.hpp>
  96. #endif