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