]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/thread/include/boost/thread/win32/thread_data.hpp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / thread / include / boost / thread / win32 / thread_data.hpp
CommitLineData
7c673cae
FG
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
14#include <boost/predef/platform.h>
15
16#include <boost/intrusive_ptr.hpp>
17#ifdef BOOST_THREAD_USES_CHRONO
18#include <boost/chrono/system_clocks.hpp>
19#endif
20
21#include <map>
22#include <vector>
23#include <utility>
24
25#include <boost/config/abi_prefix.hpp>
26
27#ifdef BOOST_MSVC
28#pragma warning(push)
29#pragma warning(disable:4251)
30#endif
31
32namespace boost
33{
34 class condition_variable;
35 class mutex;
36
37 class thread_attributes {
38 public:
39 thread_attributes() BOOST_NOEXCEPT {
40 val_.stack_size = 0;
41 //val_.lpThreadAttributes=0;
42 }
43 ~thread_attributes() {
44 }
45 // stack size
46 void set_stack_size(std::size_t size) BOOST_NOEXCEPT {
47 val_.stack_size = size;
48 }
49
50 std::size_t get_stack_size() const BOOST_NOEXCEPT {
51 return val_.stack_size;
52 }
53
54 //void set_security(LPSECURITY_ATTRIBUTES lpThreadAttributes)
55 //{
56 // val_.lpThreadAttributes=lpThreadAttributes;
57 //}
58 //LPSECURITY_ATTRIBUTES get_security()
59 //{
60 // return val_.lpThreadAttributes;
61 //}
62
63 struct win_attrs {
64 std::size_t stack_size;
65 //LPSECURITY_ATTRIBUTES lpThreadAttributes;
66 };
67 typedef win_attrs native_handle_type;
68 native_handle_type* native_handle() {return &val_;}
69 const native_handle_type* native_handle() const {return &val_;}
70
71 private:
72 win_attrs val_;
73 };
74
75 namespace detail
76 {
77 struct shared_state_base;
78 struct tss_cleanup_function;
79 struct thread_exit_callback_node;
80 struct tss_data_node
81 {
82 boost::shared_ptr<boost::detail::tss_cleanup_function> func;
83 void* value;
84
85 tss_data_node(boost::shared_ptr<boost::detail::tss_cleanup_function> func_,
86 void* value_):
87 func(func_),value(value_)
88 {}
89 };
90
91 struct thread_data_base;
92 void intrusive_ptr_add_ref(thread_data_base * p);
93 void intrusive_ptr_release(thread_data_base * p);
94
95 struct BOOST_THREAD_DECL thread_data_base
96 {
97 long count;
98
99 // Win32 threading APIs are not available in store apps so
100 // use abstraction on top of Windows::System::Threading.
101#if BOOST_PLAT_WINDOWS_RUNTIME
102 detail::win32::scoped_winrt_thread thread_handle;
103#else
104 detail::win32::handle_manager thread_handle;
105#endif
106
107 boost::detail::thread_exit_callback_node* thread_exit_callbacks;
108 unsigned id;
109 std::map<void const*,boost::detail::tss_data_node> tss_data;
110 typedef std::vector<std::pair<condition_variable*, mutex*>
111 //, hidden_allocator<std::pair<condition_variable*, mutex*> >
112 > notify_list_t;
113 notify_list_t notify;
114
115 typedef std::vector<shared_ptr<shared_state_base> > async_states_t;
116 async_states_t async_states_;
117//#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
118 // These data must be at the end so that the access to the other fields doesn't change
119 // when BOOST_THREAD_PROVIDES_INTERRUPTIONS is defined
120 // Another option is to have them always
121 detail::win32::handle_manager interruption_handle;
122 bool interruption_enabled;
123//#endif
124
125 thread_data_base():
126 count(0),
127 thread_handle(),
128 thread_exit_callbacks(0),
129 id(0),
130 tss_data(),
131 notify(),
132 async_states_()
133//#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
134 , interruption_handle(create_anonymous_event(detail::win32::manual_reset_event,detail::win32::event_initially_reset))
135 , interruption_enabled(true)
136//#endif
137 {}
138 virtual ~thread_data_base();
139
140 friend void intrusive_ptr_add_ref(thread_data_base * p)
141 {
142 BOOST_INTERLOCKED_INCREMENT(&p->count);
143 }
144
145 friend void intrusive_ptr_release(thread_data_base * p)
146 {
147 if(!BOOST_INTERLOCKED_DECREMENT(&p->count))
148 {
149 detail::heap_delete(p);
150 }
151 }
152
153#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
154 void interrupt()
155 {
156 BOOST_VERIFY(detail::win32::SetEvent(interruption_handle)!=0);
157 }
158#endif
159 typedef detail::win32::handle native_handle_type;
160
161 virtual void run()=0;
162
163 virtual void notify_all_at_thread_exit(condition_variable* cv, mutex* m)
164 {
165 notify.push_back(std::pair<condition_variable*, mutex*>(cv, m));
166 }
167
168 void make_ready_at_thread_exit(shared_ptr<shared_state_base> as)
169 {
170 async_states_.push_back(as);
171 }
172
173 };
174 BOOST_THREAD_DECL thread_data_base* get_current_thread_data();
175
176 typedef boost::intrusive_ptr<detail::thread_data_base> thread_data_ptr;
177
178 struct BOOST_SYMBOL_VISIBLE timeout
179 {
180 win32::ticks_type start;
181 uintmax_t milliseconds;
182 bool relative;
183 boost::system_time abs_time;
184
185 static unsigned long const max_non_infinite_wait=0xfffffffe;
186
187 timeout(uintmax_t milliseconds_):
188 start(win32::GetTickCount64_()()),
189 milliseconds(milliseconds_),
190 relative(true)
191 //,
192 // abs_time(boost::get_system_time())
193 {}
194
195 timeout(boost::system_time const& abs_time_):
196 start(win32::GetTickCount64_()()),
197 milliseconds(0),
198 relative(false),
199 abs_time(abs_time_)
200 {}
201
202 struct BOOST_SYMBOL_VISIBLE remaining_time
203 {
204 bool more;
205 unsigned long milliseconds;
206
207 remaining_time(uintmax_t remaining):
208 more(remaining>max_non_infinite_wait),
209 milliseconds(more?max_non_infinite_wait:(unsigned long)remaining)
210 {}
211 };
212
213 remaining_time remaining_milliseconds() const
214 {
215 if(is_sentinel())
216 {
217 return remaining_time(win32::infinite);
218 }
219 else if(relative)
220 {
221 win32::ticks_type const now=win32::GetTickCount64_()();
222 win32::ticks_type const elapsed=now-start;
223 return remaining_time((elapsed<milliseconds)?(milliseconds-elapsed):0);
224 }
225 else
226 {
227 system_time const now=get_system_time();
228 if(abs_time<=now)
229 {
230 return remaining_time(0);
231 }
232 return remaining_time((abs_time-now).total_milliseconds()+1);
233 }
234 }
235
236 bool is_sentinel() const
237 {
238 return milliseconds==~uintmax_t(0);
239 }
240
241
242 static timeout sentinel()
243 {
244 return timeout(sentinel_type());
245 }
246 private:
247 struct sentinel_type
248 {};
249
250 explicit timeout(sentinel_type):
251 start(0),milliseconds(~uintmax_t(0)),relative(true)
252 {}
253 };
254
255 inline uintmax_t pin_to_zero(intmax_t value)
256 {
257 return (value<0)?0u:(uintmax_t)value;
258 }
259 }
260
261 namespace this_thread
262 {
263 void BOOST_THREAD_DECL yield() BOOST_NOEXCEPT;
264
265 bool BOOST_THREAD_DECL interruptible_wait(detail::win32::handle handle_to_wait_for,detail::timeout target_time);
266 inline void interruptible_wait(uintmax_t milliseconds)
267 {
268 interruptible_wait(detail::win32::invalid_handle_value,milliseconds);
269 }
270 inline BOOST_SYMBOL_VISIBLE void interruptible_wait(system_time const& abs_time)
271 {
272 interruptible_wait(detail::win32::invalid_handle_value,abs_time);
273 }
274 template<typename TimeDuration>
275 inline BOOST_SYMBOL_VISIBLE void sleep(TimeDuration const& rel_time)
276 {
277 interruptible_wait(detail::pin_to_zero(rel_time.total_milliseconds()));
278 }
279 inline BOOST_SYMBOL_VISIBLE void sleep(system_time const& abs_time)
280 {
281 interruptible_wait(abs_time);
282 }
283// #11322 sleep_for() nanoseconds overload will always return too early on windows
284//#ifdef BOOST_THREAD_USES_CHRONO
285// inline void BOOST_SYMBOL_VISIBLE sleep_for(const chrono::nanoseconds& ns)
286// {
287// interruptible_wait(chrono::duration_cast<chrono::milliseconds>(ns).count());
288// }
289//#endif
290 namespace no_interruption_point
291 {
292 bool BOOST_THREAD_DECL non_interruptible_wait(detail::win32::handle handle_to_wait_for,detail::timeout target_time);
293 inline void non_interruptible_wait(uintmax_t milliseconds)
294 {
295 non_interruptible_wait(detail::win32::invalid_handle_value,milliseconds);
296 }
297 inline BOOST_SYMBOL_VISIBLE void non_interruptible_wait(system_time const& abs_time)
298 {
299 non_interruptible_wait(detail::win32::invalid_handle_value,abs_time);
300 }
301 template<typename TimeDuration>
302 inline BOOST_SYMBOL_VISIBLE void sleep(TimeDuration const& rel_time)
303 {
304 non_interruptible_wait(detail::pin_to_zero(rel_time.total_milliseconds()));
305 }
306 inline BOOST_SYMBOL_VISIBLE void sleep(system_time const& abs_time)
307 {
308 non_interruptible_wait(abs_time);
309 }
310// #11322 sleep_for() nanoseconds overload will always return too early on windows
311//#ifdef BOOST_THREAD_USES_CHRONO
312// inline void BOOST_SYMBOL_VISIBLE sleep_for(const chrono::nanoseconds& ns)
313// {
314// non_interruptible_wait(chrono::duration_cast<chrono::milliseconds>(ns).count());
315// }
316//#endif
317 }
318 }
319
320}
321
322#ifdef BOOST_MSVC
323#pragma warning(pop)
324#endif
325
326#include <boost/config/abi_suffix.hpp>
327
328#endif