First public contribution.
1 // Copyright (C) 2001-2003 William E. Kempf
2 // Copyright (C) 2006 Roland Schwarz
4 // Distributed under the Boost Software License, Version 1.0. (See accompanying
5 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7 #ifndef BOOST_TSS_WEK070601_HPP
8 #define BOOST_TSS_WEK070601_HPP
10 #include <boost/thread/detail/config.hpp>
12 #include <boost/utility.hpp>
13 #include <boost/function.hpp>
14 #include <boost/thread/exceptions.hpp>
16 #if defined(BOOST_HAS_PTHREADS)
18 #elif defined(BOOST_HAS_MPTASKS)
19 # include <Multiprocessing.h>
24 // disable warnings about non dll import
25 // see: http://www.boost.org/more/separate_compilation.html#dlls
27 # pragma warning(push)
28 # pragma warning(disable: 4251 4231 4660 4275)
33 class BOOST_THREAD_DECL tss : private noncopyable
36 tss(boost::function1<void, void*>* pcleanup) {
37 if (pcleanup == 0) throw boost::thread_resource_error();
45 throw boost::thread_resource_error();
51 void set(void* value);
52 void cleanup(void* p);
55 unsigned int m_slot; //This is a "pseudo-slot", not a native slot
57 void init(boost::function1<void, void*>* pcleanup);
60 #if defined(BOOST_HAS_MPTASKS)
61 void thread_cleanup();
68 tss_adapter(const F& cleanup) : m_cleanup(cleanup) { }
69 void operator()(void* p) { m_cleanup(static_cast<T*>(p)); }
70 boost::function1<void, T*> m_cleanup;
76 class thread_specific_ptr : private noncopyable
80 : m_tss(new boost::function1<void, void*>(
81 boost::detail::tss_adapter<T>(
82 &thread_specific_ptr<T>::cleanup)))
85 thread_specific_ptr(void (*clean)(T*))
86 : m_tss(new boost::function1<void, void*>(
87 boost::detail::tss_adapter<T>(clean)))
90 ~thread_specific_ptr() { reset(); }
92 T* get() const { return static_cast<T*>(m_tss.get()); }
93 T* operator->() const { return get(); }
94 T& operator*() const { return *get(); }
95 T* release() { T* temp = get(); if (temp) m_tss.set(0); return temp; }
101 if (cur) m_tss.cleanup(cur);
105 static void cleanup(T* p) { delete p; }
110 # pragma warning(pop)
115 #endif //BOOST_TSS_WEK070601_HPP
119 // WEKEMPF Initial version.
121 // Added interface to set specific cleanup handlers.
122 // Removed TLS slot limits from most implementations.
123 // 22 Mar 04 GlassfordM for WEKEMPF
124 // Fixed: thread_specific_ptr::reset() doesn't check error returned
125 // by tss::set(); tss::set() now throws if it fails.
126 // Fixed: calling thread_specific_ptr::reset() or
127 // thread_specific_ptr::release() causes double-delete: once on
128 // reset()/release() and once on ~thread_specific_ptr().