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 <boost/shared_ptr.hpp>
+#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<tss_cleanup_function> 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<thread_specific_ptr const*>(self)->cleanup((T*)value);
-        }
+            void operator()(void* data)
+            {
+                delete static_cast<T*>(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<detail::tss_cleanup_function> cleanup;
         
     public:
         thread_specific_ptr():
-            func(0)
+            cleanup(detail::heap_new<delete_data>(),detail::do_heap_delete<delete_data>())
         {}
         explicit thread_specific_ptr(void (*func_)(T*)):
-            func(func_)
+            cleanup(detail::heap_new<run_custom_cleanup_function>(func_),detail::do_heap_delete<run_custom_cleanup_function>())
         {}
         ~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<typename T>
-        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<typename T>
-        do_delete<T> make_heap_deleter(T* data)
-        {
-            return do_delete<T>(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<boost::detail::tss_cleanup_function> 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<boost::detail::tss_cleanup_function> 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<thread_exit_callback_node>(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<tss_cleanup_function> 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;
