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