1 // 2 // detail/win_thread.hpp 3 // ~~~~~~~~~~~~~~~~~~~~~ 4 // 5 // Copyright (c) 2003-2021 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 11 #ifndef BOOST_ASIO_DETAIL_WIN_THREAD_HPP 12 #define BOOST_ASIO_DETAIL_WIN_THREAD_HPP 13 14 #if defined(_MSC_VER) && (_MSC_VER >= 1200) 15 # pragma once 16 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) 17 18 #include <boost/asio/detail/config.hpp> 19 20 #if defined(BOOST_ASIO_WINDOWS) \ 21 && !defined(BOOST_ASIO_WINDOWS_APP) \ 22 && !defined(UNDER_CE) 23 24 #include <cstddef> 25 #include <boost/asio/detail/noncopyable.hpp> 26 #include <boost/asio/detail/socket_types.hpp> 27 28 #include <boost/asio/detail/push_options.hpp> 29 30 namespace boost { 31 namespace asio { 32 namespace detail { 33 34 BOOST_ASIO_DECL unsigned int __stdcall win_thread_function(void* arg); 35 36 #if defined(WINVER) && (WINVER < 0x0500) 37 BOOST_ASIO_DECL void __stdcall apc_function(ULONG data); 38 #else 39 BOOST_ASIO_DECL void __stdcall apc_function(ULONG_PTR data); 40 #endif 41 42 template <typename T> 43 class win_thread_base 44 { 45 public: terminate_threads()46 static bool terminate_threads() 47 { 48 return ::InterlockedExchangeAdd(&terminate_threads_, 0) != 0; 49 } 50 set_terminate_threads(bool b)51 static void set_terminate_threads(bool b) 52 { 53 ::InterlockedExchange(&terminate_threads_, b ? 1 : 0); 54 } 55 56 private: 57 static long terminate_threads_; 58 }; 59 60 template <typename T> 61 long win_thread_base<T>::terminate_threads_ = 0; 62 63 class win_thread 64 : private noncopyable, 65 public win_thread_base<win_thread> 66 { 67 public: 68 // Constructor. 69 template <typename Function> win_thread(Function f,unsigned int stack_size=0)70 win_thread(Function f, unsigned int stack_size = 0) 71 : thread_(0), 72 exit_event_(0) 73 { 74 start_thread(new func<Function>(f), stack_size); 75 } 76 77 // Destructor. 78 BOOST_ASIO_DECL ~win_thread(); 79 80 // Wait for the thread to exit. 81 BOOST_ASIO_DECL void join(); 82 83 // Get number of CPUs. 84 BOOST_ASIO_DECL static std::size_t hardware_concurrency(); 85 86 private: 87 friend BOOST_ASIO_DECL unsigned int __stdcall win_thread_function(void* arg); 88 89 #if defined(WINVER) && (WINVER < 0x0500) 90 friend BOOST_ASIO_DECL void __stdcall apc_function(ULONG); 91 #else 92 friend BOOST_ASIO_DECL void __stdcall apc_function(ULONG_PTR); 93 #endif 94 95 class func_base 96 { 97 public: ~func_base()98 virtual ~func_base() {} 99 virtual void run() = 0; 100 ::HANDLE entry_event_; 101 ::HANDLE exit_event_; 102 }; 103 104 struct auto_func_base_ptr 105 { 106 func_base* ptr; ~auto_func_base_ptrboost::asio::detail::win_thread::auto_func_base_ptr107 ~auto_func_base_ptr() { delete ptr; } 108 }; 109 110 template <typename Function> 111 class func 112 : public func_base 113 { 114 public: func(Function f)115 func(Function f) 116 : f_(f) 117 { 118 } 119 run()120 virtual void run() 121 { 122 f_(); 123 } 124 125 private: 126 Function f_; 127 }; 128 129 BOOST_ASIO_DECL void start_thread(func_base* arg, unsigned int stack_size); 130 131 ::HANDLE thread_; 132 ::HANDLE exit_event_; 133 }; 134 135 } // namespace detail 136 } // namespace asio 137 } // namespace boost 138 139 #include <boost/asio/detail/pop_options.hpp> 140 141 #if defined(BOOST_ASIO_HEADER_ONLY) 142 # include <boost/asio/detail/impl/win_thread.ipp> 143 #endif // defined(BOOST_ASIO_HEADER_ONLY) 144 145 #endif // defined(BOOST_ASIO_WINDOWS) 146 // && !defined(BOOST_ASIO_WINDOWS_APP) 147 // && !defined(UNDER_CE) 148 149 #endif // BOOST_ASIO_DETAIL_WIN_THREAD_HPP 150