win_thread.hpp 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. //
  2. // detail/win_thread.hpp
  3. // ~~~~~~~~~~~~~~~~~~~~~
  4. //
  5. // Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com)
  6. //
  7. // Distributed under the Boost Software License, Version 1.0. (See accompanying
  8. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  9. //
  10. #ifndef ASIO_DETAIL_WIN_THREAD_HPP
  11. #define ASIO_DETAIL_WIN_THREAD_HPP
  12. #if defined(_MSC_VER) && (_MSC_VER >= 1200)
  13. # pragma once
  14. #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
  15. #include "asio/detail/config.hpp"
  16. #if defined(ASIO_WINDOWS) && !defined(UNDER_CE)
  17. #include "asio/detail/noncopyable.hpp"
  18. #include "asio/detail/socket_types.hpp"
  19. #include "asio/detail/push_options.hpp"
  20. namespace asio {
  21. namespace detail {
  22. ASIO_DECL unsigned int __stdcall win_thread_function(void* arg);
  23. #if defined(WINVER) && (WINVER < 0x0500)
  24. ASIO_DECL void __stdcall apc_function(ULONG data);
  25. #else
  26. ASIO_DECL void __stdcall apc_function(ULONG_PTR data);
  27. #endif
  28. template <typename T>
  29. class win_thread_base
  30. {
  31. public:
  32. static bool terminate_threads()
  33. {
  34. return ::InterlockedExchangeAdd(&terminate_threads_, 0) != 0;
  35. }
  36. static void set_terminate_threads(bool b)
  37. {
  38. ::InterlockedExchange(&terminate_threads_, b ? 1 : 0);
  39. }
  40. private:
  41. static long terminate_threads_;
  42. };
  43. template <typename T>
  44. long win_thread_base<T>::terminate_threads_ = 0;
  45. class win_thread
  46. : private noncopyable,
  47. public win_thread_base<win_thread>
  48. {
  49. public:
  50. // Constructor.
  51. template <typename Function>
  52. win_thread(Function f, unsigned int stack_size = 0)
  53. : thread_(0),
  54. exit_event_(0)
  55. {
  56. start_thread(new func<Function>(f), stack_size);
  57. }
  58. // Destructor.
  59. ASIO_DECL ~win_thread();
  60. // Wait for the thread to exit.
  61. ASIO_DECL void join();
  62. private:
  63. friend ASIO_DECL unsigned int __stdcall win_thread_function(void* arg);
  64. #if defined(WINVER) && (WINVER < 0x0500)
  65. friend ASIO_DECL void __stdcall apc_function(ULONG);
  66. #else
  67. friend ASIO_DECL void __stdcall apc_function(ULONG_PTR);
  68. #endif
  69. class func_base
  70. {
  71. public:
  72. virtual ~func_base() {}
  73. virtual void run() = 0;
  74. ::HANDLE entry_event_;
  75. ::HANDLE exit_event_;
  76. };
  77. struct auto_func_base_ptr
  78. {
  79. func_base* ptr;
  80. ~auto_func_base_ptr() { delete ptr; }
  81. };
  82. template <typename Function>
  83. class func
  84. : public func_base
  85. {
  86. public:
  87. func(Function f)
  88. : f_(f)
  89. {
  90. }
  91. virtual void run()
  92. {
  93. f_();
  94. }
  95. private:
  96. Function f_;
  97. };
  98. ASIO_DECL void start_thread(func_base* arg, unsigned int stack_size);
  99. ::HANDLE thread_;
  100. ::HANDLE exit_event_;
  101. };
  102. } // namespace detail
  103. } // namespace asio
  104. #include "asio/detail/pop_options.hpp"
  105. #if defined(ASIO_HEADER_ONLY)
  106. # include "asio/detail/impl/win_thread.ipp"
  107. #endif // defined(ASIO_HEADER_ONLY)
  108. #endif // defined(ASIO_WINDOWS) && !defined(UNDER_CE)
  109. #endif // ASIO_DETAIL_WIN_THREAD_HPP