2 // experimental/detail/channel_operation.hpp
3 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5 // Copyright (c) 2003-2022 Christopher M. Kohlhoff (chris at kohlhoff dot com)
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)
11 #ifndef BOOST_ASIO_EXPERIMENTAL_DETAIL_CHANNEL_OPERATION_HPP
12 #define BOOST_ASIO_EXPERIMENTAL_DETAIL_CHANNEL_OPERATION_HPP
14 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
16 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
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/op_queue.hpp>
22 #include <boost/asio/execution/executor.hpp>
23 #include <boost/asio/execution/outstanding_work.hpp>
24 #include <boost/asio/executor_work_guard.hpp>
25 #include <boost/asio/prefer.hpp>
27 #include <boost/asio/detail/push_options.hpp>
31 namespace experimental {
34 // Base class for all channel operations. A function pointer is used instead of
35 // virtual functions to avoid the associated overhead.
36 class channel_operation BOOST_ASIO_INHERIT_TRACKED_HANDLER
39 template <typename Executor, typename = void>
40 class handler_work_base;
42 template <typename Handler, typename IoExecutor, typename = void>
47 func_(this, destroy_op, 0);
59 typedef void (*func_type)(channel_operation*, action, void*);
61 channel_operation(func_type func)
68 // Prevents deletion through this type.
73 friend class boost::asio::detail::op_queue_access;
74 channel_operation* next_;
78 // The operation key used for targeted cancellation.
79 void* cancellation_key_;
82 template <typename Executor, typename>
83 class channel_operation::handler_work_base
86 handler_work_base(int, const Executor& ex)
87 : executor_(boost::asio::prefer(ex, execution::outstanding_work.tracked))
91 template <typename Function, typename Handler>
92 void post(Function& function, Handler& handler)
94 typename associated_allocator<Handler>::type allocator =
95 (get_associated_allocator)(handler);
99 boost::asio::require(executor_, execution::blocking.never),
100 execution::allocator(allocator)),
101 BOOST_ASIO_MOVE_CAST(Function)(function));
106 typename prefer_result<Executor,
107 execution::outstanding_work_t::tracked_t
112 #if !defined(BOOST_ASIO_NO_TS_EXECUTORS)
114 template <typename Executor>
115 class channel_operation::handler_work_base<Executor,
117 !execution::is_executor<Executor>::value
121 handler_work_base(int, const Executor& ex)
126 template <typename Function, typename Handler>
127 void post(Function& function, Handler& handler)
129 typename associated_allocator<Handler>::type allocator =
130 (get_associated_allocator)(handler);
132 work_.get_executor().post(
133 BOOST_ASIO_MOVE_CAST(Function)(function), allocator);
137 executor_work_guard<Executor> work_;
140 #endif // !defined(BOOST_ASIO_NO_TS_EXECUTORS)
142 template <typename Handler, typename IoExecutor, typename>
143 class channel_operation::handler_work :
144 channel_operation::handler_work_base<IoExecutor>,
145 channel_operation::handler_work_base<
146 typename associated_executor<Handler, IoExecutor>::type, IoExecutor>
149 typedef channel_operation::handler_work_base<IoExecutor> base1_type;
151 typedef channel_operation::handler_work_base<
152 typename associated_executor<Handler, IoExecutor>::type, IoExecutor>
155 handler_work(Handler& handler, const IoExecutor& io_ex) BOOST_ASIO_NOEXCEPT
156 : base1_type(0, io_ex),
157 base2_type(0, (get_associated_executor)(handler, io_ex))
161 template <typename Function>
162 void complete(Function& function, Handler& handler)
164 base2_type::post(function, handler);
168 template <typename Handler, typename IoExecutor>
169 class channel_operation::handler_work<
173 typename associated_executor<Handler,
174 IoExecutor>::asio_associated_executor_is_unspecialised,
177 >::type> : handler_work_base<IoExecutor>
180 typedef channel_operation::handler_work_base<IoExecutor> base1_type;
182 handler_work(Handler&, const IoExecutor& io_ex) BOOST_ASIO_NOEXCEPT
183 : base1_type(0, io_ex)
187 template <typename Function>
188 void complete(Function& function, Handler& handler)
190 base1_type::post(function, handler);
194 } // namespace detail
195 } // namespace experimental
199 #include <boost/asio/detail/pop_options.hpp>
201 #endif // BOOST_ASIO_EXPERIMENTAL_DETAIL_CHANNEL_OPERATION_HPP