diff --git a/include/boost/thread/pthread/thread_data.hpp b/include/boost/thread/pthread/thread_data.hpp index 46f111d9..588e997f 100644 --- a/include/boost/thread/pthread/thread_data.hpp +++ b/include/boost/thread/pthread/thread_data.hpp @@ -94,12 +94,15 @@ namespace boost struct thread_exit_callback_node; struct tss_data_node { - boost::shared_ptr func; + typedef void(*cleanup_func_t)(void*); + typedef void(*cleanup_caller_t)(cleanup_func_t, void*); + + cleanup_caller_t caller; + cleanup_func_t func; void* value; - tss_data_node(boost::shared_ptr func_, - void* value_): - func(func_),value(value_) + tss_data_node(cleanup_caller_t caller_,cleanup_func_t func_,void* value_): + caller(caller_),func(func_),value(value_) {} }; diff --git a/include/boost/thread/tss.hpp b/include/boost/thread/tss.hpp index d798bef5..bcfbdf0f 100644 --- a/include/boost/thread/tss.hpp +++ b/include/boost/thread/tss.hpp @@ -6,8 +6,8 @@ // (C) Copyright 2007-8 Anthony Williams #include -#include -#include + +#include #include @@ -15,15 +15,13 @@ namespace boost { namespace detail { - struct tss_cleanup_function + namespace thread { - virtual ~tss_cleanup_function() - {} + typedef void(*cleanup_func_t)(void*); + typedef void(*cleanup_caller_t)(cleanup_func_t, void*); + } - virtual void operator()(void* data)=0; - }; - - BOOST_THREAD_DECL void set_tss_data(void const* key,boost::shared_ptr func,void* tss_data,bool cleanup_existing); + BOOST_THREAD_DECL void set_tss_data(void const* key,detail::thread::cleanup_caller_t caller,detail::thread::cleanup_func_t func,void* tss_data,bool cleanup_existing); BOOST_THREAD_DECL void* get_tss_data(void const* key); } @@ -34,49 +32,33 @@ namespace boost thread_specific_ptr(thread_specific_ptr&); thread_specific_ptr& operator=(thread_specific_ptr&); - struct delete_data: - detail::tss_cleanup_function + typedef void(*original_cleanup_func_t)(T*); + + static void default_deleter(T* data) { - void operator()(void* data) - { - delete static_cast(data); - } - }; + delete data; + } - struct run_custom_cleanup_function: - detail::tss_cleanup_function + static void cleanup_caller(detail::thread::cleanup_func_t cleanup_function,void* data) { - void (*cleanup_function)(T*); - - explicit run_custom_cleanup_function(void (*cleanup_function_)(T*)): - cleanup_function(cleanup_function_) - {} - - void operator()(void* data) - { - cleanup_function(static_cast(data)); - } - }; + reinterpret_cast(cleanup_function)(static_cast(data)); + } - boost::shared_ptr cleanup; + detail::thread::cleanup_func_t cleanup; public: typedef T element_type; thread_specific_ptr(): - cleanup(detail::heap_new(),detail::do_heap_delete()) + cleanup(reinterpret_cast(&default_deleter)) {} explicit thread_specific_ptr(void (*func_)(T*)) - { - if(func_) - { - cleanup.reset(detail::heap_new(func_),detail::do_heap_delete()); - } - } + : cleanup(reinterpret_cast(func_)) + {} ~thread_specific_ptr() { - detail::set_tss_data(this,boost::shared_ptr(),0,true); + detail::set_tss_data(this,0,0,0,true); } T* get() const @@ -87,14 +69,14 @@ namespace boost { return get(); } - typename boost::detail::sp_dereference< T >::type operator*() const + typename add_reference::type operator*() const { return *get(); } T* release() { T* const temp=get(); - detail::set_tss_data(this,boost::shared_ptr(),0,false); + detail::set_tss_data(this,0,0,0,false); return temp; } void reset(T* new_value=0) @@ -102,7 +84,7 @@ namespace boost T* const current_value=get(); if(current_value!=new_value) { - detail::set_tss_data(this,cleanup,new_value,true); + detail::set_tss_data(this,&cleanup_caller,cleanup,new_value,true); } } }; diff --git a/include/boost/thread/win32/thread_data.hpp b/include/boost/thread/win32/thread_data.hpp index 2f288202..b1a550af 100644 --- a/include/boost/thread/win32/thread_data.hpp +++ b/include/boost/thread/win32/thread_data.hpp @@ -80,12 +80,15 @@ namespace boost struct thread_exit_callback_node; struct tss_data_node { - boost::shared_ptr func; + typedef void(*cleanup_func_t)(void*); + typedef void(*cleanup_caller_t)(cleanup_func_t, void*); + + cleanup_caller_t caller; + cleanup_func_t func; void* value; - tss_data_node(boost::shared_ptr func_, - void* value_): - func(func_),value(value_) + tss_data_node(cleanup_caller_t caller_,cleanup_func_t func_,void* value_): + caller(caller_),func(func_),value(value_) {} }; diff --git a/src/pthread/thread.cpp b/src/pthread/thread.cpp index 1b76570b..f318635d 100644 --- a/src/pthread/thread.cpp +++ b/src/pthread/thread.cpp @@ -111,7 +111,7 @@ namespace boost = thread_info->tss_data.begin(); if(current->second.func && (current->second.value!=0)) { - (*current->second.func)(current->second.value); + (*current->second.caller)(current->second.func,current->second.value); } thread_info->tss_data.erase(current); } @@ -726,11 +726,12 @@ namespace boost } void add_new_tss_node(void const* key, - boost::shared_ptr func, + detail::tss_data_node::cleanup_caller_t caller, + detail::tss_data_node::cleanup_func_t func, void* tss_data) { detail::thread_data_base* const current_thread_data(get_or_make_current_thread_data()); - current_thread_data->tss_data.insert(std::make_pair(key,tss_data_node(func,tss_data))); + current_thread_data->tss_data.insert(std::make_pair(key,tss_data_node(caller,func,tss_data))); } void erase_tss_node(void const* key) @@ -743,17 +744,19 @@ namespace boost } void set_tss_data(void const* key, - boost::shared_ptr func, + detail::tss_data_node::cleanup_caller_t caller, + detail::tss_data_node::cleanup_func_t func, void* tss_data,bool cleanup_existing) { if(tss_data_node* const current_node=find_tss_data(key)) { if(cleanup_existing && current_node->func && (current_node->value!=0)) { - (*current_node->func)(current_node->value); + (*current_node->caller)(current_node->func,current_node->value); } if(func || (tss_data!=0)) { + current_node->caller=caller; current_node->func=func; current_node->value=tss_data; } @@ -764,7 +767,7 @@ namespace boost } else if(func || (tss_data!=0)) { - add_new_tss_node(key,func,tss_data); + add_new_tss_node(key,caller,func,tss_data); } } } diff --git a/src/win32/thread.cpp b/src/win32/thread.cpp index 8aceb114..e1ae050b 100644 --- a/src/win32/thread.cpp +++ b/src/win32/thread.cpp @@ -276,7 +276,7 @@ namespace boost = current_thread_data->tss_data.begin(); if(current->second.func && (current->second.value!=0)) { - (*current->second.func)(current->second.value); + (*current->second.caller)(current->second.func,current->second.value); } current_thread_data->tss_data.erase(current); } @@ -909,11 +909,12 @@ namespace boost } void add_new_tss_node(void const* key, - boost::shared_ptr func, + detail::tss_data_node::cleanup_caller_t caller, + detail::tss_data_node::cleanup_func_t func, void* tss_data) { detail::thread_data_base* const current_thread_data(get_or_make_current_thread_data()); - current_thread_data->tss_data.insert(std::make_pair(key,tss_data_node(func,tss_data))); + current_thread_data->tss_data.insert(std::make_pair(key,tss_data_node(caller,func,tss_data))); } void erase_tss_node(void const* key) @@ -923,17 +924,19 @@ namespace boost } void set_tss_data(void const* key, - boost::shared_ptr func, + detail::tss_data_node::cleanup_caller_t caller, + detail::tss_data_node::cleanup_func_t func, void* tss_data,bool cleanup_existing) { if(tss_data_node* const current_node=find_tss_data(key)) { if(cleanup_existing && current_node->func && (current_node->value!=0)) { - (*current_node->func)(current_node->value); + (*current_node->caller)(current_node->func,current_node->value); } if(func || (tss_data!=0)) { + current_node->caller=caller; current_node->func=func; current_node->value=tss_data; } @@ -944,7 +947,7 @@ namespace boost } else if(func || (tss_data!=0)) { - add_new_tss_node(key,func,tss_data); + add_new_tss_node(key,caller,func,tss_data); } } }