]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/thread/win32/thread_data.hpp
update sources to ceph Nautilus 14.2.1
[ceph.git] / ceph / src / boost / boost / thread / win32 / thread_data.hpp
1 #ifndef BOOST_THREAD_PTHREAD_THREAD_DATA_HPP
2 #define BOOST_THREAD_PTHREAD_THREAD_DATA_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 2008 Anthony Williams
7 // (C) Copyright 2011-2012 Vicente J. Botet Escriba
8
9 #include <boost/thread/detail/config.hpp>
10 #include <boost/thread/thread_time.hpp>
11 #include <boost/thread/win32/thread_primitives.hpp>
12 #include <boost/thread/win32/thread_heap_alloc.hpp>
13 #include <boost/thread/detail/platform_time.hpp>
14
15 #include <boost/predef/platform.h>
16
17 #include <boost/intrusive_ptr.hpp>
18 #ifdef BOOST_THREAD_USES_CHRONO
19 #include <boost/chrono/system_clocks.hpp>
20 #endif
21
22 #include <map>
23 #include <vector>
24 #include <utility>
25
26 #include <boost/config/abi_prefix.hpp>
27
28 #ifdef BOOST_MSVC
29 #pragma warning(push)
30 #pragma warning(disable:4251)
31 #endif
32
33 namespace boost
34 {
35 class condition_variable;
36 class mutex;
37
38 class thread_attributes {
39 public:
40 thread_attributes() BOOST_NOEXCEPT {
41 val_.stack_size = 0;
42 //val_.lpThreadAttributes=0;
43 }
44 ~thread_attributes() {
45 }
46 // stack size
47 void set_stack_size(std::size_t size) BOOST_NOEXCEPT {
48 val_.stack_size = size;
49 }
50
51 std::size_t get_stack_size() const BOOST_NOEXCEPT {
52 return val_.stack_size;
53 }
54
55 //void set_security(LPSECURITY_ATTRIBUTES lpThreadAttributes)
56 //{
57 // val_.lpThreadAttributes=lpThreadAttributes;
58 //}
59 //LPSECURITY_ATTRIBUTES get_security()
60 //{
61 // return val_.lpThreadAttributes;
62 //}
63
64 struct win_attrs {
65 std::size_t stack_size;
66 //LPSECURITY_ATTRIBUTES lpThreadAttributes;
67 };
68 typedef win_attrs native_handle_type;
69 native_handle_type* native_handle() {return &val_;}
70 const native_handle_type* native_handle() const {return &val_;}
71
72 private:
73 win_attrs val_;
74 };
75
76 namespace detail
77 {
78 struct shared_state_base;
79 struct tss_cleanup_function;
80 struct thread_exit_callback_node;
81 struct tss_data_node
82 {
83 boost::shared_ptr<boost::detail::tss_cleanup_function> func;
84 void* value;
85
86 tss_data_node(boost::shared_ptr<boost::detail::tss_cleanup_function> func_,
87 void* value_):
88 func(func_),value(value_)
89 {}
90 };
91
92 struct thread_data_base;
93 void intrusive_ptr_add_ref(thread_data_base * p);
94 void intrusive_ptr_release(thread_data_base * p);
95
96 struct BOOST_THREAD_DECL thread_data_base
97 {
98 long count;
99
100 // Win32 threading APIs are not available in store apps so
101 // use abstraction on top of Windows::System::Threading.
102 #if BOOST_PLAT_WINDOWS_RUNTIME
103 detail::win32::scoped_winrt_thread thread_handle;
104 #else
105 detail::win32::handle_manager thread_handle;
106 #endif
107
108 boost::detail::thread_exit_callback_node* thread_exit_callbacks;
109 unsigned id;
110 std::map<void const*,boost::detail::tss_data_node> tss_data;
111 typedef std::vector<std::pair<condition_variable*, mutex*>
112 //, hidden_allocator<std::pair<condition_variable*, mutex*> >
113 > notify_list_t;
114 notify_list_t notify;
115
116 typedef std::vector<shared_ptr<shared_state_base> > async_states_t;
117 async_states_t async_states_;
118 //#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
119 // These data must be at the end so that the access to the other fields doesn't change
120 // when BOOST_THREAD_PROVIDES_INTERRUPTIONS is defined
121 // Another option is to have them always
122 detail::win32::handle_manager interruption_handle;
123 bool interruption_enabled;
124 //#endif
125
126 thread_data_base():
127 count(0),
128 thread_handle(),
129 thread_exit_callbacks(0),
130 id(0),
131 tss_data(),
132 notify(),
133 async_states_()
134 //#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
135 , interruption_handle(create_anonymous_event(detail::win32::manual_reset_event,detail::win32::event_initially_reset))
136 , interruption_enabled(true)
137 //#endif
138 {}
139 virtual ~thread_data_base();
140
141 friend void intrusive_ptr_add_ref(thread_data_base * p)
142 {
143 BOOST_INTERLOCKED_INCREMENT(&p->count);
144 }
145
146 friend void intrusive_ptr_release(thread_data_base * p)
147 {
148 if(!BOOST_INTERLOCKED_DECREMENT(&p->count))
149 {
150 detail::heap_delete(p);
151 }
152 }
153
154 #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
155 void interrupt()
156 {
157 BOOST_VERIFY(winapi::SetEvent(interruption_handle)!=0);
158 }
159 #endif
160 typedef detail::win32::handle native_handle_type;
161
162 virtual void run()=0;
163
164 virtual void notify_all_at_thread_exit(condition_variable* cv, mutex* m)
165 {
166 notify.push_back(std::pair<condition_variable*, mutex*>(cv, m));
167 }
168
169 void make_ready_at_thread_exit(shared_ptr<shared_state_base> as)
170 {
171 async_states_.push_back(as);
172 }
173
174 };
175 BOOST_THREAD_DECL thread_data_base* get_current_thread_data();
176
177 typedef boost::intrusive_ptr<detail::thread_data_base> thread_data_ptr;
178 }
179
180 namespace this_thread
181 {
182 void BOOST_THREAD_DECL yield() BOOST_NOEXCEPT;
183
184 bool BOOST_THREAD_DECL interruptible_wait(detail::win32::handle handle_to_wait_for, detail::internal_platform_timepoint const &timeout);
185
186 #if defined BOOST_THREAD_USES_DATETIME
187 template<typename TimeDuration>
188 BOOST_SYMBOL_VISIBLE void sleep(TimeDuration const& rel_time)
189 {
190 interruptible_wait(detail::win32::invalid_handle_value, detail::internal_platform_clock::now() + detail::platform_duration(rel_time));
191 }
192
193 inline BOOST_SYMBOL_VISIBLE void sleep(system_time const& abs_time)
194 {
195 const detail::real_platform_timepoint ts(abs_time);
196 detail::platform_duration d(ts - detail::real_platform_clock::now());
197 while (d > detail::platform_duration::zero())
198 {
199 d = (std::min)(d, detail::platform_milliseconds(BOOST_THREAD_POLL_INTERVAL_MILLISECONDS));
200 interruptible_wait(detail::win32::invalid_handle_value, detail::internal_platform_clock::now() + d);
201 d = ts - detail::real_platform_clock::now();
202 }
203 }
204 #endif
205
206 #ifdef BOOST_THREAD_USES_CHRONO
207 template <class Rep, class Period>
208 void sleep_for(const chrono::duration<Rep, Period>& d)
209 {
210 interruptible_wait(detail::win32::invalid_handle_value, detail::internal_platform_clock::now() + detail::platform_duration(d));
211 }
212
213 template <class Duration>
214 void sleep_until(const chrono::time_point<chrono::steady_clock, Duration>& t)
215 {
216 sleep_for(t - chrono::steady_clock::now());
217 }
218
219 template <class Clock, class Duration>
220 void sleep_until(const chrono::time_point<Clock, Duration>& t)
221 {
222 typedef typename common_type<Duration, typename Clock::duration>::type common_duration;
223 common_duration d(t - Clock::now());
224 while (d > common_duration::zero())
225 {
226 d = (std::min)(d, common_duration(chrono::milliseconds(BOOST_THREAD_POLL_INTERVAL_MILLISECONDS)));
227 sleep_for(d);
228 d = t - Clock::now();
229 }
230 }
231 #endif
232
233 namespace no_interruption_point
234 {
235 bool BOOST_THREAD_DECL non_interruptible_wait(detail::win32::handle handle_to_wait_for, detail::internal_platform_timepoint const &timeout);
236
237 #if defined BOOST_THREAD_USES_DATETIME
238 template<typename TimeDuration>
239 BOOST_SYMBOL_VISIBLE void sleep(TimeDuration const& rel_time)
240 {
241 non_interruptible_wait(detail::win32::invalid_handle_value, detail::internal_platform_clock::now() + detail::platform_duration(rel_time));
242 }
243
244 inline BOOST_SYMBOL_VISIBLE void sleep(system_time const& abs_time)
245 {
246 const detail::real_platform_timepoint ts(abs_time);
247 detail::platform_duration d(ts - detail::real_platform_clock::now());
248 while (d > detail::platform_duration::zero())
249 {
250 d = (std::min)(d, detail::platform_milliseconds(BOOST_THREAD_POLL_INTERVAL_MILLISECONDS));
251 non_interruptible_wait(detail::win32::invalid_handle_value, detail::internal_platform_clock::now() + d);
252 d = ts - detail::real_platform_clock::now();
253 }
254 }
255 #endif
256
257 #ifdef BOOST_THREAD_USES_CHRONO
258 template <class Rep, class Period>
259 void sleep_for(const chrono::duration<Rep, Period>& d)
260 {
261 non_interruptible_wait(detail::win32::invalid_handle_value, detail::internal_platform_clock::now() + detail::platform_duration(d));
262 }
263
264 template <class Duration>
265 void sleep_until(const chrono::time_point<chrono::steady_clock, Duration>& t)
266 {
267 sleep_for(t - chrono::steady_clock::now());
268 }
269
270 template <class Clock, class Duration>
271 void sleep_until(const chrono::time_point<Clock, Duration>& t)
272 {
273 typedef typename common_type<Duration, typename Clock::duration>::type common_duration;
274 common_duration d(t - Clock::now());
275 while (d > common_duration::zero())
276 {
277 d = (std::min)(d, common_duration(chrono::milliseconds(BOOST_THREAD_POLL_INTERVAL_MILLISECONDS)));
278 sleep_for(d);
279 d = t - Clock::now();
280 }
281 }
282 #endif
283 }
284 }
285
286 }
287
288 #ifdef BOOST_MSVC
289 #pragma warning(pop)
290 #endif
291
292 #include <boost/config/abi_suffix.hpp>
293
294 #endif