]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/asio/impl/executor.hpp
bump version to 18.2.2-pve1
[ceph.git] / ceph / src / boost / boost / asio / impl / executor.hpp
1 //
2 // impl/executor.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_IMPL_EXECUTOR_HPP
12 #define BOOST_ASIO_IMPL_EXECUTOR_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
20 #if !defined(BOOST_ASIO_NO_TS_EXECUTORS)
21
22 #include <boost/asio/detail/atomic_count.hpp>
23 #include <boost/asio/detail/global.hpp>
24 #include <boost/asio/detail/memory.hpp>
25 #include <boost/asio/executor.hpp>
26 #include <boost/asio/system_executor.hpp>
27
28 #include <boost/asio/detail/push_options.hpp>
29
30 namespace boost {
31 namespace asio {
32
33 #if !defined(GENERATING_DOCUMENTATION)
34
35 // Default polymorphic executor implementation.
36 template <typename Executor, typename Allocator>
37 class executor::impl
38 : public executor::impl_base
39 {
40 public:
41 typedef BOOST_ASIO_REBIND_ALLOC(Allocator, impl) allocator_type;
42
43 static impl_base* create(const Executor& e, Allocator a = Allocator())
44 {
45 raw_mem mem(a);
46 impl* p = new (mem.ptr_) impl(e, a);
47 mem.ptr_ = 0;
48 return p;
49 }
50
51 impl(const Executor& e, const Allocator& a) BOOST_ASIO_NOEXCEPT
52 : impl_base(false),
53 ref_count_(1),
54 executor_(e),
55 allocator_(a)
56 {
57 }
58
59 impl_base* clone() const BOOST_ASIO_NOEXCEPT
60 {
61 detail::ref_count_up(ref_count_);
62 return const_cast<impl_base*>(static_cast<const impl_base*>(this));
63 }
64
65 void destroy() BOOST_ASIO_NOEXCEPT
66 {
67 if (detail::ref_count_down(ref_count_))
68 {
69 allocator_type alloc(allocator_);
70 impl* p = this;
71 p->~impl();
72 alloc.deallocate(p, 1);
73 }
74 }
75
76 void on_work_started() BOOST_ASIO_NOEXCEPT
77 {
78 executor_.on_work_started();
79 }
80
81 void on_work_finished() BOOST_ASIO_NOEXCEPT
82 {
83 executor_.on_work_finished();
84 }
85
86 execution_context& context() BOOST_ASIO_NOEXCEPT
87 {
88 return executor_.context();
89 }
90
91 void dispatch(BOOST_ASIO_MOVE_ARG(function) f)
92 {
93 executor_.dispatch(BOOST_ASIO_MOVE_CAST(function)(f), allocator_);
94 }
95
96 void post(BOOST_ASIO_MOVE_ARG(function) f)
97 {
98 executor_.post(BOOST_ASIO_MOVE_CAST(function)(f), allocator_);
99 }
100
101 void defer(BOOST_ASIO_MOVE_ARG(function) f)
102 {
103 executor_.defer(BOOST_ASIO_MOVE_CAST(function)(f), allocator_);
104 }
105
106 type_id_result_type target_type() const BOOST_ASIO_NOEXCEPT
107 {
108 return type_id<Executor>();
109 }
110
111 void* target() BOOST_ASIO_NOEXCEPT
112 {
113 return &executor_;
114 }
115
116 const void* target() const BOOST_ASIO_NOEXCEPT
117 {
118 return &executor_;
119 }
120
121 bool equals(const impl_base* e) const BOOST_ASIO_NOEXCEPT
122 {
123 if (this == e)
124 return true;
125 if (target_type() != e->target_type())
126 return false;
127 return executor_ == *static_cast<const Executor*>(e->target());
128 }
129
130 private:
131 mutable detail::atomic_count ref_count_;
132 Executor executor_;
133 Allocator allocator_;
134
135 struct raw_mem
136 {
137 allocator_type allocator_;
138 impl* ptr_;
139
140 explicit raw_mem(const Allocator& a)
141 : allocator_(a),
142 ptr_(allocator_.allocate(1))
143 {
144 }
145
146 ~raw_mem()
147 {
148 if (ptr_)
149 allocator_.deallocate(ptr_, 1);
150 }
151
152 private:
153 // Disallow copying and assignment.
154 raw_mem(const raw_mem&);
155 raw_mem operator=(const raw_mem&);
156 };
157 };
158
159 // Polymorphic executor specialisation for system_executor.
160 template <typename Allocator>
161 class executor::impl<system_executor, Allocator>
162 : public executor::impl_base
163 {
164 public:
165 static impl_base* create(const system_executor&,
166 const Allocator& = Allocator())
167 {
168 return &detail::global<impl<system_executor, std::allocator<void> > >();
169 }
170
171 impl()
172 : impl_base(true)
173 {
174 }
175
176 impl_base* clone() const BOOST_ASIO_NOEXCEPT
177 {
178 return const_cast<impl_base*>(static_cast<const impl_base*>(this));
179 }
180
181 void destroy() BOOST_ASIO_NOEXCEPT
182 {
183 }
184
185 void on_work_started() BOOST_ASIO_NOEXCEPT
186 {
187 executor_.on_work_started();
188 }
189
190 void on_work_finished() BOOST_ASIO_NOEXCEPT
191 {
192 executor_.on_work_finished();
193 }
194
195 execution_context& context() BOOST_ASIO_NOEXCEPT
196 {
197 return executor_.context();
198 }
199
200 void dispatch(BOOST_ASIO_MOVE_ARG(function) f)
201 {
202 executor_.dispatch(BOOST_ASIO_MOVE_CAST(function)(f),
203 std::allocator<void>());
204 }
205
206 void post(BOOST_ASIO_MOVE_ARG(function) f)
207 {
208 executor_.post(BOOST_ASIO_MOVE_CAST(function)(f),
209 std::allocator<void>());
210 }
211
212 void defer(BOOST_ASIO_MOVE_ARG(function) f)
213 {
214 executor_.defer(BOOST_ASIO_MOVE_CAST(function)(f),
215 std::allocator<void>());
216 }
217
218 type_id_result_type target_type() const BOOST_ASIO_NOEXCEPT
219 {
220 return type_id<system_executor>();
221 }
222
223 void* target() BOOST_ASIO_NOEXCEPT
224 {
225 return &executor_;
226 }
227
228 const void* target() const BOOST_ASIO_NOEXCEPT
229 {
230 return &executor_;
231 }
232
233 bool equals(const impl_base* e) const BOOST_ASIO_NOEXCEPT
234 {
235 return this == e;
236 }
237
238 private:
239 system_executor executor_;
240 };
241
242 template <typename Executor>
243 executor::executor(Executor e)
244 : impl_(impl<Executor, std::allocator<void> >::create(e))
245 {
246 }
247
248 template <typename Executor, typename Allocator>
249 executor::executor(allocator_arg_t, const Allocator& a, Executor e)
250 : impl_(impl<Executor, Allocator>::create(e, a))
251 {
252 }
253
254 template <typename Function, typename Allocator>
255 void executor::dispatch(BOOST_ASIO_MOVE_ARG(Function) f,
256 const Allocator& a) const
257 {
258 impl_base* i = get_impl();
259 if (i->fast_dispatch_)
260 system_executor().dispatch(BOOST_ASIO_MOVE_CAST(Function)(f), a);
261 else
262 i->dispatch(function(BOOST_ASIO_MOVE_CAST(Function)(f), a));
263 }
264
265 template <typename Function, typename Allocator>
266 void executor::post(BOOST_ASIO_MOVE_ARG(Function) f,
267 const Allocator& a) const
268 {
269 get_impl()->post(function(BOOST_ASIO_MOVE_CAST(Function)(f), a));
270 }
271
272 template <typename Function, typename Allocator>
273 void executor::defer(BOOST_ASIO_MOVE_ARG(Function) f,
274 const Allocator& a) const
275 {
276 get_impl()->defer(function(BOOST_ASIO_MOVE_CAST(Function)(f), a));
277 }
278
279 template <typename Executor>
280 Executor* executor::target() BOOST_ASIO_NOEXCEPT
281 {
282 return impl_ && impl_->target_type() == type_id<Executor>()
283 ? static_cast<Executor*>(impl_->target()) : 0;
284 }
285
286 template <typename Executor>
287 const Executor* executor::target() const BOOST_ASIO_NOEXCEPT
288 {
289 return impl_ && impl_->target_type() == type_id<Executor>()
290 ? static_cast<Executor*>(impl_->target()) : 0;
291 }
292
293 #endif // !defined(GENERATING_DOCUMENTATION)
294
295 } // namespace asio
296 } // namespace boost
297
298 #include <boost/asio/detail/pop_options.hpp>
299
300 #endif // !defined(BOOST_ASIO_NO_TS_EXECUTORS)
301
302 #endif // BOOST_ASIO_IMPL_EXECUTOR_HPP