5 // Copyright (c) 2003-2017 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_HPP
12 #define BOOST_ASIO_EXECUTOR_HPP
14 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
16 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
18 #include <boost/asio/detail/config.hpp>
20 #include <boost/asio/detail/cstddef.hpp>
21 #include <boost/asio/detail/memory.hpp>
22 #include <boost/asio/detail/throw_exception.hpp>
23 #include <boost/asio/execution_context.hpp>
25 #include <boost/asio/detail/push_options.hpp>
30 /// Exception thrown when trying to access an empty polymorphic executor.
32 : public std::exception
36 BOOST_ASIO_DECL bad_executor() BOOST_ASIO_NOEXCEPT;
38 /// Obtain message associated with exception.
39 BOOST_ASIO_DECL virtual const char* what() const
40 BOOST_ASIO_NOEXCEPT_OR_NOTHROW;
43 /// Polymorphic wrapper for executors.
47 /// Default constructor.
48 executor() BOOST_ASIO_NOEXCEPT
53 /// Construct from nullptr.
54 executor(nullptr_t) BOOST_ASIO_NOEXCEPT
60 executor(const executor& other) BOOST_ASIO_NOEXCEPT
61 : impl_(other.clone())
65 #if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
67 executor(executor&& other) BOOST_ASIO_NOEXCEPT
72 #endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
74 /// Construct a polymorphic wrapper for the specified executor.
75 template <typename Executor>
78 /// Allocator-aware constructor to create a polymorphic wrapper for the
79 /// specified executor.
80 template <typename Executor, typename Allocator>
81 executor(allocator_arg_t, const Allocator& a, Executor e);
89 /// Assignment operator.
90 executor& operator=(const executor& other) BOOST_ASIO_NOEXCEPT
93 impl_ = other.clone();
97 #if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
98 // Move assignment operator.
99 executor& operator=(executor&& other) BOOST_ASIO_NOEXCEPT
106 #endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
108 /// Assignment operator for nullptr_t.
109 executor& operator=(nullptr_t) BOOST_ASIO_NOEXCEPT
116 /// Assignment operator to create a polymorphic wrapper for the specified
118 template <typename Executor>
119 executor& operator=(BOOST_ASIO_MOVE_ARG(Executor) e) BOOST_ASIO_NOEXCEPT
121 executor tmp(BOOST_ASIO_MOVE_CAST(Executor)(e));
128 /// Obtain the underlying execution context.
129 execution_context& context() const BOOST_ASIO_NOEXCEPT
131 return get_impl()->context();
134 /// Inform the executor that it has some outstanding work to do.
135 void on_work_started() const BOOST_ASIO_NOEXCEPT
137 get_impl()->on_work_started();
140 /// Inform the executor that some work is no longer outstanding.
141 void on_work_finished() const BOOST_ASIO_NOEXCEPT
143 get_impl()->on_work_finished();
146 /// Request the executor to invoke the given function object.
148 * This function is used to ask the executor to execute the given function
149 * object. The function object is executed according to the rules of the
150 * target executor object.
152 * @param f The function object to be called. The executor will make a copy
153 * of the handler object as required. The function signature of the function
154 * object must be: @code void function(); @endcode
156 * @param a An allocator that may be used by the executor to allocate the
157 * internal storage needed for function invocation.
159 template <typename Function, typename Allocator>
160 void dispatch(BOOST_ASIO_MOVE_ARG(Function) f, const Allocator& a) const;
162 /// Request the executor to invoke the given function object.
164 * This function is used to ask the executor to execute the given function
165 * object. The function object is executed according to the rules of the
166 * target executor object.
168 * @param f The function object to be called. The executor will make
169 * a copy of the handler object as required. The function signature of the
170 * function object must be: @code void function(); @endcode
172 * @param a An allocator that may be used by the executor to allocate the
173 * internal storage needed for function invocation.
175 template <typename Function, typename Allocator>
176 void post(BOOST_ASIO_MOVE_ARG(Function) f, const Allocator& a) const;
178 /// Request the executor to invoke the given function object.
180 * This function is used to ask the executor to execute the given function
181 * object. The function object is executed according to the rules of the
182 * target executor object.
184 * @param f The function object to be called. The executor will make
185 * a copy of the handler object as required. The function signature of the
186 * function object must be: @code void function(); @endcode
188 * @param a An allocator that may be used by the executor to allocate the
189 * internal storage needed for function invocation.
191 template <typename Function, typename Allocator>
192 void defer(BOOST_ASIO_MOVE_ARG(Function) f, const Allocator& a) const;
194 struct unspecified_bool_type_t {};
195 typedef void (*unspecified_bool_type)(unspecified_bool_type_t);
196 static void unspecified_bool_true(unspecified_bool_type_t) {}
198 /// Operator to test if the executor contains a valid target.
199 operator unspecified_bool_type() const BOOST_ASIO_NOEXCEPT
201 return impl_ ? &executor::unspecified_bool_true : 0;
204 /// Obtain type information for the target executor object.
206 * @returns If @c *this has a target type of type @c T, <tt>typeid(T)</tt>;
207 * otherwise, <tt>typeid(void)</tt>.
209 #if !defined(BOOST_ASIO_NO_TYPEID) || defined(GENERATING_DOCUMENTATION)
210 const std::type_info& target_type() const BOOST_ASIO_NOEXCEPT
212 return impl_ ? impl_->target_type() : typeid(void);
214 #else // !defined(BOOST_ASIO_NO_TYPEID) || defined(GENERATING_DOCUMENTATION)
215 const void* target_type() const BOOST_ASIO_NOEXCEPT
217 return impl_ ? impl_->target_type() : 0;
219 #endif // !defined(BOOST_ASIO_NO_TYPEID) || defined(GENERATING_DOCUMENTATION)
221 /// Obtain a pointer to the target executor object.
223 * @returns If <tt>target_type() == typeid(T)</tt>, a pointer to the stored
224 * executor target; otherwise, a null pointer.
226 template <typename Executor>
227 Executor* target() BOOST_ASIO_NOEXCEPT;
229 /// Obtain a pointer to the target executor object.
231 * @returns If <tt>target_type() == typeid(T)</tt>, a pointer to the stored
232 * executor target; otherwise, a null pointer.
234 template <typename Executor>
235 const Executor* target() const BOOST_ASIO_NOEXCEPT;
237 /// Compare two executors for equality.
238 friend bool operator==(const executor& a,
239 const executor& b) BOOST_ASIO_NOEXCEPT
241 if (a.impl_ == b.impl_)
243 if (!a.impl_ || !b.impl_)
245 return a.impl_->equals(b.impl_);
248 /// Compare two executors for inequality.
249 friend bool operator!=(const executor& a,
250 const executor& b) BOOST_ASIO_NOEXCEPT
256 #if !defined(GENERATING_DOCUMENTATION)
258 template <typename, typename> class impl;
260 #if !defined(BOOST_ASIO_NO_TYPEID)
261 typedef const std::type_info& type_id_result_type;
262 #else // !defined(BOOST_ASIO_NO_TYPEID)
263 typedef const void* type_id_result_type;
264 #endif // !defined(BOOST_ASIO_NO_TYPEID)
266 template <typename T>
267 static type_id_result_type type_id()
269 #if !defined(BOOST_ASIO_NO_TYPEID)
271 #else // !defined(BOOST_ASIO_NO_TYPEID)
272 static int unique_id;
274 #endif // !defined(BOOST_ASIO_NO_TYPEID)
277 // Base class for all polymorphic executor implementations.
281 virtual impl_base* clone() const BOOST_ASIO_NOEXCEPT = 0;
282 virtual void destroy() BOOST_ASIO_NOEXCEPT = 0;
283 virtual execution_context& context() BOOST_ASIO_NOEXCEPT = 0;
284 virtual void on_work_started() BOOST_ASIO_NOEXCEPT = 0;
285 virtual void on_work_finished() BOOST_ASIO_NOEXCEPT = 0;
286 virtual void dispatch(BOOST_ASIO_MOVE_ARG(function)) = 0;
287 virtual void post(BOOST_ASIO_MOVE_ARG(function)) = 0;
288 virtual void defer(BOOST_ASIO_MOVE_ARG(function)) = 0;
289 virtual type_id_result_type target_type() const BOOST_ASIO_NOEXCEPT = 0;
290 virtual void* target() BOOST_ASIO_NOEXCEPT = 0;
291 virtual const void* target() const BOOST_ASIO_NOEXCEPT = 0;
292 virtual bool equals(const impl_base* e) const BOOST_ASIO_NOEXCEPT = 0;
295 impl_base(bool fast_dispatch) : fast_dispatch_(fast_dispatch) {}
296 virtual ~impl_base() {}
299 friend class executor;
300 const bool fast_dispatch_;
303 // Helper function to check and return the implementation pointer.
304 impl_base* get_impl() const
309 boost::asio::detail::throw_exception(ex);
314 // Helper function to clone another implementation.
315 impl_base* clone() const BOOST_ASIO_NOEXCEPT
317 return impl_ ? impl_->clone() : 0;
320 // Helper function to destroy an implementation.
321 void destroy() BOOST_ASIO_NOEXCEPT
328 #endif // !defined(GENERATING_DOCUMENTATION)
334 BOOST_ASIO_USES_ALLOCATOR(boost::asio::executor)
336 #include <boost/asio/detail/pop_options.hpp>
338 #include <boost/asio/impl/executor.hpp>
339 #if defined(BOOST_ASIO_HEADER_ONLY)
340 # include <boost/asio/impl/executor.ipp>
341 #endif // defined(BOOST_ASIO_HEADER_ONLY)
343 #endif // BOOST_ASIO_EXECUTOR_HPP