1//
2// detail/initiate_post.hpp
3// ~~~~~~~~~~~~~~~~~~~~~~~~
4//
5// Copyright (c) 2003-2024 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_INITIATE_POST_HPP
12#define BOOST_ASIO_DETAIL_INITIATE_POST_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>
22#include <boost/asio/execution/allocator.hpp>
23#include <boost/asio/execution/blocking.hpp>
24#include <boost/asio/execution/relationship.hpp>
25#include <boost/asio/prefer.hpp>
26#include <boost/asio/require.hpp>
27
28#include <boost/asio/detail/push_options.hpp>
29
30namespace boost {
31namespace asio {
32namespace detail {
33
34class initiate_post
35{
36public:
37 template <typename CompletionHandler>
38 void operator()(CompletionHandler&& handler,
39 enable_if_t<
40 execution::is_executor<
41 associated_executor_t<decay_t<CompletionHandler>>
42 >::value
43 >* = 0) const
44 {
45 associated_executor_t<decay_t<CompletionHandler>> ex(
46 (get_associated_executor)(handler));
47
48 associated_allocator_t<decay_t<CompletionHandler>> alloc(
49 (get_associated_allocator)(handler));
50
51 boost::asio::prefer(
52 boost::asio::require(ex, execution::blocking.never),
53 execution::relationship.fork,
54 execution::allocator(alloc)
55 ).execute(
56 boost::asio::detail::bind_handler(
57 static_cast<CompletionHandler&&>(handler)));
58 }
59
60 template <typename CompletionHandler>
61 void operator()(CompletionHandler&& handler,
62 enable_if_t<
63 !execution::is_executor<
64 associated_executor_t<decay_t<CompletionHandler>>
65 >::value
66 >* = 0) const
67 {
68 associated_executor_t<decay_t<CompletionHandler>> ex(
69 (get_associated_executor)(handler));
70
71 associated_allocator_t<decay_t<CompletionHandler>> alloc(
72 (get_associated_allocator)(handler));
73
74 ex.post(boost::asio::detail::bind_handler(
75 static_cast<CompletionHandler&&>(handler)), alloc);
76 }
77};
78
79template <typename Executor>
80class initiate_post_with_executor
81{
82public:
83 typedef Executor executor_type;
84
85 explicit initiate_post_with_executor(const Executor& ex)
86 : ex_(ex)
87 {
88 }
89
90 executor_type get_executor() const noexcept
91 {
92 return ex_;
93 }
94
95 template <typename CompletionHandler>
96 void operator()(CompletionHandler&& handler,
97 enable_if_t<
98 execution::is_executor<
99 conditional_t<true, executor_type, CompletionHandler>
100 >::value
101 >* = 0,
102 enable_if_t<
103 !detail::is_work_dispatcher_required<
104 decay_t<CompletionHandler>,
105 Executor
106 >::value
107 >* = 0) const
108 {
109 associated_allocator_t<decay_t<CompletionHandler>> alloc(
110 (get_associated_allocator)(handler));
111
112 boost::asio::prefer(
113 boost::asio::require(ex_, execution::blocking.never),
114 execution::relationship.fork,
115 execution::allocator(alloc)
116 ).execute(
117 boost::asio::detail::bind_handler(
118 static_cast<CompletionHandler&&>(handler)));
119 }
120
121 template <typename CompletionHandler>
122 void operator()(CompletionHandler&& handler,
123 enable_if_t<
124 execution::is_executor<
125 conditional_t<true, executor_type, CompletionHandler>
126 >::value
127 >* = 0,
128 enable_if_t<
129 detail::is_work_dispatcher_required<
130 decay_t<CompletionHandler>,
131 Executor
132 >::value
133 >* = 0) const
134 {
135 typedef decay_t<CompletionHandler> handler_t;
136
137 typedef associated_executor_t<handler_t, Executor> handler_ex_t;
138 handler_ex_t handler_ex((get_associated_executor)(handler, ex_));
139
140 associated_allocator_t<handler_t> alloc(
141 (get_associated_allocator)(handler));
142
143 boost::asio::prefer(
144 boost::asio::require(ex_, execution::blocking.never),
145 execution::relationship.fork,
146 execution::allocator(alloc)
147 ).execute(
148 detail::work_dispatcher<handler_t, handler_ex_t>(
149 static_cast<CompletionHandler&&>(handler), handler_ex));
150 }
151
152 template <typename CompletionHandler>
153 void operator()(CompletionHandler&& handler,
154 enable_if_t<
155 !execution::is_executor<
156 conditional_t<true, executor_type, CompletionHandler>
157 >::value
158 >* = 0,
159 enable_if_t<
160 !detail::is_work_dispatcher_required<
161 decay_t<CompletionHandler>,
162 Executor
163 >::value
164 >* = 0) const
165 {
166 associated_allocator_t<decay_t<CompletionHandler>> alloc(
167 (get_associated_allocator)(handler));
168
169 ex_.post(boost::asio::detail::bind_handler(
170 static_cast<CompletionHandler&&>(handler)), alloc);
171 }
172
173 template <typename CompletionHandler>
174 void operator()(CompletionHandler&& handler,
175 enable_if_t<
176 !execution::is_executor<
177 conditional_t<true, executor_type, CompletionHandler>
178 >::value
179 >* = 0,
180 enable_if_t<
181 detail::is_work_dispatcher_required<
182 decay_t<CompletionHandler>,
183 Executor
184 >::value
185 >* = 0) const
186 {
187 typedef decay_t<CompletionHandler> handler_t;
188
189 typedef associated_executor_t<handler_t, Executor> handler_ex_t;
190 handler_ex_t handler_ex((get_associated_executor)(handler, ex_));
191
192 associated_allocator_t<handler_t> alloc(
193 (get_associated_allocator)(handler));
194
195 ex_.post(detail::work_dispatcher<handler_t, handler_ex_t>(
196 static_cast<CompletionHandler&&>(handler), handler_ex), alloc);
197 }
198
199private:
200 Executor ex_;
201};
202
203} // namespace detail
204} // namespace asio
205} // namespace boost
206
207#include <boost/asio/detail/pop_options.hpp>
208
209#endif // BOOST_ASIO_DETAIL_INITIATE_POST_HPP
210

source code of boost/libs/asio/include/boost/asio/detail/initiate_post.hpp