1//
2// 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_POST_HPP
12#define BOOST_ASIO_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/async_result.hpp>
20#include <boost/asio/detail/initiate_post.hpp>
21#include <boost/asio/detail/type_traits.hpp>
22#include <boost/asio/execution_context.hpp>
23#include <boost/asio/execution/blocking.hpp>
24#include <boost/asio/execution/executor.hpp>
25#include <boost/asio/is_executor.hpp>
26#include <boost/asio/require.hpp>
27
28#include <boost/asio/detail/push_options.hpp>
29
30namespace boost {
31namespace asio {
32
33/// Submits a completion token or function object for execution.
34/**
35 * This function submits an object for execution using the object's associated
36 * executor. The function object is queued for execution, and is never called
37 * from the current thread prior to returning from <tt>post()</tt>.
38 *
39 * The use of @c post(), rather than @ref defer(), indicates the caller's
40 * preference that the function object be eagerly queued for execution.
41 *
42 * @param token The @ref completion_token that will be used to produce a
43 * completion handler. The function signature of the completion handler must be:
44 * @code void handler(); @endcode
45 *
46 * @returns This function returns <tt>async_initiate<NullaryToken,
47 * void()>(Init{}, token)</tt>, where @c Init is a function object type defined
48 * as:
49 *
50 * @code class Init
51 * {
52 * public:
53 * template <typename CompletionHandler>
54 * void operator()(CompletionHandler&& completion_handler) const;
55 * }; @endcode
56 *
57 * The function call operator of @c Init:
58 *
59 * @li Obtains the handler's associated executor object @c ex of type @c Ex by
60 * performing @code auto ex = get_associated_executor(handler); @endcode
61 *
62 * @li Obtains the handler's associated allocator object @c alloc by performing
63 * @code auto alloc = get_associated_allocator(handler); @endcode
64 *
65 * @li If <tt>execution::is_executor<Ex>::value</tt> is true, performs
66 * @code prefer(
67 * require(ex, execution::blocking.never),
68 * execution::relationship.fork,
69 * execution::allocator(alloc)
70 * ).execute(std::forward<CompletionHandler>(completion_handler)); @endcode
71 *
72 * @li If <tt>execution::is_executor<Ex>::value</tt> is false, performs
73 * @code ex.post(
74 * std::forward<CompletionHandler>(completion_handler),
75 * alloc); @endcode
76 *
77 * @par Completion Signature
78 * @code void() @endcode
79 */
80template <BOOST_ASIO_COMPLETION_TOKEN_FOR(void()) NullaryToken>
81inline auto post(NullaryToken&& token)
82 -> decltype(
83 async_initiate<NullaryToken, void()>(
84 declval<detail::initiate_post>(), token))
85{
86 return async_initiate<NullaryToken, void()>(
87 detail::initiate_post(), token);
88}
89
90/// Submits a completion token or function object for execution.
91/**
92 * This function submits an object for execution using the specified executor.
93 * The function object is queued for execution, and is never called from the
94 * current thread prior to returning from <tt>post()</tt>.
95 *
96 * The use of @c post(), rather than @ref defer(), indicates the caller's
97 * preference that the function object be eagerly queued for execution.
98 *
99 * @param ex The target executor.
100 *
101 * @param token The @ref completion_token that will be used to produce a
102 * completion handler. The function signature of the completion handler must be:
103 * @code void handler(); @endcode
104 *
105 * @returns This function returns <tt>async_initiate<NullaryToken,
106 * void()>(Init{ex}, token)</tt>, where @c Init is a function object type
107 * defined as:
108 *
109 * @code class Init
110 * {
111 * public:
112 * using executor_type = Executor;
113 * explicit Init(const Executor& ex) : ex_(ex) {}
114 * executor_type get_executor() const noexcept { return ex_; }
115 * template <typename CompletionHandler>
116 * void operator()(CompletionHandler&& completion_handler) const;
117 * private:
118 * Executor ex_; // exposition only
119 * }; @endcode
120 *
121 * The function call operator of @c Init:
122 *
123 * @li Obtains the handler's associated executor object @c ex1 of type @c Ex1 by
124 * performing @code auto ex1 = get_associated_executor(handler, ex); @endcode
125 *
126 * @li Obtains the handler's associated allocator object @c alloc by performing
127 * @code auto alloc = get_associated_allocator(handler); @endcode
128 *
129 * @li If <tt>execution::is_executor<Ex1>::value</tt> is true, constructs a
130 * function object @c f with a member @c executor_ that is initialised with
131 * <tt>prefer(ex1, execution::outstanding_work.tracked)</tt>, a member @c
132 * handler_ that is a decay-copy of @c completion_handler, and a function call
133 * operator that performs:
134 * @code auto a = get_associated_allocator(handler_);
135 * prefer(executor_, execution::allocator(a)).execute(std::move(handler_));
136 * @endcode
137 *
138 * @li If <tt>execution::is_executor<Ex1>::value</tt> is false, constructs a
139 * function object @c f with a member @c work_ that is initialised with
140 * <tt>make_work_guard(ex1)</tt>, a member @c handler_ that is a decay-copy of
141 * @c completion_handler, and a function call operator that performs:
142 * @code auto a = get_associated_allocator(handler_);
143 * work_.get_executor().dispatch(std::move(handler_), a);
144 * work_.reset(); @endcode
145 *
146 * @li If <tt>execution::is_executor<Ex>::value</tt> is true, performs
147 * @code prefer(
148 * require(ex, execution::blocking.never),
149 * execution::relationship.fork,
150 * execution::allocator(alloc)
151 * ).execute(std::move(f)); @endcode
152 *
153 * @li If <tt>execution::is_executor<Ex>::value</tt> is false, performs
154 * @code ex.post(std::move(f), alloc); @endcode
155 *
156 * @par Completion Signature
157 * @code void() @endcode
158 */
159template <typename Executor,
160 BOOST_ASIO_COMPLETION_TOKEN_FOR(void()) NullaryToken
161 = default_completion_token_t<Executor>>
162inline auto post(const Executor& ex,
163 NullaryToken&& token = default_completion_token_t<Executor>(),
164 constraint_t<
165 (execution::is_executor<Executor>::value
166 && can_require<Executor, execution::blocking_t::never_t>::value)
167 || is_executor<Executor>::value
168 > = 0)
169 -> decltype(
170 async_initiate<NullaryToken, void()>(
171 declval<detail::initiate_post_with_executor<Executor>>(), token))
172{
173 return async_initiate<NullaryToken, void()>(
174 detail::initiate_post_with_executor<Executor>(ex), token);
175}
176
177/// Submits a completion token or function object for execution.
178/**
179 * @param ctx An execution context, from which the target executor is obtained.
180 *
181 * @param token The @ref completion_token that will be used to produce a
182 * completion handler. The function signature of the completion handler must be:
183 * @code void handler(); @endcode
184 *
185 * @returns <tt>post(ctx.get_executor(), forward<NullaryToken>(token))</tt>.
186 *
187 * @par Completion Signature
188 * @code void() @endcode
189 */
190template <typename ExecutionContext,
191 BOOST_ASIO_COMPLETION_TOKEN_FOR(void()) NullaryToken
192 = default_completion_token_t<typename ExecutionContext::executor_type>>
193inline auto post(ExecutionContext& ctx,
194 NullaryToken&& token = default_completion_token_t<
195 typename ExecutionContext::executor_type>(),
196 constraint_t<
197 is_convertible<ExecutionContext&, execution_context&>::value
198 > = 0)
199 -> decltype(
200 async_initiate<NullaryToken, void()>(
201 declval<detail::initiate_post_with_executor<
202 typename ExecutionContext::executor_type>>(), token))
203{
204 return async_initiate<NullaryToken, void()>(
205 detail::initiate_post_with_executor<
206 typename ExecutionContext::executor_type>(
207 ctx.get_executor()), token);
208}
209
210} // namespace asio
211} // namespace boost
212
213#include <boost/asio/detail/pop_options.hpp>
214
215#endif // BOOST_ASIO_POST_HPP
216

source code of boost/libs/asio/include/boost/asio/post.hpp