]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/asio/experimental/detail/channel_operation.hpp
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / boost / boost / asio / experimental / detail / channel_operation.hpp
1 //
2 // experimental/detail/channel_operation.hpp
3 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4 //
5 // Copyright (c) 2003-2022 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_EXPERIMENTAL_DETAIL_CHANNEL_OPERATION_HPP
12 #define BOOST_ASIO_EXPERIMENTAL_DETAIL_CHANNEL_OPERATION_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/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>
26
27 #include <boost/asio/detail/push_options.hpp>
28
29 namespace boost {
30 namespace asio {
31 namespace experimental {
32 namespace detail {
33
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
37 {
38 public:
39 template <typename Executor, typename = void>
40 class handler_work_base;
41
42 template <typename Handler, typename IoExecutor, typename = void>
43 class handler_work;
44
45 void destroy()
46 {
47 func_(this, destroy_op, 0);
48 }
49
50 protected:
51 enum action
52 {
53 destroy_op = 0,
54 complete_op = 1,
55 cancel_op = 2,
56 close_op = 3
57 };
58
59 typedef void (*func_type)(channel_operation*, action, void*);
60
61 channel_operation(func_type func)
62 : next_(0),
63 func_(func),
64 cancellation_key_(0)
65 {
66 }
67
68 // Prevents deletion through this type.
69 ~channel_operation()
70 {
71 }
72
73 friend class boost::asio::detail::op_queue_access;
74 channel_operation* next_;
75 func_type func_;
76
77 public:
78 // The operation key used for targeted cancellation.
79 void* cancellation_key_;
80 };
81
82 template <typename Executor, typename>
83 class channel_operation::handler_work_base
84 {
85 public:
86 handler_work_base(int, const Executor& ex)
87 : executor_(boost::asio::prefer(ex, execution::outstanding_work.tracked))
88 {
89 }
90
91 template <typename Function, typename Handler>
92 void post(Function& function, Handler& handler)
93 {
94 typename associated_allocator<Handler>::type allocator =
95 (get_associated_allocator)(handler);
96
97 execution::execute(
98 boost::asio::prefer(
99 boost::asio::require(executor_, execution::blocking.never),
100 execution::allocator(allocator)),
101 BOOST_ASIO_MOVE_CAST(Function)(function));
102 }
103
104 private:
105 typename decay<
106 typename prefer_result<Executor,
107 execution::outstanding_work_t::tracked_t
108 >::type
109 >::type executor_;
110 };
111
112 #if !defined(BOOST_ASIO_NO_TS_EXECUTORS)
113
114 template <typename Executor>
115 class channel_operation::handler_work_base<Executor,
116 typename enable_if<
117 !execution::is_executor<Executor>::value
118 >::type>
119 {
120 public:
121 handler_work_base(int, const Executor& ex)
122 : work_(ex)
123 {
124 }
125
126 template <typename Function, typename Handler>
127 void post(Function& function, Handler& handler)
128 {
129 typename associated_allocator<Handler>::type allocator =
130 (get_associated_allocator)(handler);
131
132 work_.get_executor().post(
133 BOOST_ASIO_MOVE_CAST(Function)(function), allocator);
134 }
135
136 private:
137 executor_work_guard<Executor> work_;
138 };
139
140 #endif // !defined(BOOST_ASIO_NO_TS_EXECUTORS)
141
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>
147 {
148 public:
149 typedef channel_operation::handler_work_base<IoExecutor> base1_type;
150
151 typedef channel_operation::handler_work_base<
152 typename associated_executor<Handler, IoExecutor>::type, IoExecutor>
153 base2_type;
154
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))
158 {
159 }
160
161 template <typename Function>
162 void complete(Function& function, Handler& handler)
163 {
164 base2_type::post(function, handler);
165 }
166 };
167
168 template <typename Handler, typename IoExecutor>
169 class channel_operation::handler_work<
170 Handler, IoExecutor,
171 typename enable_if<
172 is_same<
173 typename associated_executor<Handler,
174 IoExecutor>::asio_associated_executor_is_unspecialised,
175 void
176 >::value
177 >::type> : handler_work_base<IoExecutor>
178 {
179 public:
180 typedef channel_operation::handler_work_base<IoExecutor> base1_type;
181
182 handler_work(Handler&, const IoExecutor& io_ex) BOOST_ASIO_NOEXCEPT
183 : base1_type(0, io_ex)
184 {
185 }
186
187 template <typename Function>
188 void complete(Function& function, Handler& handler)
189 {
190 base1_type::post(function, handler);
191 }
192 };
193
194 } // namespace detail
195 } // namespace experimental
196 } // namespace asio
197 } // namespace boost
198
199 #include <boost/asio/detail/pop_options.hpp>
200
201 #endif // BOOST_ASIO_EXPERIMENTAL_DETAIL_CHANNEL_OPERATION_HPP