123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169 |
- //
- // io_object_executor.hpp
- // ~~~~~~~~~~~~~~~~~~~~~~
- //
- // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
- //
- // Distributed under the Boost Software License, Version 1.0. (See accompanying
- // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
- //
- #ifndef BOOST_ASIO_DETAIL_IO_OBJECT_EXECUTOR_HPP
- #define BOOST_ASIO_DETAIL_IO_OBJECT_EXECUTOR_HPP
- #if defined(_MSC_VER) && (_MSC_VER >= 1200)
- # pragma once
- #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
- #include <boost/asio/detail/config.hpp>
- #include <boost/asio/detail/handler_invoke_helpers.hpp>
- #include <boost/asio/detail/type_traits.hpp>
- #include <boost/asio/io_context.hpp>
- #include <boost/asio/detail/push_options.hpp>
- namespace boost {
- namespace asio {
- namespace detail {
- // Wrap the (potentially polymorphic) executor so that we can bypass it when
- // dispatching on a target executor that has a native I/O implementation.
- template <typename Executor>
- class io_object_executor
- {
- public:
- io_object_executor(const Executor& ex,
- bool native_implementation) BOOST_ASIO_NOEXCEPT
- : executor_(ex),
- has_native_impl_(native_implementation)
- {
- }
- io_object_executor(const io_object_executor& other) BOOST_ASIO_NOEXCEPT
- : executor_(other.executor_),
- has_native_impl_(other.has_native_impl_)
- {
- }
- template <typename Executor1>
- io_object_executor(
- const io_object_executor<Executor1>& other) BOOST_ASIO_NOEXCEPT
- : executor_(other.inner_executor()),
- has_native_impl_(other.has_native_implementation())
- {
- }
- #if defined(BOOST_ASIO_HAS_MOVE)
- io_object_executor(io_object_executor&& other) BOOST_ASIO_NOEXCEPT
- : executor_(BOOST_ASIO_MOVE_CAST(Executor)(other.executor_)),
- has_native_impl_(other.has_native_impl_)
- {
- }
- #endif // defined(BOOST_ASIO_HAS_MOVE)
- const Executor& inner_executor() const BOOST_ASIO_NOEXCEPT
- {
- return executor_;
- }
- bool has_native_implementation() const BOOST_ASIO_NOEXCEPT
- {
- return has_native_impl_;
- }
- execution_context& context() const BOOST_ASIO_NOEXCEPT
- {
- return executor_.context();
- }
- void on_work_started() const BOOST_ASIO_NOEXCEPT
- {
- if (is_same<Executor, io_context::executor_type>::value
- || has_native_impl_)
- {
- // When using a native implementation, work is already counted by the
- // execution context.
- }
- else
- {
- executor_.on_work_started();
- }
- }
- void on_work_finished() const BOOST_ASIO_NOEXCEPT
- {
- if (is_same<Executor, io_context::executor_type>::value
- || has_native_impl_)
- {
- // When using a native implementation, work is already counted by the
- // execution context.
- }
- else
- {
- executor_.on_work_finished();
- }
- }
- template <typename F, typename A>
- void dispatch(BOOST_ASIO_MOVE_ARG(F) f, const A& a) const
- {
- if (is_same<Executor, io_context::executor_type>::value
- || has_native_impl_)
- {
- // When using a native implementation, I/O completion handlers are
- // already dispatched according to the execution context's executor's
- // rules. We can call the function directly.
- #if defined(BOOST_ASIO_HAS_MOVE)
- if (is_same<F, typename decay<F>::type>::value)
- {
- boost_asio_handler_invoke_helpers::invoke(f, f);
- return;
- }
- #endif // defined(BOOST_ASIO_HAS_MOVE)
- typename decay<F>::type function(BOOST_ASIO_MOVE_CAST(F)(f));
- boost_asio_handler_invoke_helpers::invoke(function, function);
- }
- else
- {
- executor_.dispatch(BOOST_ASIO_MOVE_CAST(F)(f), a);
- }
- }
- template <typename F, typename A>
- void post(BOOST_ASIO_MOVE_ARG(F) f, const A& a) const
- {
- executor_.post(BOOST_ASIO_MOVE_CAST(F)(f), a);
- }
- template <typename F, typename A>
- void defer(BOOST_ASIO_MOVE_ARG(F) f, const A& a) const
- {
- executor_.defer(BOOST_ASIO_MOVE_CAST(F)(f), a);
- }
- friend bool operator==(const io_object_executor& a,
- const io_object_executor& b) BOOST_ASIO_NOEXCEPT
- {
- return a.executor_ == b.executor_
- && a.has_native_impl_ == b.has_native_impl_;
- }
- friend bool operator!=(const io_object_executor& a,
- const io_object_executor& b) BOOST_ASIO_NOEXCEPT
- {
- return a.executor_ != b.executor_
- || a.has_native_impl_ != b.has_native_impl_;
- }
- private:
- Executor executor_;
- const bool has_native_impl_;
- };
- } // namespace detail
- } // namespace asio
- } // namespace boost
- #include <boost/asio/detail/pop_options.hpp>
- #endif // BOOST_ASIO_DETAIL_IO_OBJECT_EXECUTOR_HPP
|