• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1[/
2 / Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
3 /
4 / Distributed under the Boost Software License, Version 1.0. (See accompanying
5 / file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 /]
7
8[section:std_executors Proposed Standard Executors]
9
10Boost.Asio provides a complete implementation of the proposed standard executors, as
11described in [@http://wg21.link/P0443r13 P0443r13], [@http://wg21.link/P1348r0
12P1348r0], and [@http://wg21.link/P1393r0 P1393r0].
13
14Just as with executors under the Networking TS model, a standard executor
15represents a policy as to how, when, and where a piece of code should be
16executed. Most existing code should continue to work with little or no change.
17
18[heading Standard Executor Implementations in Boost.Asio]
19
20The [link boost_asio.reference.io_context.executor_type `io_context::executor_type`],
21[link boost_asio.reference.thread_pool.executor_type `thread_pool::executor_type`],
22[link boost_asio.reference.system_executor `system_executor`], and [link
23boost_asio.reference.strand `strand`] executors meet the requirements for the
24proposed standard executors. For compatibility, these classes also meet the
25requirements for the Networking TS model of executors.
26
27[heading Standard Executor Use in Boost.Asio]
28
29All I/O objects such as [link boost_asio.reference.ip__tcp.socket `ip::tcp::socket`],
30asynchronous operations, and utilities including [link boost_asio.reference.dispatch
31`dispatch`], [link boost_asio.reference.post `post`], [link boost_asio.reference.defer
32`defer`], [link boost_asio.reference.get_associated_executor
33`get_associated_executor`], [link boost_asio.reference.bind_executor
34`bind_executor`], [link boost_asio.reference.make_work_guard `make_work_guard`],
35[link boost_asio.reference.spawn `spawn`], [link boost_asio.reference.co_spawn `co_spawn`],
36[link boost_asio.reference.async_compose `async_compose`], [link
37boost_asio.reference.use_future `use_future`], etc., can interoperate with both
38proposed standard executors, and with Networking TS executors. Boost.Asio's
39implementation determines at compile time which model a particular executor
40meets; the proposed standard executor model is used in preference if both are
41detected.
42
43Support for the existing Networking TS model of executors can be disabled
44by defining `BOOST_ASIO_NO_TS_EXECUTORS`.
45
46[heading Polymorphic I/O Executor]
47
48The [link boost_asio.reference.any_io_executor `any_io_executor`] type alias is the
49default runtime-polymorphic executor for all I/O objects. This type alias
50points to the [link boost_asio.reference.execution__any_executor
51`execution::any_executor<>`] template with a set of supportable properties
52specified for use with I/O.
53
54This new name may break existing code that directly uses the old polymorphic
55wrapper, [link boost_asio.reference.executor `executor`]. If required for backward
56compatibility, `BOOST_ASIO_USE_TS_EXECUTOR_AS_DEFAULT` can be defined, which changes
57the `any_io_executor` type alias to instead point to the `executor` polymorphic
58wrapper.
59
60[heading Implementing a Minimal I/O Executor]
61
62Standard executor properties make what were previously hard requirements on an
63executor (such as work counting, or the ability to distinguish between `post`,
64`dispatch`, and `defer`) into optional facilities. With this relaxation, the
65minimal requirements for an I/O executor are:
66
67* Conformance to the [link boost_asio.reference.Executor1.standard_executors
68  `executor`] concept.
69
70* The ability to query the [link boost_asio.reference.execution__context
71  `execution::context`] property, with the result being [link
72  boost_asio.reference.execution_context `execution_context&`] or a reference to a
73  class that is derived from `execution_context`.
74
75* The `execute` operation having, at minimum, the [link
76  boost_asio.reference.execution__blocking_t.never `execution::blocking.never`]
77  semantic.
78
79The following example shows a minimal I/O executor. Given a queue submission
80operation implemented elsewhere:
81
82```
83queue_t queue_create();
84template <typename F> void queue_submit(queue_t q, F f);
85```
86
87the executor may be defined as follows:
88
89```
90struct minimal_io_executor
91{
92  boost::asio::execution_context* context_;
93  queue_t queue_;
94
95  bool operator==(const minimal_io_executor& other) const noexcept
96  {
97    return context_ == other.context_ && queue_ == other.queue_;
98  }
99
100  bool operator!=(const minimal_io_executor& other) const noexcept
101  {
102    return !(*this == other);
103  }
104
105  boost::asio::execution_context& query(
106      boost::asio::execution::context_t) const noexcept
107  {
108    return *context_;
109  }
110
111  static constexpr boost::asio::execution::blocking_t::never_t query(
112      boost::asio::execution::blocking_t) noexcept
113  {
114    // This executor always has blocking.never semantics.
115    return boost::asio::execution::blocking.never;
116  }
117
118  template <class F>
119  void execute(F f) const
120  {
121    queue_submit(queue_, std::move(f));
122  }
123};
124```
125
126This executor may be created as follows:
127
128```
129boost::asio::execution_context context;
130queue_t queue = queue_create();
131minimal_io_executor executor{&context, queue};
132```
133
134and then used with I/O objects:
135
136```
137boost::asio::ip::tcp::acceptor acceptor(executor);
138```
139
140or assigned into the [link boost_asio.reference.any_io_executor `any_io_executor`]
141polymorphic wrapper:
142
143```
144boost::asio::any_io_executor poly_executor = executor;
145```
146
147[heading Traits for Deducing Conformance to the Executor Concept]
148
149Older C++ standards and compilers require some assistance to determine whether
150an executor implementation conforms to the `executor` concept and type
151requirements. This is achieved through specialisation of traits. The following
152code shows a specialisation of these traits for the `minimal_io_executor`
153example from above:
154
155```
156namespace boost { namespace asio {
157namespace traits {
158
159#if !defined(BOOST_ASIO_HAS_DEDUCED_EXECUTE_MEMBER_TRAIT)
160
161template <typename F>
162struct execute_member<minimal_io_executor, F>
163{
164  static constexpr bool is_valid = true;
165  static constexpr bool is_noexcept = true;
166  typedef void result_type;
167};
168
169#endif // !defined(BOOST_ASIO_HAS_DEDUCED_EXECUTE_MEMBER_TRAIT)
170#if !defined(BOOST_ASIO_HAS_DEDUCED_EQUALITY_COMPARABLE_TRAIT)
171
172template <>
173struct equality_comparable<minimal_io_executor>
174{
175  static constexpr bool is_valid = true;
176  static constexpr bool is_noexcept = true;
177};
178
179#endif // !defined(BOOST_ASIO_HAS_DEDUCED_EQUALITY_COMPARABLE_TRAIT)
180#if !defined(BOOST_ASIO_HAS_DEDUCED_QUERY_MEMBER_TRAIT)
181
182template <>
183struct query_member<minimal_io_executor,
184    boost::asio::execution::context_t>
185{
186  static constexpr bool is_valid = true;
187  static constexpr bool is_noexcept = true;
188  typedef boost::asio::execution_context& result_type;
189};
190
191#endif // !defined(BOOST_ASIO_HAS_DEDUCED_QUERY_MEMBER_TRAIT)
192#if !defined(BOOST_ASIO_HAS_DEDUCED_QUERY_STATIC_CONSTEXPR_MEMBER_TRAIT)
193
194template <typename Property>
195struct query_static_constexpr_member<minimal_io_executor, Property,
196    typename enable_if<
197      std::is_convertible<Property, boost::asio::execution::blocking_t>::value
198    >::type>
199{
200  static constexpr bool is_valid = true;
201  static constexpr bool is_noexcept = true;
202  typedef boost::asio::execution::blocking_t::never_t result_type;
203  static constexpr result_type value() noexcept { return result_type(); }
204};
205
206#endif // !defined(BOOST_ASIO_HAS_DEDUCED_QUERY_STATIC_CONSTEXPR_MEMBER_TRAIT)
207
208} // namespace traits
209} } // namespace boost::asio
210```
211
212Boost.Asio uses an extensive set of traits to implement all of the proposed standard
213executor functionality on older C++ standards. These traits may be found under
214the [^boost/asio/traits] include directory.
215
216[endsect]
217