]>
Commit | Line | Data |
---|---|---|
b32b8144 FG |
1 | // |
2 | // impl/dispatch.hpp | |
3 | // ~~~~~~~~~~~~~~~~~ | |
4 | // | |
f67539c2 | 5 | // Copyright (c) 2003-2020 Christopher M. Kohlhoff (chris at kohlhoff dot com) |
b32b8144 FG |
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_IMPL_DISPATCH_HPP | |
12 | #define BOOST_ASIO_IMPL_DISPATCH_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 | #include <boost/asio/associated_allocator.hpp> | |
20 | #include <boost/asio/associated_executor.hpp> | |
21 | #include <boost/asio/detail/work_dispatcher.hpp> | |
20effc67 TL |
22 | #include <boost/asio/execution/allocator.hpp> |
23 | #include <boost/asio/execution/blocking.hpp> | |
24 | #include <boost/asio/prefer.hpp> | |
b32b8144 FG |
25 | |
26 | #include <boost/asio/detail/push_options.hpp> | |
27 | ||
28 | namespace boost { | |
29 | namespace asio { | |
92f5a8d4 | 30 | namespace detail { |
b32b8144 | 31 | |
92f5a8d4 | 32 | class initiate_dispatch |
b32b8144 | 33 | { |
92f5a8d4 TL |
34 | public: |
35 | template <typename CompletionHandler> | |
20effc67 TL |
36 | void operator()(BOOST_ASIO_MOVE_ARG(CompletionHandler) handler, |
37 | typename enable_if< | |
38 | execution::is_executor< | |
39 | typename associated_executor< | |
40 | typename decay<CompletionHandler>::type | |
41 | >::type | |
42 | >::value | |
43 | >::type* = 0) const | |
92f5a8d4 | 44 | { |
20effc67 | 45 | typedef typename decay<CompletionHandler>::type handler_t; |
b32b8144 | 46 | |
20effc67 | 47 | typename associated_executor<handler_t>::type ex( |
92f5a8d4 | 48 | (get_associated_executor)(handler)); |
b32b8144 | 49 | |
20effc67 TL |
50 | typename associated_allocator<handler_t>::type alloc( |
51 | (get_associated_allocator)(handler)); | |
52 | ||
53 | execution::execute( | |
54 | boost::asio::prefer(ex, | |
55 | execution::blocking.possibly, | |
56 | execution::allocator(alloc)), | |
57 | BOOST_ASIO_MOVE_CAST(CompletionHandler)(handler)); | |
58 | } | |
59 | ||
60 | template <typename CompletionHandler> | |
61 | void operator()(BOOST_ASIO_MOVE_ARG(CompletionHandler) handler, | |
62 | typename enable_if< | |
63 | !execution::is_executor< | |
64 | typename associated_executor< | |
65 | typename decay<CompletionHandler>::type | |
66 | >::type | |
67 | >::value | |
68 | >::type* = 0) const | |
69 | { | |
70 | typedef typename decay<CompletionHandler>::type handler_t; | |
71 | ||
72 | typename associated_executor<handler_t>::type ex( | |
73 | (get_associated_executor)(handler)); | |
74 | ||
75 | typename associated_allocator<handler_t>::type alloc( | |
92f5a8d4 | 76 | (get_associated_allocator)(handler)); |
b32b8144 | 77 | |
92f5a8d4 TL |
78 | ex.dispatch(BOOST_ASIO_MOVE_CAST(CompletionHandler)(handler), alloc); |
79 | } | |
80 | }; | |
b32b8144 | 81 | |
92f5a8d4 TL |
82 | template <typename Executor> |
83 | class initiate_dispatch_with_executor | |
84 | { | |
85 | public: | |
86 | typedef Executor executor_type; | |
b32b8144 | 87 | |
92f5a8d4 TL |
88 | explicit initiate_dispatch_with_executor(const Executor& ex) |
89 | : ex_(ex) | |
90 | { | |
91 | } | |
b32b8144 | 92 | |
92f5a8d4 TL |
93 | executor_type get_executor() const BOOST_ASIO_NOEXCEPT |
94 | { | |
95 | return ex_; | |
96 | } | |
97 | ||
98 | template <typename CompletionHandler> | |
20effc67 TL |
99 | void operator()(BOOST_ASIO_MOVE_ARG(CompletionHandler) handler, |
100 | typename enable_if< | |
101 | execution::is_executor< | |
102 | typename conditional<true, executor_type, CompletionHandler>::type | |
103 | >::value | |
104 | && | |
105 | !detail::is_work_dispatcher_required< | |
106 | typename decay<CompletionHandler>::type, | |
107 | Executor | |
108 | >::value | |
109 | >::type* = 0) const | |
92f5a8d4 | 110 | { |
20effc67 TL |
111 | typedef typename decay<CompletionHandler>::type handler_t; |
112 | ||
113 | typename associated_allocator<handler_t>::type alloc( | |
114 | (get_associated_allocator)(handler)); | |
115 | ||
116 | execution::execute( | |
117 | boost::asio::prefer(ex_, | |
118 | execution::blocking.possibly, | |
119 | execution::allocator(alloc)), | |
120 | BOOST_ASIO_MOVE_CAST(CompletionHandler)(handler)); | |
121 | } | |
122 | ||
123 | template <typename CompletionHandler> | |
124 | void operator()(BOOST_ASIO_MOVE_ARG(CompletionHandler) handler, | |
125 | typename enable_if< | |
126 | execution::is_executor< | |
127 | typename conditional<true, executor_type, CompletionHandler>::type | |
128 | >::value | |
129 | && | |
130 | detail::is_work_dispatcher_required< | |
131 | typename decay<CompletionHandler>::type, | |
132 | Executor | |
133 | >::value | |
134 | >::type* = 0) const | |
135 | { | |
136 | typedef typename decay<CompletionHandler>::type handler_t; | |
137 | ||
138 | typedef typename associated_executor< | |
139 | handler_t, Executor>::type handler_ex_t; | |
140 | handler_ex_t handler_ex((get_associated_executor)(handler, ex_)); | |
92f5a8d4 | 141 | |
20effc67 | 142 | typename associated_allocator<handler_t>::type alloc( |
92f5a8d4 | 143 | (get_associated_allocator)(handler)); |
b32b8144 | 144 | |
20effc67 TL |
145 | execution::execute( |
146 | boost::asio::prefer(ex_, | |
147 | execution::blocking.possibly, | |
148 | execution::allocator(alloc)), | |
149 | detail::work_dispatcher<handler_t, handler_ex_t>( | |
150 | BOOST_ASIO_MOVE_CAST(CompletionHandler)(handler), handler_ex)); | |
151 | } | |
152 | ||
153 | template <typename CompletionHandler> | |
154 | void operator()(BOOST_ASIO_MOVE_ARG(CompletionHandler) handler, | |
155 | typename enable_if< | |
156 | !execution::is_executor< | |
157 | typename conditional<true, executor_type, CompletionHandler>::type | |
158 | >::value | |
159 | && | |
160 | !detail::is_work_dispatcher_required< | |
161 | typename decay<CompletionHandler>::type, | |
162 | Executor | |
163 | >::value | |
164 | >::type* = 0) const | |
165 | { | |
166 | typedef typename decay<CompletionHandler>::type handler_t; | |
167 | ||
168 | typename associated_allocator<handler_t>::type alloc( | |
169 | (get_associated_allocator)(handler)); | |
170 | ||
171 | ex_.dispatch(BOOST_ASIO_MOVE_CAST(CompletionHandler)(handler), alloc); | |
172 | } | |
173 | ||
174 | template <typename CompletionHandler> | |
175 | void operator()(BOOST_ASIO_MOVE_ARG(CompletionHandler) handler, | |
176 | typename enable_if< | |
177 | !execution::is_executor< | |
178 | typename conditional<true, executor_type, CompletionHandler>::type | |
179 | >::value | |
180 | && | |
181 | detail::is_work_dispatcher_required< | |
182 | typename decay<CompletionHandler>::type, | |
183 | Executor | |
184 | >::value | |
185 | >::type* = 0) const | |
186 | { | |
187 | typedef typename decay<CompletionHandler>::type handler_t; | |
188 | ||
189 | typedef typename associated_executor< | |
190 | handler_t, Executor>::type handler_ex_t; | |
191 | handler_ex_t handler_ex((get_associated_executor)(handler, ex_)); | |
192 | ||
193 | typename associated_allocator<handler_t>::type alloc( | |
194 | (get_associated_allocator)(handler)); | |
195 | ||
196 | ex_.dispatch(detail::work_dispatcher<handler_t, handler_ex_t>( | |
197 | BOOST_ASIO_MOVE_CAST(CompletionHandler)(handler), | |
198 | handler_ex), alloc); | |
92f5a8d4 | 199 | } |
b32b8144 | 200 | |
92f5a8d4 TL |
201 | private: |
202 | Executor ex_; | |
203 | }; | |
b32b8144 | 204 | |
92f5a8d4 | 205 | } // namespace detail |
b32b8144 | 206 | |
92f5a8d4 TL |
207 | template <BOOST_ASIO_COMPLETION_TOKEN_FOR(void()) CompletionToken> |
208 | BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void()) dispatch( | |
209 | BOOST_ASIO_MOVE_ARG(CompletionToken) token) | |
210 | { | |
211 | return async_initiate<CompletionToken, void()>( | |
212 | detail::initiate_dispatch(), token); | |
213 | } | |
214 | ||
215 | template <typename Executor, | |
216 | BOOST_ASIO_COMPLETION_TOKEN_FOR(void()) CompletionToken> | |
217 | BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void()) dispatch( | |
218 | const Executor& ex, BOOST_ASIO_MOVE_ARG(CompletionToken) token, | |
20effc67 TL |
219 | typename enable_if< |
220 | execution::is_executor<Executor>::value || is_executor<Executor>::value | |
221 | >::type*) | |
92f5a8d4 TL |
222 | { |
223 | return async_initiate<CompletionToken, void()>( | |
224 | detail::initiate_dispatch_with_executor<Executor>(ex), token); | |
b32b8144 FG |
225 | } |
226 | ||
92f5a8d4 TL |
227 | template <typename ExecutionContext, |
228 | BOOST_ASIO_COMPLETION_TOKEN_FOR(void()) CompletionToken> | |
229 | inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void()) dispatch( | |
b32b8144 FG |
230 | ExecutionContext& ctx, BOOST_ASIO_MOVE_ARG(CompletionToken) token, |
231 | typename enable_if<is_convertible< | |
232 | ExecutionContext&, execution_context&>::value>::type*) | |
233 | { | |
20effc67 TL |
234 | return async_initiate<CompletionToken, void()>( |
235 | detail::initiate_dispatch_with_executor< | |
236 | typename ExecutionContext::executor_type>( | |
237 | ctx.get_executor()), token); | |
b32b8144 FG |
238 | } |
239 | ||
240 | } // namespace asio | |
241 | } // namespace boost | |
242 | ||
243 | #include <boost/asio/detail/pop_options.hpp> | |
244 | ||
245 | #endif // BOOST_ASIO_IMPL_DISPATCH_HPP |