1#ifndef BOOST_THREAD_TSS_HPP
2#define BOOST_THREAD_TSS_HPP
3// Distributed under the Boost Software License, Version 1.0. (See
4// accompanying file LICENSE_1_0.txt or copy at
5// http://www.boost.org/LICENSE_1_0.txt)
6// (C) Copyright 2007-8 Anthony Williams
7
8#include <boost/thread/detail/config.hpp>
9#include <boost/shared_ptr.hpp>
10#include <boost/thread/detail/thread_heap_alloc.hpp>
11
12#include <boost/config/abi_prefix.hpp>
13
14namespace boost
15{
16 namespace detail
17 {
18 struct tss_cleanup_function
19 {
20 virtual ~tss_cleanup_function()
21 {}
22
23 virtual void operator()(void* data)=0;
24 };
25
26 BOOST_THREAD_DECL void set_tss_data(void const* key,boost::shared_ptr<tss_cleanup_function> func,void* tss_data,bool cleanup_existing);
27 BOOST_THREAD_DECL void* get_tss_data(void const* key);
28 }
29
30 template <typename T>
31 class thread_specific_ptr
32 {
33 private:
34 thread_specific_ptr(thread_specific_ptr&);
35 thread_specific_ptr& operator=(thread_specific_ptr&);
36
37 struct delete_data:
38 detail::tss_cleanup_function
39 {
40 void operator()(void* data)
41 {
42 delete static_cast<T*>(data);
43 }
44 };
45
46 struct run_custom_cleanup_function:
47 detail::tss_cleanup_function
48 {
49 void (*cleanup_function)(T*);
50
51 explicit run_custom_cleanup_function(void (*cleanup_function_)(T*)):
52 cleanup_function(cleanup_function_)
53 {}
54
55 void operator()(void* data)
56 {
57 cleanup_function(static_cast<T*>(data));
58 }
59 };
60
61
62 boost::shared_ptr<detail::tss_cleanup_function> cleanup;
63
64 public:
65 typedef T element_type;
66
67 thread_specific_ptr():
68 cleanup(detail::heap_new<delete_data>(),detail::do_heap_delete<delete_data>())
69 {}
70 explicit thread_specific_ptr(void (*func_)(T*))
71 {
72 if(func_)
73 {
74 cleanup.reset(detail::heap_new<run_custom_cleanup_function>(func_),detail::do_heap_delete<run_custom_cleanup_function>());
75 }
76 }
77 ~thread_specific_ptr()
78 {
79 detail::set_tss_data(this,boost::shared_ptr<detail::tss_cleanup_function>(),0,true);
80 }
81
82 T* get() const
83 {
84 return static_cast<T*>(detail::get_tss_data(this));
85 }
86 T* operator->() const
87 {
88 return get();
89 }
90 typename boost::detail::sp_dereference< T >::type operator*() const
91 {
92 return *get();
93 }
94 T* release()
95 {
96 T* const temp=get();
97 detail::set_tss_data(this,boost::shared_ptr<detail::tss_cleanup_function>(),0,false);
98 return temp;
99 }
100 void reset(T* new_value=0)
101 {
102 T* const current_value=get();
103 if(current_value!=new_value)
104 {
105 detail::set_tss_data(this,cleanup,new_value,true);
106 }
107 }
108 };
109}
110
111#include <boost/config/abi_suffix.hpp>
112
113#endif
114