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

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