$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r53387 - in trunk: boost/thread libs/thread/test
From: anthony_at_[hidden]
Date: 2009-05-29 06:57:41
Author: anthonyw
Date: 2009-05-29 06:57:39 EDT (Fri, 29 May 2009)
New Revision: 53387
URL: http://svn.boost.org/trac/boost/changeset/53387
Log:
Test and fix for first part of issue #2797
Text files modified: 
   trunk/boost/thread/tss.hpp          |   222 ++++++++++++++++++++--------------------
   trunk/libs/thread/test/test_tss.cpp |    21 +++                                     
   2 files changed, 132 insertions(+), 111 deletions(-)
Modified: trunk/boost/thread/tss.hpp
==============================================================================
--- trunk/boost/thread/tss.hpp	(original)
+++ trunk/boost/thread/tss.hpp	2009-05-29 06:57:39 EDT (Fri, 29 May 2009)
@@ -1,111 +1,111 @@
-#ifndef BOOST_THREAD_TSS_HPP
-#define BOOST_THREAD_TSS_HPP
-// Distributed under the Boost Software License, Version 1.0. (See
-// accompanying file LICENSE_1_0.txt or copy at
-// http://www.boost.org/LICENSE_1_0.txt)
-// (C) Copyright 2007-8 Anthony Williams
-
-#include <boost/thread/detail/config.hpp>
-#include <boost/shared_ptr.hpp>
-#include <boost/thread/detail/thread_heap_alloc.hpp>
-
-#include <boost/config/abi_prefix.hpp>
-
-namespace boost
-{
-    namespace detail
-    {
-        struct tss_cleanup_function
-        {
-            virtual ~tss_cleanup_function()
-            {}
-            
-            virtual void operator()(void* data)=0;
-        };
-        
-        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);
-    }
-
-    template <typename T>
-    class thread_specific_ptr
-    {
-    private:
-        thread_specific_ptr(thread_specific_ptr&);
-        thread_specific_ptr& operator=(thread_specific_ptr&);
-
-        struct delete_data:
-            detail::tss_cleanup_function
-        {
-            void operator()(void* data)
-            {
-                delete static_cast<T*>(data);
-            }
-        };
-        
-        struct run_custom_cleanup_function:
-            detail::tss_cleanup_function
-        {
-            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<T*>(data));
-            }
-        };
-
-
-        boost::shared_ptr<detail::tss_cleanup_function> cleanup;
-        
-    public:
-        thread_specific_ptr():
-            cleanup(detail::heap_new<delete_data>(),detail::do_heap_delete<delete_data>())
-        {}
-        explicit thread_specific_ptr(void (*func_)(T*))
-        {
-            if(func_)
-            {
-                cleanup.reset(detail::heap_new<run_custom_cleanup_function>(func_),detail::do_heap_delete<run_custom_cleanup_function>());
-            }
-        }
-        ~thread_specific_ptr()
-        {
-            reset();
-        }
-
-        T* get() const
-        {
-            return static_cast<T*>(detail::get_tss_data(this));
-        }
-        T* operator->() const
-        {
-            return get();
-        }
-        T& operator*() const
-        {
-            return *get();
-        }
-        T* release()
-        {
-            T* const temp=get();
-            detail::set_tss_data(this,boost::shared_ptr<detail::tss_cleanup_function>(),0,false);
-            return temp;
-        }
-        void reset(T* new_value=0)
-        {
-            T* const current_value=get();
-            if(current_value!=new_value)
-            {
-                detail::set_tss_data(this,cleanup,new_value,true);
-            }
-        }
-    };
-}
-
-#include <boost/config/abi_suffix.hpp>
-
-#endif
+#ifndef BOOST_THREAD_TSS_HPP
+#define BOOST_THREAD_TSS_HPP
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+// (C) Copyright 2007-8 Anthony Williams
+
+#include <boost/thread/detail/config.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/thread/detail/thread_heap_alloc.hpp>
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost
+{
+    namespace detail
+    {
+        struct tss_cleanup_function
+        {
+            virtual ~tss_cleanup_function()
+            {}
+            
+            virtual void operator()(void* data)=0;
+        };
+        
+        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);
+    }
+
+    template <typename T>
+    class thread_specific_ptr
+    {
+    private:
+        thread_specific_ptr(thread_specific_ptr&);
+        thread_specific_ptr& operator=(thread_specific_ptr&);
+
+        struct delete_data:
+            detail::tss_cleanup_function
+        {
+            void operator()(void* data)
+            {
+                delete static_cast<T*>(data);
+            }
+        };
+        
+        struct run_custom_cleanup_function:
+            detail::tss_cleanup_function
+        {
+            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<T*>(data));
+            }
+        };
+
+
+        boost::shared_ptr<detail::tss_cleanup_function> cleanup;
+        
+    public:
+        thread_specific_ptr():
+            cleanup(detail::heap_new<delete_data>(),detail::do_heap_delete<delete_data>())
+        {}
+        explicit thread_specific_ptr(void (*func_)(T*))
+        {
+            if(func_)
+            {
+                cleanup.reset(detail::heap_new<run_custom_cleanup_function>(func_),detail::do_heap_delete<run_custom_cleanup_function>());
+            }
+        }
+        ~thread_specific_ptr()
+        {
+            detail::set_tss_data(this,boost::shared_ptr<detail::tss_cleanup_function>(),0,true);
+        }
+
+        T* get() const
+        {
+            return static_cast<T*>(detail::get_tss_data(this));
+        }
+        T* operator->() const
+        {
+            return get();
+        }
+        T& operator*() const
+        {
+            return *get();
+        }
+        T* release()
+        {
+            T* const temp=get();
+            detail::set_tss_data(this,boost::shared_ptr<detail::tss_cleanup_function>(),0,false);
+            return temp;
+        }
+        void reset(T* new_value=0)
+        {
+            T* const current_value=get();
+            if(current_value!=new_value)
+            {
+                detail::set_tss_data(this,cleanup,new_value,true);
+            }
+        }
+    };
+}
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif
Modified: trunk/libs/thread/test/test_tss.cpp
==============================================================================
--- trunk/libs/thread/test/test_tss.cpp	(original)
+++ trunk/libs/thread/test/test_tss.cpp	2009-05-29 06:57:39 EDT (Fri, 29 May 2009)
@@ -310,6 +310,26 @@
     timed_test(&do_test_tss_does_no_cleanup_with_null_cleanup_function, 2);
 }
 
+void thread_with_local_tss_ptr()
+{
+    {
+        boost::thread_specific_ptr<Dummy> local_tss(tss_custom_cleanup);
+
+        local_tss.reset(new Dummy);
+    }
+    BOOST_CHECK(tss_cleanup_called);
+    tss_cleanup_called=false;
+}
+
+
+void test_tss_does_not_call_cleanup_after_ptr_destroyed()
+{
+    boost::thread t(thread_with_local_tss_ptr);
+    t.join();
+    BOOST_CHECK(!tss_cleanup_called);
+}
+
+
 boost::unit_test_framework::test_suite* init_unit_test_suite(int, char*[])
 {
     boost::unit_test_framework::test_suite* test =
@@ -319,6 +339,7 @@
     test->add(BOOST_TEST_CASE(test_tss_with_custom_cleanup));
     test->add(BOOST_TEST_CASE(test_tss_does_no_cleanup_after_release));
     test->add(BOOST_TEST_CASE(test_tss_does_no_cleanup_with_null_cleanup_function));
+    test->add(BOOST_TEST_CASE(test_tss_does_not_call_cleanup_after_ptr_destroyed));
 
     return test;
 }