|
||||
File indexing completed on 2025-01-18 09:29:09
0001 // 0002 // defer.hpp 0003 // ~~~~~~~~~ 0004 // 0005 // Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) 0006 // 0007 // Distributed under the Boost Software License, Version 1.0. (See accompanying 0008 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 0009 // 0010 0011 #ifndef BOOST_ASIO_DEFER_HPP 0012 #define BOOST_ASIO_DEFER_HPP 0013 0014 #if defined(_MSC_VER) && (_MSC_VER >= 1200) 0015 # pragma once 0016 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) 0017 0018 #include <boost/asio/detail/config.hpp> 0019 #include <boost/asio/async_result.hpp> 0020 #include <boost/asio/detail/initiate_defer.hpp> 0021 #include <boost/asio/detail/type_traits.hpp> 0022 #include <boost/asio/execution_context.hpp> 0023 #include <boost/asio/execution/blocking.hpp> 0024 #include <boost/asio/execution/executor.hpp> 0025 #include <boost/asio/is_executor.hpp> 0026 #include <boost/asio/require.hpp> 0027 0028 #include <boost/asio/detail/push_options.hpp> 0029 0030 namespace boost { 0031 namespace asio { 0032 0033 /// Submits a completion token or function object for execution. 0034 /** 0035 * This function submits an object for execution using the object's associated 0036 * executor. The function object is queued for execution, and is never called 0037 * from the current thread prior to returning from <tt>defer()</tt>. 0038 * 0039 * The use of @c defer(), rather than @ref post(), indicates the caller's 0040 * preference that the executor defer the queueing of the function object. This 0041 * may allow the executor to optimise queueing for cases when the function 0042 * object represents a continuation of the current call context. 0043 * 0044 * @param token The @ref completion_token that will be used to produce a 0045 * completion handler. The function signature of the completion handler must be: 0046 * @code void handler(); @endcode 0047 * 0048 * @returns This function returns <tt>async_initiate<NullaryToken, 0049 * void()>(Init{}, token)</tt>, where @c Init is a function object type defined 0050 * as: 0051 * 0052 * @code class Init 0053 * { 0054 * public: 0055 * template <typename CompletionHandler> 0056 * void operator()(CompletionHandler&& completion_handler) const; 0057 * }; @endcode 0058 * 0059 * The function call operator of @c Init: 0060 * 0061 * @li Obtains the handler's associated executor object @c ex of type @c Ex by 0062 * performing @code auto ex = get_associated_executor(handler); @endcode 0063 * 0064 * @li Obtains the handler's associated allocator object @c alloc by performing 0065 * @code auto alloc = get_associated_allocator(handler); @endcode 0066 * 0067 * @li If <tt>execution::is_executor<Ex>::value</tt> is true, performs 0068 * @code prefer( 0069 * require(ex, execution::blocking.never), 0070 * execution::relationship.continuation, 0071 * execution::allocator(alloc) 0072 * ).execute(std::forward<CompletionHandler>(completion_handler)); @endcode 0073 * 0074 * @li If <tt>execution::is_executor<Ex>::value</tt> is false, performs 0075 * @code ex.defer( 0076 * std::forward<CompletionHandler>(completion_handler), 0077 * alloc); @endcode 0078 * 0079 * @par Completion Signature 0080 * @code void() @endcode 0081 */ 0082 template <BOOST_ASIO_COMPLETION_TOKEN_FOR(void()) NullaryToken> 0083 auto defer(NullaryToken&& token) 0084 -> decltype( 0085 async_initiate<NullaryToken, void()>( 0086 declval<detail::initiate_defer>(), token)) 0087 { 0088 return async_initiate<NullaryToken, void()>( 0089 detail::initiate_defer(), token); 0090 } 0091 0092 /// Submits a completion token or function object for execution. 0093 /** 0094 * This function submits an object for execution using the specified executor. 0095 * The function object is queued for execution, and is never called from the 0096 * current thread prior to returning from <tt>defer()</tt>. 0097 * 0098 * The use of @c defer(), rather than @ref post(), indicates the caller's 0099 * preference that the executor defer the queueing of the function object. This 0100 * may allow the executor to optimise queueing for cases when the function 0101 * object represents a continuation of the current call context. 0102 * 0103 * @param ex The target executor. 0104 * 0105 * @param token The @ref completion_token that will be used to produce a 0106 * completion handler. The function signature of the completion handler must be: 0107 * @code void handler(); @endcode 0108 * 0109 * @returns This function returns <tt>async_initiate<NullaryToken, 0110 * void()>(Init{ex}, token)</tt>, where @c Init is a function object type 0111 * defined as: 0112 * 0113 * @code class Init 0114 * { 0115 * public: 0116 * using executor_type = Executor; 0117 * explicit Init(const Executor& ex) : ex_(ex) {} 0118 * executor_type get_executor() const noexcept { return ex_; } 0119 * template <typename CompletionHandler> 0120 * void operator()(CompletionHandler&& completion_handler) const; 0121 * private: 0122 * Executor ex_; // exposition only 0123 * }; @endcode 0124 * 0125 * The function call operator of @c Init: 0126 * 0127 * @li Obtains the handler's associated executor object @c ex1 of type @c Ex1 by 0128 * performing @code auto ex1 = get_associated_executor(handler, ex); @endcode 0129 * 0130 * @li Obtains the handler's associated allocator object @c alloc by performing 0131 * @code auto alloc = get_associated_allocator(handler); @endcode 0132 * 0133 * @li If <tt>execution::is_executor<Ex1>::value</tt> is true, constructs a 0134 * function object @c f with a member @c executor_ that is initialised with 0135 * <tt>prefer(ex1, execution::outstanding_work.tracked)</tt>, a member @c 0136 * handler_ that is a decay-copy of @c completion_handler, and a function call 0137 * operator that performs: 0138 * @code auto a = get_associated_allocator(handler_); 0139 * prefer(executor_, execution::allocator(a)).execute(std::move(handler_)); 0140 * @endcode 0141 * 0142 * @li If <tt>execution::is_executor<Ex1>::value</tt> is false, constructs a 0143 * function object @c f with a member @c work_ that is initialised with 0144 * <tt>make_work_guard(ex1)</tt>, a member @c handler_ that is a decay-copy of 0145 * @c completion_handler, and a function call operator that performs: 0146 * @code auto a = get_associated_allocator(handler_); 0147 * work_.get_executor().dispatch(std::move(handler_), a); 0148 * work_.reset(); @endcode 0149 * 0150 * @li If <tt>execution::is_executor<Ex>::value</tt> is true, performs 0151 * @code prefer( 0152 * require(ex, execution::blocking.never), 0153 * execution::relationship.continuation, 0154 * execution::allocator(alloc) 0155 * ).execute(std::move(f)); @endcode 0156 * 0157 * @li If <tt>execution::is_executor<Ex>::value</tt> is false, performs 0158 * @code ex.defer(std::move(f), alloc); @endcode 0159 * 0160 * @par Completion Signature 0161 * @code void() @endcode 0162 */ 0163 template <typename Executor, 0164 BOOST_ASIO_COMPLETION_TOKEN_FOR(void()) NullaryToken 0165 = default_completion_token_t<Executor>> 0166 auto defer(const Executor& ex, 0167 NullaryToken&& token 0168 = default_completion_token_t<Executor>(), 0169 constraint_t< 0170 (execution::is_executor<Executor>::value 0171 && can_require<Executor, execution::blocking_t::never_t>::value) 0172 || is_executor<Executor>::value 0173 > = 0) 0174 -> decltype( 0175 async_initiate<NullaryToken, void()>( 0176 declval<detail::initiate_defer_with_executor<Executor>>(), token)) 0177 { 0178 return async_initiate<NullaryToken, void()>( 0179 detail::initiate_defer_with_executor<Executor>(ex), token); 0180 } 0181 0182 /// Submits a completion token or function object for execution. 0183 /** 0184 * @param ctx An execution context, from which the target executor is obtained. 0185 * 0186 * @param token The @ref completion_token that will be used to produce a 0187 * completion handler. The function signature of the completion handler must be: 0188 * @code void handler(); @endcode 0189 * 0190 * @returns <tt>defer(ctx.get_executor(), forward<NullaryToken>(token))</tt>. 0191 * 0192 * @par Completion Signature 0193 * @code void() @endcode 0194 */ 0195 template <typename ExecutionContext, 0196 BOOST_ASIO_COMPLETION_TOKEN_FOR(void()) NullaryToken 0197 = default_completion_token_t<typename ExecutionContext::executor_type>> 0198 auto defer(ExecutionContext& ctx, 0199 NullaryToken&& token 0200 = default_completion_token_t<typename ExecutionContext::executor_type>(), 0201 constraint_t< 0202 is_convertible<ExecutionContext&, execution_context&>::value 0203 > = 0) 0204 -> decltype( 0205 async_initiate<NullaryToken, void()>( 0206 declval<detail::initiate_defer_with_executor< 0207 typename ExecutionContext::executor_type>>(), token)) 0208 { 0209 return async_initiate<NullaryToken, void()>( 0210 detail::initiate_defer_with_executor< 0211 typename ExecutionContext::executor_type>( 0212 ctx.get_executor()), token); 0213 } 0214 0215 } // namespace asio 0216 } // namespace boost 0217 0218 #include <boost/asio/detail/pop_options.hpp> 0219 0220 #endif // BOOST_ASIO_DEFER_HPP
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |