]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/boost/asio/executor_work_guard.hpp
import quincy beta 17.1.0
[ceph.git] / ceph / src / boost / boost / asio / executor_work_guard.hpp
CommitLineData
b32b8144
FG
1//
2// executor_work_guard.hpp
20effc67 3// ~~~~~~~~~~~~~~~~~~~~~~~
b32b8144 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_EXECUTOR_WORK_GUARD_HPP
12#define BOOST_ASIO_EXECUTOR_WORK_GUARD_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
FG
22#include <boost/asio/associated_executor.hpp>
23#include <boost/asio/detail/type_traits.hpp>
20effc67 24#include <boost/asio/execution.hpp>
b32b8144
FG
25#include <boost/asio/is_executor.hpp>
26
27#include <boost/asio/detail/push_options.hpp>
28
29namespace boost {
30namespace asio {
31
20effc67
TL
32#if !defined(BOOST_ASIO_EXECUTOR_WORK_GUARD_DECL)
33#define BOOST_ASIO_EXECUTOR_WORK_GUARD_DECL
34
35template <typename Executor, typename = void>
36class executor_work_guard;
37
38#endif // !defined(BOOST_ASIO_EXECUTOR_WORK_GUARD_DECL)
39
b32b8144
FG
40/// An object of type @c executor_work_guard controls ownership of executor work
41/// within a scope.
20effc67 42#if defined(GENERATING_DOCUMENTATION)
b32b8144 43template <typename Executor>
20effc67
TL
44#else // defined(GENERATING_DOCUMENTATION)
45template <typename Executor, typename>
46#endif // defined(GENERATING_DOCUMENTATION)
b32b8144
FG
47class executor_work_guard
48{
49public:
50 /// The underlying executor type.
51 typedef Executor executor_type;
52
53 /// Constructs a @c executor_work_guard object for the specified executor.
54 /**
55 * Stores a copy of @c e and calls <tt>on_work_started()</tt> on it.
56 */
57 explicit executor_work_guard(const executor_type& e) BOOST_ASIO_NOEXCEPT
58 : executor_(e),
59 owns_(true)
60 {
61 executor_.on_work_started();
62 }
63
64 /// Copy constructor.
65 executor_work_guard(const executor_work_guard& other) BOOST_ASIO_NOEXCEPT
66 : executor_(other.executor_),
67 owns_(other.owns_)
68 {
69 if (owns_)
70 executor_.on_work_started();
71 }
72
73#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
74 /// Move constructor.
92f5a8d4 75 executor_work_guard(executor_work_guard&& other) BOOST_ASIO_NOEXCEPT
b32b8144
FG
76 : executor_(BOOST_ASIO_MOVE_CAST(Executor)(other.executor_)),
77 owns_(other.owns_)
78 {
79 other.owns_ = false;
80 }
81#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
82
83 /// Destructor.
84 /**
85 * Unless the object has already been reset, or is in a moved-from state,
86 * calls <tt>on_work_finished()</tt> on the stored executor.
87 */
88 ~executor_work_guard()
89 {
90 if (owns_)
91 executor_.on_work_finished();
92 }
93
94 /// Obtain the associated executor.
95 executor_type get_executor() const BOOST_ASIO_NOEXCEPT
96 {
97 return executor_;
98 }
99
100 /// Whether the executor_work_guard object owns some outstanding work.
101 bool owns_work() const BOOST_ASIO_NOEXCEPT
102 {
103 return owns_;
104 }
105
106 /// Indicate that the work is no longer outstanding.
f67539c2 107 /**
b32b8144
FG
108 * Unless the object has already been reset, or is in a moved-from state,
109 * calls <tt>on_work_finished()</tt> on the stored executor.
110 */
111 void reset() BOOST_ASIO_NOEXCEPT
112 {
113 if (owns_)
114 {
115 executor_.on_work_finished();
116 owns_ = false;
117 }
118 }
119
120private:
121 // Disallow assignment.
122 executor_work_guard& operator=(const executor_work_guard&);
123
124 executor_type executor_;
125 bool owns_;
126};
127
20effc67
TL
128#if !defined(GENERATING_DOCUMENTATION)
129
130template <typename Executor>
131class executor_work_guard<Executor,
132 typename enable_if<
133 !is_executor<Executor>::value && execution::is_executor<Executor>::value
134 >::type>
135{
136public:
137 typedef Executor executor_type;
138
139 explicit executor_work_guard(const executor_type& e) BOOST_ASIO_NOEXCEPT
140 : executor_(e),
141 owns_(true)
142 {
143 new (&work_) work_type(boost::asio::prefer(executor_,
144 execution::outstanding_work.tracked));
145 }
146
147 executor_work_guard(const executor_work_guard& other) BOOST_ASIO_NOEXCEPT
148 : executor_(other.executor_),
149 owns_(other.owns_)
150 {
151 if (owns_)
152 {
153 new (&work_) work_type(boost::asio::prefer(executor_,
154 execution::outstanding_work.tracked));
155 }
156 }
157
158#if defined(BOOST_ASIO_HAS_MOVE)
159 executor_work_guard(executor_work_guard&& other) BOOST_ASIO_NOEXCEPT
160 : executor_(BOOST_ASIO_MOVE_CAST(Executor)(other.executor_)),
161 owns_(other.owns_)
162 {
163 if (owns_)
164 {
165 new (&work_) work_type(
166 BOOST_ASIO_MOVE_CAST(work_type)(
167 *static_cast<work_type*>(
168 static_cast<void*>(&other.work_))));
169 other.owns_ = false;
170 }
171 }
172#endif // defined(BOOST_ASIO_HAS_MOVE)
173
174 ~executor_work_guard()
175 {
176 if (owns_)
177 static_cast<work_type*>(static_cast<void*>(&work_))->~work_type();
178 }
179
180 executor_type get_executor() const BOOST_ASIO_NOEXCEPT
181 {
182 return executor_;
183 }
184
185 bool owns_work() const BOOST_ASIO_NOEXCEPT
186 {
187 return owns_;
188 }
189
190 void reset() BOOST_ASIO_NOEXCEPT
191 {
192 if (owns_)
193 {
194 static_cast<work_type*>(static_cast<void*>(&work_))->~work_type();
195 owns_ = false;
196 }
197 }
198
199private:
200 // Disallow assignment.
201 executor_work_guard& operator=(const executor_work_guard&);
202
203 typedef typename decay<
204 typename prefer_result<
205 const executor_type&,
206 execution::outstanding_work_t::tracked_t
207 >::type
208 >::type work_type;
209
210 executor_type executor_;
211 typename aligned_storage<sizeof(work_type),
212 alignment_of<work_type>::value>::type work_;
213 bool owns_;
214};
215
216#endif // !defined(GENERATING_DOCUMENTATION)
217
b32b8144
FG
218/// Create an @ref executor_work_guard object.
219template <typename Executor>
220inline executor_work_guard<Executor> make_work_guard(const Executor& ex,
20effc67
TL
221 typename enable_if<
222 is_executor<Executor>::value || execution::is_executor<Executor>::value
223 >::type* = 0)
b32b8144
FG
224{
225 return executor_work_guard<Executor>(ex);
226}
227
228/// Create an @ref executor_work_guard object.
229template <typename ExecutionContext>
230inline executor_work_guard<typename ExecutionContext::executor_type>
231make_work_guard(ExecutionContext& ctx,
232 typename enable_if<
20effc67
TL
233 is_convertible<ExecutionContext&, execution_context&>::value
234 >::type* = 0)
b32b8144
FG
235{
236 return executor_work_guard<typename ExecutionContext::executor_type>(
237 ctx.get_executor());
238}
239
240/// Create an @ref executor_work_guard object.
241template <typename T>
242inline executor_work_guard<typename associated_executor<T>::type>
243make_work_guard(const T& t,
20effc67
TL
244 typename enable_if<
245 !is_executor<T>::value && !execution::is_executor<T>::value
246 && !is_convertible<T&, execution_context&
247 >::value>::type* = 0)
b32b8144
FG
248{
249 return executor_work_guard<typename associated_executor<T>::type>(
250 associated_executor<T>::get(t));
251}
252
253/// Create an @ref executor_work_guard object.
254template <typename T, typename Executor>
255inline executor_work_guard<typename associated_executor<T, Executor>::type>
256make_work_guard(const T& t, const Executor& ex,
20effc67
TL
257 typename enable_if<
258 is_executor<Executor>::value || execution::is_executor<Executor>::value
259 >::type* = 0)
b32b8144
FG
260{
261 return executor_work_guard<typename associated_executor<T, Executor>::type>(
262 associated_executor<T, Executor>::get(t, ex));
263}
264
265/// Create an @ref executor_work_guard object.
266template <typename T, typename ExecutionContext>
267inline executor_work_guard<typename associated_executor<T,
268 typename ExecutionContext::executor_type>::type>
269make_work_guard(const T& t, ExecutionContext& ctx,
20effc67
TL
270 typename enable_if<
271 !is_executor<T>::value && !execution::is_executor<T>::value
272 && !is_convertible<T&, execution_context&>::value
273 && is_convertible<ExecutionContext&, execution_context&>::value
274 >::type* = 0)
b32b8144
FG
275{
276 return executor_work_guard<typename associated_executor<T,
277 typename ExecutionContext::executor_type>::type>(
278 associated_executor<T, typename ExecutionContext::executor_type>::get(
279 t, ctx.get_executor()));
280}
281
282} // namespace asio
283} // namespace boost
284
285#include <boost/asio/detail/pop_options.hpp>
286
20effc67
TL
287#endif // !defined(BOOST_ASIO_NO_TS_EXECUTORS)
288
b32b8144 289#endif // BOOST_ASIO_EXECUTOR_WORK_GUARD_HPP