]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/boost/asio/impl/executor.hpp
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / boost / boost / asio / impl / executor.hpp
CommitLineData
b32b8144
FG
1//
2// impl/executor.hpp
3// ~~~~~~~~~~~~~~~~~
4//
1e59de90 5// Copyright (c) 2003-2022 Christopher M. Kohlhoff (chris at kohlhoff dot com)
b32b8144
FG
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>
20effc67
TL
19
20#if !defined(BOOST_ASIO_NO_TS_EXECUTORS)
21
b32b8144 22#include <boost/asio/detail/atomic_count.hpp>
b32b8144
FG
23#include <boost/asio/detail/global.hpp>
24#include <boost/asio/detail/memory.hpp>
b32b8144
FG
25#include <boost/asio/executor.hpp>
26#include <boost/asio/system_executor.hpp>
27
28#include <boost/asio/detail/push_options.hpp>
29
30namespace boost {
31namespace asio {
32
33#if !defined(GENERATING_DOCUMENTATION)
34
20effc67 35// Default polymorphic executor implementation.
b32b8144
FG
36template <typename Executor, typename Allocator>
37class executor::impl
38 : public executor::impl_base
39{
40public:
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 {
20effc67 61 detail::ref_count_up(ref_count_);
b32b8144
FG
62 return const_cast<impl_base*>(static_cast<const impl_base*>(this));
63 }
64
65 void destroy() BOOST_ASIO_NOEXCEPT
66 {
20effc67 67 if (detail::ref_count_down(ref_count_))
b32b8144
FG
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
130private:
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
20effc67 159// Polymorphic executor specialisation for system_executor.
b32b8144
FG
160template <typename Allocator>
161class executor::impl<system_executor, Allocator>
162 : public executor::impl_base
163{
164public:
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 {
20effc67
TL
202 executor_.dispatch(BOOST_ASIO_MOVE_CAST(function)(f),
203 std::allocator<void>());
b32b8144
FG
204 }
205
206 void post(BOOST_ASIO_MOVE_ARG(function) f)
207 {
20effc67
TL
208 executor_.post(BOOST_ASIO_MOVE_CAST(function)(f),
209 std::allocator<void>());
b32b8144
FG
210 }
211
212 void defer(BOOST_ASIO_MOVE_ARG(function) f)
213 {
20effc67
TL
214 executor_.defer(BOOST_ASIO_MOVE_CAST(function)(f),
215 std::allocator<void>());
b32b8144
FG
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
238private:
239 system_executor executor_;
b32b8144
FG
240};
241
242template <typename Executor>
243executor::executor(Executor e)
244 : impl_(impl<Executor, std::allocator<void> >::create(e))
245{
246}
247
248template <typename Executor, typename Allocator>
249executor::executor(allocator_arg_t, const Allocator& a, Executor e)
250 : impl_(impl<Executor, Allocator>::create(e, a))
251{
252}
253
254template <typename Function, typename Allocator>
255void 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
265template <typename Function, typename Allocator>
266void 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
272template <typename Function, typename Allocator>
273void 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
279template <typename Executor>
280Executor* executor::target() BOOST_ASIO_NOEXCEPT
281{
282 return impl_ && impl_->target_type() == type_id<Executor>()
283 ? static_cast<Executor*>(impl_->target()) : 0;
284}
285
286template <typename Executor>
287const 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
20effc67
TL
300#endif // !defined(BOOST_ASIO_NO_TS_EXECUTORS)
301
b32b8144 302#endif // BOOST_ASIO_IMPL_EXECUTOR_HPP