2 // executor_work_guard.hpp
5 // Copyright (c) 2003-2020 Christopher M. Kohlhoff (chris at kohlhoff dot com)
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)
11 #ifndef BOOST_ASIO_EXECUTOR_WORK_GUARD_HPP
12 #define BOOST_ASIO_EXECUTOR_WORK_GUARD_HPP
14 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
16 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
18 #include <boost/asio/detail/config.hpp>
19 #include <boost/asio/associated_executor.hpp>
20 #include <boost/asio/detail/type_traits.hpp>
21 #include <boost/asio/is_executor.hpp>
23 #include <boost/asio/detail/push_options.hpp>
28 /// An object of type @c executor_work_guard controls ownership of executor work
30 template <typename Executor>
31 class executor_work_guard
34 /// The underlying executor type.
35 typedef Executor executor_type;
37 /// Constructs a @c executor_work_guard object for the specified executor.
39 * Stores a copy of @c e and calls <tt>on_work_started()</tt> on it.
41 explicit executor_work_guard(const executor_type& e) BOOST_ASIO_NOEXCEPT
45 executor_.on_work_started();
49 executor_work_guard(const executor_work_guard& other) BOOST_ASIO_NOEXCEPT
50 : executor_(other.executor_),
54 executor_.on_work_started();
57 #if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
59 executor_work_guard(executor_work_guard&& other) BOOST_ASIO_NOEXCEPT
60 : executor_(BOOST_ASIO_MOVE_CAST(Executor)(other.executor_)),
65 #endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
69 * Unless the object has already been reset, or is in a moved-from state,
70 * calls <tt>on_work_finished()</tt> on the stored executor.
72 ~executor_work_guard()
75 executor_.on_work_finished();
78 /// Obtain the associated executor.
79 executor_type get_executor() const BOOST_ASIO_NOEXCEPT
84 /// Whether the executor_work_guard object owns some outstanding work.
85 bool owns_work() const BOOST_ASIO_NOEXCEPT
90 /// Indicate that the work is no longer outstanding.
92 * Unless the object has already been reset, or is in a moved-from state,
93 * calls <tt>on_work_finished()</tt> on the stored executor.
95 void reset() BOOST_ASIO_NOEXCEPT
99 executor_.on_work_finished();
105 // Disallow assignment.
106 executor_work_guard& operator=(const executor_work_guard&);
108 executor_type executor_;
112 /// Create an @ref executor_work_guard object.
113 template <typename Executor>
114 inline executor_work_guard<Executor> make_work_guard(const Executor& ex,
115 typename enable_if<is_executor<Executor>::value>::type* = 0)
117 return executor_work_guard<Executor>(ex);
120 /// Create an @ref executor_work_guard object.
121 template <typename ExecutionContext>
122 inline executor_work_guard<typename ExecutionContext::executor_type>
123 make_work_guard(ExecutionContext& ctx,
125 is_convertible<ExecutionContext&, execution_context&>::value>::type* = 0)
127 return executor_work_guard<typename ExecutionContext::executor_type>(
131 /// Create an @ref executor_work_guard object.
132 template <typename T>
133 inline executor_work_guard<typename associated_executor<T>::type>
134 make_work_guard(const T& t,
135 typename enable_if<!is_executor<T>::value &&
136 !is_convertible<T&, execution_context&>::value>::type* = 0)
138 return executor_work_guard<typename associated_executor<T>::type>(
139 associated_executor<T>::get(t));
142 /// Create an @ref executor_work_guard object.
143 template <typename T, typename Executor>
144 inline executor_work_guard<typename associated_executor<T, Executor>::type>
145 make_work_guard(const T& t, const Executor& ex,
146 typename enable_if<is_executor<Executor>::value>::type* = 0)
148 return executor_work_guard<typename associated_executor<T, Executor>::type>(
149 associated_executor<T, Executor>::get(t, ex));
152 /// Create an @ref executor_work_guard object.
153 template <typename T, typename ExecutionContext>
154 inline executor_work_guard<typename associated_executor<T,
155 typename ExecutionContext::executor_type>::type>
156 make_work_guard(const T& t, ExecutionContext& ctx,
157 typename enable_if<!is_executor<T>::value &&
158 !is_convertible<T&, execution_context&>::value &&
159 is_convertible<ExecutionContext&, execution_context&>::value>::type* = 0)
161 return executor_work_guard<typename associated_executor<T,
162 typename ExecutionContext::executor_type>::type>(
163 associated_executor<T, typename ExecutionContext::executor_type>::get(
164 t, ctx.get_executor()));
170 #include <boost/asio/detail/pop_options.hpp>
172 #endif // BOOST_ASIO_EXECUTOR_WORK_GUARD_HPP