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