123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673 |
- //
- // system_executor.hpp
- // ~~~~~~~~~~~~~~~~~~~
- //
- // Copyright (c) 2003-2024 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_SYSTEM_EXECUTOR_HPP
- #define BOOST_ASIO_SYSTEM_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/memory.hpp>
- #include <boost/asio/execution.hpp>
- #include <boost/asio/detail/push_options.hpp>
- namespace boost {
- namespace asio {
- class system_context;
- /// An executor that uses arbitrary threads.
- /**
- * The system executor represents an execution context where functions are
- * permitted to run on arbitrary threads. When the blocking.never property is
- * established, the system executor will schedule the function to run on an
- * unspecified system thread pool. When either blocking.possibly or
- * blocking.always is established, the executor invokes the function
- * immediately.
- */
- template <typename Blocking, typename Relationship, typename Allocator>
- class basic_system_executor
- {
- public:
- /// Default constructor.
- basic_system_executor() noexcept
- : allocator_(Allocator())
- {
- }
- #if !defined(GENERATING_DOCUMENTATION)
- private:
- friend struct boost_asio_require_fn::impl;
- friend struct boost_asio_prefer_fn::impl;
- #endif // !defined(GENERATING_DOCUMENTATION)
- /// Obtain an executor with the @c blocking.possibly property.
- /**
- * Do not call this function directly. It is intended for use with the
- * boost::asio::require customisation point.
- *
- * For example:
- * @code boost::asio::system_executor ex1;
- * auto ex2 = boost::asio::require(ex1,
- * boost::asio::execution::blocking.possibly); @endcode
- */
- basic_system_executor<execution::blocking_t::possibly_t,
- Relationship, Allocator>
- require(execution::blocking_t::possibly_t) const
- {
- return basic_system_executor<execution::blocking_t::possibly_t,
- Relationship, Allocator>(allocator_);
- }
- /// Obtain an executor with the @c blocking.always property.
- /**
- * Do not call this function directly. It is intended for use with the
- * boost::asio::require customisation point.
- *
- * For example:
- * @code boost::asio::system_executor ex1;
- * auto ex2 = boost::asio::require(ex1,
- * boost::asio::execution::blocking.always); @endcode
- */
- basic_system_executor<execution::blocking_t::always_t,
- Relationship, Allocator>
- require(execution::blocking_t::always_t) const
- {
- return basic_system_executor<execution::blocking_t::always_t,
- Relationship, Allocator>(allocator_);
- }
- /// Obtain an executor with the @c blocking.never property.
- /**
- * Do not call this function directly. It is intended for use with the
- * boost::asio::require customisation point.
- *
- * For example:
- * @code boost::asio::system_executor ex1;
- * auto ex2 = boost::asio::require(ex1,
- * boost::asio::execution::blocking.never); @endcode
- */
- basic_system_executor<execution::blocking_t::never_t,
- Relationship, Allocator>
- require(execution::blocking_t::never_t) const
- {
- return basic_system_executor<execution::blocking_t::never_t,
- Relationship, Allocator>(allocator_);
- }
- /// Obtain an executor with the @c relationship.continuation property.
- /**
- * Do not call this function directly. It is intended for use with the
- * boost::asio::require customisation point.
- *
- * For example:
- * @code boost::asio::system_executor ex1;
- * auto ex2 = boost::asio::require(ex1,
- * boost::asio::execution::relationship.continuation); @endcode
- */
- basic_system_executor<Blocking,
- execution::relationship_t::continuation_t, Allocator>
- require(execution::relationship_t::continuation_t) const
- {
- return basic_system_executor<Blocking,
- execution::relationship_t::continuation_t, Allocator>(allocator_);
- }
- /// Obtain an executor with the @c relationship.fork property.
- /**
- * Do not call this function directly. It is intended for use with the
- * boost::asio::require customisation point.
- *
- * For example:
- * @code boost::asio::system_executor ex1;
- * auto ex2 = boost::asio::require(ex1,
- * boost::asio::execution::relationship.fork); @endcode
- */
- basic_system_executor<Blocking,
- execution::relationship_t::fork_t, Allocator>
- require(execution::relationship_t::fork_t) const
- {
- return basic_system_executor<Blocking,
- execution::relationship_t::fork_t, Allocator>(allocator_);
- }
- /// Obtain an executor with the specified @c allocator property.
- /**
- * Do not call this function directly. It is intended for use with the
- * boost::asio::require customisation point.
- *
- * For example:
- * @code boost::asio::system_executor ex1;
- * auto ex2 = boost::asio::require(ex1,
- * boost::asio::execution::allocator(my_allocator)); @endcode
- */
- template <typename OtherAllocator>
- basic_system_executor<Blocking, Relationship, OtherAllocator>
- require(execution::allocator_t<OtherAllocator> a) const
- {
- return basic_system_executor<Blocking,
- Relationship, OtherAllocator>(a.value());
- }
- /// Obtain an executor with the default @c allocator property.
- /**
- * Do not call this function directly. It is intended for use with the
- * boost::asio::require customisation point.
- *
- * For example:
- * @code boost::asio::system_executor ex1;
- * auto ex2 = boost::asio::require(ex1,
- * boost::asio::execution::allocator); @endcode
- */
- basic_system_executor<Blocking, Relationship, std::allocator<void>>
- require(execution::allocator_t<void>) const
- {
- return basic_system_executor<Blocking,
- Relationship, std::allocator<void>>();
- }
- #if !defined(GENERATING_DOCUMENTATION)
- private:
- friend struct boost_asio_query_fn::impl;
- friend struct boost::asio::execution::detail::blocking_t<0>;
- friend struct boost::asio::execution::detail::mapping_t<0>;
- friend struct boost::asio::execution::detail::outstanding_work_t<0>;
- friend struct boost::asio::execution::detail::relationship_t<0>;
- #endif // !defined(GENERATING_DOCUMENTATION)
- /// Query the current value of the @c mapping property.
- /**
- * Do not call this function directly. It is intended for use with the
- * boost::asio::query customisation point.
- *
- * For example:
- * @code boost::asio::system_executor ex;
- * if (boost::asio::query(ex, boost::asio::execution::mapping)
- * == boost::asio::execution::mapping.thread)
- * ... @endcode
- */
- static constexpr execution::mapping_t query(
- execution::mapping_t) noexcept
- {
- return execution::mapping.thread;
- }
- /// Query the current value of the @c context property.
- /**
- * Do not call this function directly. It is intended for use with the
- * boost::asio::query customisation point.
- *
- * For example:
- * @code boost::asio::system_executor ex;
- * boost::asio::system_context& pool = boost::asio::query(
- * ex, boost::asio::execution::context); @endcode
- */
- static system_context& query(execution::context_t) noexcept;
- /// Query the current value of the @c blocking property.
- /**
- * Do not call this function directly. It is intended for use with the
- * boost::asio::query customisation point.
- *
- * For example:
- * @code boost::asio::system_executor ex;
- * if (boost::asio::query(ex, boost::asio::execution::blocking)
- * == boost::asio::execution::blocking.always)
- * ... @endcode
- */
- static constexpr execution::blocking_t query(
- execution::blocking_t) noexcept
- {
- return Blocking();
- }
- /// Query the current value of the @c relationship property.
- /**
- * Do not call this function directly. It is intended for use with the
- * boost::asio::query customisation point.
- *
- * For example:
- * @code boost::asio::system_executor ex;
- * if (boost::asio::query(ex, boost::asio::execution::relationship)
- * == boost::asio::execution::relationship.continuation)
- * ... @endcode
- */
- static constexpr execution::relationship_t query(
- execution::relationship_t) noexcept
- {
- return Relationship();
- }
- /// Query the current value of the @c allocator property.
- /**
- * Do not call this function directly. It is intended for use with the
- * boost::asio::query customisation point.
- *
- * For example:
- * @code boost::asio::system_executor ex;
- * auto alloc = boost::asio::query(ex,
- * boost::asio::execution::allocator); @endcode
- */
- template <typename OtherAllocator>
- constexpr Allocator query(
- execution::allocator_t<OtherAllocator>) const noexcept
- {
- return allocator_;
- }
- /// Query the current value of the @c allocator property.
- /**
- * Do not call this function directly. It is intended for use with the
- * boost::asio::query customisation point.
- *
- * For example:
- * @code boost::asio::system_executor ex;
- * auto alloc = boost::asio::query(ex,
- * boost::asio::execution::allocator); @endcode
- */
- constexpr Allocator query(
- execution::allocator_t<void>) const noexcept
- {
- return allocator_;
- }
- /// Query the occupancy (recommended number of work items) for the system
- /// context.
- /**
- * Do not call this function directly. It is intended for use with the
- * boost::asio::query customisation point.
- *
- * For example:
- * @code boost::asio::system_executor ex;
- * std::size_t occupancy = boost::asio::query(
- * ex, boost::asio::execution::occupancy); @endcode
- */
- std::size_t query(execution::occupancy_t) const noexcept;
- public:
- /// Compare two executors for equality.
- /**
- * Two executors are equal if they refer to the same underlying io_context.
- */
- friend bool operator==(const basic_system_executor&,
- const basic_system_executor&) noexcept
- {
- return true;
- }
- /// Compare two executors for inequality.
- /**
- * Two executors are equal if they refer to the same underlying io_context.
- */
- friend bool operator!=(const basic_system_executor&,
- const basic_system_executor&) noexcept
- {
- return false;
- }
- /// Execution function.
- template <typename Function>
- void execute(Function&& f) const
- {
- this->do_execute(static_cast<Function&&>(f), Blocking());
- }
- #if !defined(BOOST_ASIO_NO_TS_EXECUTORS)
- public:
- /// Obtain the underlying execution context.
- system_context& context() const noexcept;
- /// Inform the executor that it has some outstanding work to do.
- /**
- * For the system executor, this is a no-op.
- */
- void on_work_started() const noexcept
- {
- }
- /// Inform the executor that some work is no longer outstanding.
- /**
- * For the system executor, this is a no-op.
- */
- void on_work_finished() const noexcept
- {
- }
- /// Request the system executor to invoke the given function object.
- /**
- * This function is used to ask the executor to execute the given function
- * object. The function object will always be executed inside this function.
- *
- * @param f The function object to be called. The executor will make
- * a copy of the handler object as required. The function signature of the
- * function object must be: @code void function(); @endcode
- *
- * @param a An allocator that may be used by the executor to allocate the
- * internal storage needed for function invocation.
- */
- template <typename Function, typename OtherAllocator>
- void dispatch(Function&& f, const OtherAllocator& a) const;
- /// Request the system executor to invoke the given function object.
- /**
- * This function is used to ask the executor to execute the given function
- * object. The function object will never be executed inside this function.
- * Instead, it will be scheduled to run on an unspecified system thread pool.
- *
- * @param f The function object to be called. The executor will make
- * a copy of the handler object as required. The function signature of the
- * function object must be: @code void function(); @endcode
- *
- * @param a An allocator that may be used by the executor to allocate the
- * internal storage needed for function invocation.
- */
- template <typename Function, typename OtherAllocator>
- void post(Function&& f, const OtherAllocator& a) const;
- /// Request the system executor to invoke the given function object.
- /**
- * This function is used to ask the executor to execute the given function
- * object. The function object will never be executed inside this function.
- * Instead, it will be scheduled to run on an unspecified system thread pool.
- *
- * @param f The function object to be called. The executor will make
- * a copy of the handler object as required. The function signature of the
- * function object must be: @code void function(); @endcode
- *
- * @param a An allocator that may be used by the executor to allocate the
- * internal storage needed for function invocation.
- */
- template <typename Function, typename OtherAllocator>
- void defer(Function&& f, const OtherAllocator& a) const;
- #endif // !defined(BOOST_ASIO_NO_TS_EXECUTORS)
- private:
- template <typename, typename, typename> friend class basic_system_executor;
- // Constructor used by require().
- basic_system_executor(const Allocator& a)
- : allocator_(a)
- {
- }
- /// Execution helper implementation for the possibly blocking property.
- template <typename Function>
- void do_execute(Function&& f,
- execution::blocking_t::possibly_t) const;
- /// Execution helper implementation for the always blocking property.
- template <typename Function>
- void do_execute(Function&& f,
- execution::blocking_t::always_t) const;
- /// Execution helper implementation for the never blocking property.
- template <typename Function>
- void do_execute(Function&& f,
- execution::blocking_t::never_t) const;
- // The allocator used for execution functions.
- Allocator allocator_;
- };
- /// An executor that uses arbitrary threads.
- /**
- * The system executor represents an execution context where functions are
- * permitted to run on arbitrary threads. When the blocking.never property is
- * established, the system executor will schedule the function to run on an
- * unspecified system thread pool. When either blocking.possibly or
- * blocking.always is established, the executor invokes the function
- * immediately.
- */
- typedef basic_system_executor<execution::blocking_t::possibly_t,
- execution::relationship_t::fork_t, std::allocator<void>>
- system_executor;
- #if !defined(GENERATING_DOCUMENTATION)
- namespace traits {
- #if !defined(BOOST_ASIO_HAS_DEDUCED_EQUALITY_COMPARABLE_TRAIT)
- template <typename Blocking, typename Relationship, typename Allocator>
- struct equality_comparable<
- boost::asio::basic_system_executor<Blocking, Relationship, Allocator>
- >
- {
- static constexpr bool is_valid = true;
- static constexpr bool is_noexcept = true;
- };
- #endif // !defined(BOOST_ASIO_HAS_DEDUCED_EQUALITY_COMPARABLE_TRAIT)
- #if !defined(BOOST_ASIO_HAS_DEDUCED_EXECUTE_MEMBER_TRAIT)
- template <typename Blocking, typename Relationship,
- typename Allocator, typename Function>
- struct execute_member<
- boost::asio::basic_system_executor<Blocking, Relationship, Allocator>,
- Function
- >
- {
- static constexpr bool is_valid = true;
- static constexpr bool is_noexcept = false;
- typedef void result_type;
- };
- #endif // !defined(BOOST_ASIO_HAS_DEDUCED_EXECUTE_MEMBER_TRAIT)
- #if !defined(BOOST_ASIO_HAS_DEDUCED_REQUIRE_MEMBER_TRAIT)
- template <typename Blocking, typename Relationship, typename Allocator>
- struct require_member<
- boost::asio::basic_system_executor<Blocking, Relationship, Allocator>,
- boost::asio::execution::blocking_t::possibly_t
- >
- {
- static constexpr bool is_valid = true;
- static constexpr bool is_noexcept = false;
- typedef boost::asio::basic_system_executor<
- boost::asio::execution::blocking_t::possibly_t,
- Relationship, Allocator> result_type;
- };
- template <typename Blocking, typename Relationship, typename Allocator>
- struct require_member<
- boost::asio::basic_system_executor<Blocking, Relationship, Allocator>,
- boost::asio::execution::blocking_t::always_t
- >
- {
- static constexpr bool is_valid = true;
- static constexpr bool is_noexcept = false;
- typedef boost::asio::basic_system_executor<
- boost::asio::execution::blocking_t::always_t,
- Relationship, Allocator> result_type;
- };
- template <typename Blocking, typename Relationship, typename Allocator>
- struct require_member<
- boost::asio::basic_system_executor<Blocking, Relationship, Allocator>,
- boost::asio::execution::blocking_t::never_t
- >
- {
- static constexpr bool is_valid = true;
- static constexpr bool is_noexcept = false;
- typedef boost::asio::basic_system_executor<
- boost::asio::execution::blocking_t::never_t,
- Relationship, Allocator> result_type;
- };
- template <typename Blocking, typename Relationship, typename Allocator>
- struct require_member<
- boost::asio::basic_system_executor<Blocking, Relationship, Allocator>,
- boost::asio::execution::relationship_t::fork_t
- >
- {
- static constexpr bool is_valid = true;
- static constexpr bool is_noexcept = false;
- typedef boost::asio::basic_system_executor<Blocking,
- boost::asio::execution::relationship_t::fork_t,
- Allocator> result_type;
- };
- template <typename Blocking, typename Relationship, typename Allocator>
- struct require_member<
- boost::asio::basic_system_executor<Blocking, Relationship, Allocator>,
- boost::asio::execution::relationship_t::continuation_t
- >
- {
- static constexpr bool is_valid = true;
- static constexpr bool is_noexcept = false;
- typedef boost::asio::basic_system_executor<Blocking,
- boost::asio::execution::relationship_t::continuation_t,
- Allocator> result_type;
- };
- template <typename Blocking, typename Relationship, typename Allocator>
- struct require_member<
- boost::asio::basic_system_executor<Blocking, Relationship, Allocator>,
- boost::asio::execution::allocator_t<void>
- >
- {
- static constexpr bool is_valid = true;
- static constexpr bool is_noexcept = false;
- typedef boost::asio::basic_system_executor<Blocking,
- Relationship, std::allocator<void>> result_type;
- };
- template <typename Blocking, typename Relationship,
- typename Allocator, typename OtherAllocator>
- struct require_member<
- boost::asio::basic_system_executor<Blocking, Relationship, Allocator>,
- boost::asio::execution::allocator_t<OtherAllocator>
- >
- {
- static constexpr bool is_valid = true;
- static constexpr bool is_noexcept = false;
- typedef boost::asio::basic_system_executor<Blocking,
- Relationship, OtherAllocator> result_type;
- };
- #endif // !defined(BOOST_ASIO_HAS_DEDUCED_REQUIRE_MEMBER_TRAIT)
- #if !defined(BOOST_ASIO_HAS_DEDUCED_QUERY_STATIC_CONSTEXPR_MEMBER_TRAIT)
- template <typename Blocking, typename Relationship,
- typename Allocator, typename Property>
- struct query_static_constexpr_member<
- boost::asio::basic_system_executor<Blocking, Relationship, Allocator>,
- Property,
- typename boost::asio::enable_if<
- boost::asio::is_convertible<
- Property,
- boost::asio::execution::mapping_t
- >::value
- >::type
- >
- {
- static constexpr bool is_valid = true;
- static constexpr bool is_noexcept = true;
- typedef boost::asio::execution::mapping_t::thread_t result_type;
- static constexpr result_type value() noexcept
- {
- return result_type();
- }
- };
- #endif // !defined(BOOST_ASIO_HAS_DEDUCED_QUERY_STATIC_CONSTEXPR_MEMBER_TRAIT)
- #if !defined(BOOST_ASIO_HAS_DEDUCED_QUERY_MEMBER_TRAIT)
- template <typename Blocking, typename Relationship,
- typename Allocator, typename Property>
- struct query_member<
- boost::asio::basic_system_executor<Blocking, Relationship, Allocator>,
- Property,
- typename boost::asio::enable_if<
- boost::asio::is_convertible<
- Property,
- boost::asio::execution::blocking_t
- >::value
- >::type
- >
- {
- static constexpr bool is_valid = true;
- static constexpr bool is_noexcept = true;
- typedef boost::asio::execution::blocking_t result_type;
- };
- template <typename Blocking, typename Relationship,
- typename Allocator, typename Property>
- struct query_member<
- boost::asio::basic_system_executor<Blocking, Relationship, Allocator>,
- Property,
- typename boost::asio::enable_if<
- boost::asio::is_convertible<
- Property,
- boost::asio::execution::relationship_t
- >::value
- >::type
- >
- {
- static constexpr bool is_valid = true;
- static constexpr bool is_noexcept = true;
- typedef boost::asio::execution::relationship_t result_type;
- };
- template <typename Blocking, typename Relationship, typename Allocator>
- struct query_member<
- boost::asio::basic_system_executor<Blocking, Relationship, Allocator>,
- boost::asio::execution::context_t
- >
- {
- static constexpr bool is_valid = true;
- static constexpr bool is_noexcept = true;
- typedef boost::asio::system_context& result_type;
- };
- template <typename Blocking, typename Relationship, typename Allocator>
- struct query_member<
- boost::asio::basic_system_executor<Blocking, Relationship, Allocator>,
- boost::asio::execution::allocator_t<void>
- >
- {
- static constexpr bool is_valid = true;
- static constexpr bool is_noexcept = true;
- typedef Allocator result_type;
- };
- template <typename Blocking, typename Relationship, typename Allocator>
- struct query_member<
- boost::asio::basic_system_executor<Blocking, Relationship, Allocator>,
- boost::asio::execution::allocator_t<Allocator>
- >
- {
- static constexpr bool is_valid = true;
- static constexpr bool is_noexcept = true;
- typedef Allocator result_type;
- };
- #endif // !defined(BOOST_ASIO_HAS_DEDUCED_QUERY_MEMBER_TRAIT)
- } // namespace traits
- #endif // !defined(GENERATING_DOCUMENTATION)
- } // namespace asio
- } // namespace boost
- #include <boost/asio/detail/pop_options.hpp>
- #include <boost/asio/impl/system_executor.hpp>
- #endif // BOOST_ASIO_SYSTEM_EXECUTOR_HPP
|