Index: boost/thread/win32/tss.hpp =================================================================== --- boost/thread/win32/tss.hpp (revision 41146) +++ boost/thread/win32/tss.hpp (working copy) @@ -1,13 +1,21 @@ #ifndef BOOST_THREAD_WIN32_TSS_HPP #define BOOST_THREAD_WIN32_TSS_HPP +#include +#include "thread_heap_alloc.hpp" namespace boost { namespace detail { - typedef void(*tss_cleanup_function)(void const* key,void* value); + struct tss_cleanup_function + { + virtual ~tss_cleanup_function() + {} + + virtual void operator()(void* data)=0; + }; - BOOST_THREAD_DECL void set_tss_data(void const* key,tss_cleanup_function func,void* tss_data,bool cleanup_existing); + BOOST_THREAD_DECL void set_tss_data(void const* key,boost::shared_ptr func,void* tss_data,bool cleanup_existing); BOOST_THREAD_DECL void* get_tss_data(void const* key); } @@ -18,31 +26,39 @@ thread_specific_ptr(thread_specific_ptr&); thread_specific_ptr& operator=(thread_specific_ptr&); - static void delete_data(void const* self,void* value) + struct delete_data: + detail::tss_cleanup_function { - static_cast(self)->cleanup((T*)value); - } + void operator()(void* data) + { + delete static_cast(data); + } + }; - void cleanup(T* data) const + struct run_custom_cleanup_function: + detail::tss_cleanup_function { - if(func) + void (*cleanup_function)(T*); + + explicit run_custom_cleanup_function(void (*cleanup_function_)(T*)): + cleanup_function(cleanup_function_) + {} + + void operator()(void* data) { - func(data); + cleanup_function(data); } - else - { - delete data; - } - } + }; - void (*func)(T*); + + boost::shared_ptr cleanup; public: thread_specific_ptr(): - func(0) + cleanup(detail::heap_new(),detail::do_heap_delete()) {} explicit thread_specific_ptr(void (*func_)(T*)): - func(func_) + cleanup(detail::heap_new(func_),detail::do_heap_delete()) {} ~thread_specific_ptr() { @@ -72,7 +88,7 @@ T* const current_value=get(); if(current_value!=new_value) { - detail::set_tss_data(this,delete_data,new_value,true); + detail::set_tss_data(this,cleanup,new_value,true); } } }; Index: boost/thread/win32/thread_heap_alloc.hpp =================================================================== --- boost/thread/win32/thread_heap_alloc.hpp (revision 41146) +++ boost/thread/win32/thread_heap_alloc.hpp (working copy) @@ -156,25 +156,13 @@ } template - struct do_delete + struct do_heap_delete { - T* data; - - do_delete(T* data_): - data(data_) - {} - - void operator()() const + void operator()(T* data) const { detail::heap_delete(data); } }; - - template - do_delete make_heap_deleter(T* data) - { - return do_delete(data); - } } } Index: libs/thread/doc/Jamfile.v2 =================================================================== --- libs/thread/doc/Jamfile.v2 (revision 41146) +++ libs/thread/doc/Jamfile.v2 (working copy) @@ -7,5 +7,13 @@ import toolset ; toolset.using doxygen ; -boostbook thread : thread.xml ; +#boostbook thread : thread.xml ; +xml thread : thread.qbk ; + +boostbook standalone + : + thread + : + + ; Index: libs/thread/src/win32/thread.cpp =================================================================== --- libs/thread/src/win32/thread.cpp (revision 41146) +++ libs/thread/src/win32/thread.cpp (working copy) @@ -20,28 +20,6 @@ { namespace { -#if defined(_MSC_VER) && !defined(UNDER_CE) - __declspec(thread) detail::thread_data_base* current_thread_data=0; - detail::thread_data_base* get_current_thread_data() - { - return current_thread_data; - } - void set_current_thread_data(detail::thread_data_base* new_data) - { - current_thread_data=new_data; - } -#elif defined(__BORLANDC__) - detail::thread_data_base* __thread current_thread_data=0; - detail::thread_data_base* get_current_thread_data() - { - return current_thread_data; - } - void set_current_thread_data(detail::thread_data_base* new_data) - { - current_thread_data=new_data; - } -#else - boost::once_flag current_thread_tls_init_flag=BOOST_ONCE_INIT; DWORD current_thread_tls_key=0; @@ -62,7 +40,6 @@ boost::call_once(current_thread_tls_init_flag,create_current_thread_tls_key); BOOST_VERIFY(TlsSetValue(current_thread_tls_key,new_data)); } -#endif #ifdef BOOST_NO_THREADEX // Windows CE doesn't define _beginthreadex @@ -135,11 +112,11 @@ struct tss_data_node { void const* key; - boost::detail::tss_cleanup_function func; + boost::shared_ptr func; void* value; tss_data_node* next; - tss_data_node(void const* key_,boost::detail::tss_cleanup_function func_,void* value_, + tss_data_node(void const* key_,boost::shared_ptr func_,void* value_, tss_data_node* next_): key(key_),func(func_),value(value_),next(next_) {} @@ -173,7 +150,7 @@ current_thread_data->tss_data=current_node->next; if(current_node->func) { - (*current_node->func)(current_node->key,current_node->value); + (*current_node->func)(current_node->value); } boost::detail::heap_delete(current_node); } @@ -489,7 +466,12 @@ { void add_thread_exit_function(thread_exit_function_base* func) { - detail::thread_data_base* const current_thread_data(get_current_thread_data()); + detail::thread_data_base* current_thread_data(get_current_thread_data()); + if(!current_thread_data) + { + make_external_thread_data(); + current_thread_data=get_current_thread_data(); + } thread_exit_callback_node* const new_node= heap_new(func, current_thread_data->thread_exit_callbacks); @@ -523,14 +505,14 @@ return NULL; } - void set_tss_data(void const* key,tss_cleanup_function func,void* tss_data,bool cleanup_existing) + void set_tss_data(void const* key,boost::shared_ptr func,void* tss_data,bool cleanup_existing) { tss_cleanup_implemented(); // if anyone uses TSS, we need the cleanup linked in if(tss_data_node* const current_node=find_tss_data(key)) { if(cleanup_existing && current_node->func) { - (current_node->func)(current_node->key,current_node->value); + (*current_node->func)(current_node->value); } current_node->func=func; current_node->value=tss_data;