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 8 #include <boost/thread/detail/config.hpp> 9 #include <boost/shared_ptr.hpp> 10 #include <boost/thread/detail/thread_heap_alloc.hpp> 11 12 #include <boost/config/abi_prefix.hpp> 13 14 namespace boost 15 { 16 namespace detail 17 { 18 struct tss_cleanup_function 19 { ~tss_cleanup_functionboost::detail::tss_cleanup_function20 virtual ~tss_cleanup_function() 21 {} 22 23 virtual void operator()(void* data)=0; 24 }; 25 26 BOOST_THREAD_DECL void set_tss_data(void const* key,boost::shared_ptr<tss_cleanup_function> func,void* tss_data,bool cleanup_existing); 27 BOOST_THREAD_DECL void* get_tss_data(void const* key); 28 } 29 30 template <typename T> 31 class thread_specific_ptr 32 { 33 private: 34 thread_specific_ptr(thread_specific_ptr&); 35 thread_specific_ptr& operator=(thread_specific_ptr&); 36 37 struct delete_data: 38 detail::tss_cleanup_function 39 { operator ()boost::thread_specific_ptr::delete_data40 void operator()(void* data) 41 { 42 delete static_cast<T*>(data); 43 } 44 }; 45 46 struct run_custom_cleanup_function: 47 detail::tss_cleanup_function 48 { 49 void (*cleanup_function)(T*); 50 run_custom_cleanup_functionboost::thread_specific_ptr::run_custom_cleanup_function51 explicit run_custom_cleanup_function(void (*cleanup_function_)(T*)): 52 cleanup_function(cleanup_function_) 53 {} 54 operator ()boost::thread_specific_ptr::run_custom_cleanup_function55 void operator()(void* data) 56 { 57 cleanup_function(static_cast<T*>(data)); 58 } 59 }; 60 61 62 boost::shared_ptr<detail::tss_cleanup_function> cleanup; 63 64 public: 65 typedef T element_type; 66 thread_specific_ptr()67 thread_specific_ptr(): 68 cleanup(detail::heap_new<delete_data>(),detail::do_heap_delete<delete_data>()) 69 {} thread_specific_ptr(void (* func_)(T *))70 explicit thread_specific_ptr(void (*func_)(T*)) 71 { 72 if(func_) 73 { 74 cleanup.reset(detail::heap_new<run_custom_cleanup_function>(func_),detail::do_heap_delete<run_custom_cleanup_function>()); 75 } 76 } ~thread_specific_ptr()77 ~thread_specific_ptr() 78 { 79 detail::set_tss_data(this,boost::shared_ptr<detail::tss_cleanup_function>(),0,true); 80 } 81 get() const82 T* get() const 83 { 84 return static_cast<T*>(detail::get_tss_data(this)); 85 } operator ->() const86 T* operator->() const 87 { 88 return get(); 89 } operator *() const90 typename boost::detail::sp_dereference< T >::type operator*() const 91 { 92 return *get(); 93 } release()94 T* release() 95 { 96 T* const temp=get(); 97 detail::set_tss_data(this,boost::shared_ptr<detail::tss_cleanup_function>(),0,false); 98 return temp; 99 } reset(T * new_value=0)100 void reset(T* new_value=0) 101 { 102 T* const current_value=get(); 103 if(current_value!=new_value) 104 { 105 detail::set_tss_data(this,cleanup,new_value,true); 106 } 107 } 108 }; 109 } 110 111 #include <boost/config/abi_suffix.hpp> 112 113 #endif 114