]> git.sesse.net Git - casparcg/blob - dependencies/boost/boost/thread/tss.hpp
Manually merged pull request #222
[casparcg] / dependencies / boost / boost / thread / tss.hpp
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
14 namespace 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         T& 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