/Src/Dependencies/Boost/boost/thread/win32/thread_data.hpp

http://hadesmem.googlecode.com/ · C++ Header · 183 lines · 149 code · 30 blank · 4 comment · 5 complexity · 2b8fa54c8993812f3e2a0fb46e228554 MD5 · raw file

  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. #include <boost/thread/detail/config.hpp>
  8. #include <boost/intrusive_ptr.hpp>
  9. #include <boost/thread/thread_time.hpp>
  10. #include "thread_primitives.hpp"
  11. #include "thread_heap_alloc.hpp"
  12. #include <boost/config/abi_prefix.hpp>
  13. namespace boost
  14. {
  15. namespace detail
  16. {
  17. struct thread_exit_callback_node;
  18. struct tss_data_node;
  19. struct thread_data_base;
  20. void intrusive_ptr_add_ref(thread_data_base * p);
  21. void intrusive_ptr_release(thread_data_base * p);
  22. struct thread_data_base
  23. {
  24. long count;
  25. detail::win32::handle_manager thread_handle;
  26. detail::win32::handle_manager interruption_handle;
  27. boost::detail::thread_exit_callback_node* thread_exit_callbacks;
  28. boost::detail::tss_data_node* tss_data;
  29. bool interruption_enabled;
  30. unsigned id;
  31. thread_data_base():
  32. count(0),thread_handle(detail::win32::invalid_handle_value),
  33. interruption_handle(create_anonymous_event(detail::win32::manual_reset_event,detail::win32::event_initially_reset)),
  34. thread_exit_callbacks(0),tss_data(0),
  35. interruption_enabled(true),
  36. id(0)
  37. {}
  38. virtual ~thread_data_base()
  39. {}
  40. friend void intrusive_ptr_add_ref(thread_data_base * p)
  41. {
  42. BOOST_INTERLOCKED_INCREMENT(&p->count);
  43. }
  44. friend void intrusive_ptr_release(thread_data_base * p)
  45. {
  46. if(!BOOST_INTERLOCKED_DECREMENT(&p->count))
  47. {
  48. detail::heap_delete(p);
  49. }
  50. }
  51. void interrupt()
  52. {
  53. BOOST_VERIFY(detail::win32::SetEvent(interruption_handle)!=0);
  54. }
  55. typedef detail::win32::handle native_handle_type;
  56. virtual void run()=0;
  57. };
  58. typedef boost::intrusive_ptr<detail::thread_data_base> thread_data_ptr;
  59. struct timeout
  60. {
  61. unsigned long start;
  62. uintmax_t milliseconds;
  63. bool relative;
  64. boost::system_time abs_time;
  65. static unsigned long const max_non_infinite_wait=0xfffffffe;
  66. timeout(uintmax_t milliseconds_):
  67. start(win32::GetTickCount()),
  68. milliseconds(milliseconds_),
  69. relative(true),
  70. abs_time(boost::get_system_time())
  71. {}
  72. timeout(boost::system_time const& abs_time_):
  73. start(win32::GetTickCount()),
  74. milliseconds(0),
  75. relative(false),
  76. abs_time(abs_time_)
  77. {}
  78. struct remaining_time
  79. {
  80. bool more;
  81. unsigned long milliseconds;
  82. remaining_time(uintmax_t remaining):
  83. more(remaining>max_non_infinite_wait),
  84. milliseconds(more?max_non_infinite_wait:(unsigned long)remaining)
  85. {}
  86. };
  87. remaining_time remaining_milliseconds() const
  88. {
  89. if(is_sentinel())
  90. {
  91. return remaining_time(win32::infinite);
  92. }
  93. else if(relative)
  94. {
  95. unsigned long const now=win32::GetTickCount();
  96. unsigned long const elapsed=now-start;
  97. return remaining_time((elapsed<milliseconds)?(milliseconds-elapsed):0);
  98. }
  99. else
  100. {
  101. system_time const now=get_system_time();
  102. if(abs_time<=now)
  103. {
  104. return remaining_time(0);
  105. }
  106. return remaining_time((abs_time-now).total_milliseconds()+1);
  107. }
  108. }
  109. bool is_sentinel() const
  110. {
  111. return milliseconds==~uintmax_t(0);
  112. }
  113. static timeout sentinel()
  114. {
  115. return timeout(sentinel_type());
  116. }
  117. private:
  118. struct sentinel_type
  119. {};
  120. explicit timeout(sentinel_type):
  121. start(0),milliseconds(~uintmax_t(0)),relative(true)
  122. {}
  123. };
  124. inline uintmax_t pin_to_zero(intmax_t value)
  125. {
  126. return (value<0)?0u:(uintmax_t)value;
  127. }
  128. }
  129. namespace this_thread
  130. {
  131. void BOOST_THREAD_DECL yield();
  132. bool BOOST_THREAD_DECL interruptible_wait(detail::win32::handle handle_to_wait_for,detail::timeout target_time);
  133. inline void interruptible_wait(uintmax_t milliseconds)
  134. {
  135. interruptible_wait(detail::win32::invalid_handle_value,milliseconds);
  136. }
  137. inline void interruptible_wait(system_time const& abs_time)
  138. {
  139. interruptible_wait(detail::win32::invalid_handle_value,abs_time);
  140. }
  141. template<typename TimeDuration>
  142. inline void sleep(TimeDuration const& rel_time)
  143. {
  144. interruptible_wait(detail::pin_to_zero(rel_time.total_milliseconds()));
  145. }
  146. inline void sleep(system_time const& abs_time)
  147. {
  148. interruptible_wait(abs_time);
  149. }
  150. }
  151. }
  152. #include <boost/config/abi_suffix.hpp>
  153. #endif