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