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