1//
2// cancellation_state.hpp
3// ~~~~~~~~~~~~~~~~~~~~~~
4//
5// Copyright (c) 2003-2024 Christopher M. Kohlhoff (chris at kohlhoff dot com)
6//
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)
9//
10
11#ifndef BOOST_ASIO_CANCELLATION_STATE_HPP
12#define BOOST_ASIO_CANCELLATION_STATE_HPP
13
14#if defined(_MSC_VER) && (_MSC_VER >= 1200)
15# pragma once
16#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
17
18#include <boost/asio/detail/config.hpp>
19#include <cassert>
20#include <new>
21#include <utility>
22#include <boost/asio/cancellation_signal.hpp>
23#include <boost/asio/detail/cstddef.hpp>
24
25#include <boost/asio/detail/push_options.hpp>
26
27namespace boost {
28namespace asio {
29
30/// A simple cancellation signal propagation filter.
31template <cancellation_type_t Mask>
32struct cancellation_filter
33{
34 /// Returns <tt>type & Mask</tt>.
35 cancellation_type_t operator()(
36 cancellation_type_t type) const noexcept
37 {
38 return type & Mask;
39 }
40};
41
42/// A cancellation filter that disables cancellation.
43typedef cancellation_filter<cancellation_type::none>
44 disable_cancellation;
45
46/// A cancellation filter that enables terminal cancellation only.
47typedef cancellation_filter<cancellation_type::terminal>
48 enable_terminal_cancellation;
49
50#if defined(GENERATING_DOCUMENTATION)
51
52/// A cancellation filter that enables terminal and partial cancellation.
53typedef cancellation_filter<
54 cancellation_type::terminal | cancellation_type::partial>
55 enable_partial_cancellation;
56
57/// A cancellation filter that enables terminal, partial and total cancellation.
58typedef cancellation_filter<cancellation_type::terminal
59 | cancellation_type::partial | cancellation_type::total>
60 enable_total_cancellation;
61
62#else // defined(GENERATING_DOCUMENTATION)
63
64typedef cancellation_filter<
65 static_cast<cancellation_type_t>(
66 static_cast<unsigned int>(cancellation_type::terminal)
67 | static_cast<unsigned int>(cancellation_type::partial))>
68 enable_partial_cancellation;
69
70typedef cancellation_filter<
71 static_cast<cancellation_type_t>(
72 static_cast<unsigned int>(cancellation_type::terminal)
73 | static_cast<unsigned int>(cancellation_type::partial)
74 | static_cast<unsigned int>(cancellation_type::total))>
75 enable_total_cancellation;
76
77#endif // defined(GENERATING_DOCUMENTATION)
78
79/// A cancellation state is used for chaining signals and slots in compositions.
80class cancellation_state
81{
82public:
83 /// Construct a disconnected cancellation state.
84 constexpr cancellation_state() noexcept
85 : impl_(0)
86 {
87 }
88
89 /// Construct and attach to a parent slot to create a new child slot.
90 /**
91 * Initialises the cancellation state so that it allows terminal cancellation
92 * only. Equivalent to <tt>cancellation_state(slot,
93 * enable_terminal_cancellation())</tt>.
94 *
95 * @param slot The parent cancellation slot to which the state will be
96 * attached.
97 */
98 template <typename CancellationSlot>
99 constexpr explicit cancellation_state(CancellationSlot slot)
100 : impl_(slot.is_connected() ? &slot.template emplace<impl<>>() : 0)
101 {
102 }
103
104 /// Construct and attach to a parent slot to create a new child slot.
105 /**
106 * @param slot The parent cancellation slot to which the state will be
107 * attached.
108 *
109 * @param filter A function object that is used to transform incoming
110 * cancellation signals as they are received from the parent slot. This
111 * function object must have the signature:
112 * @code boost::asio::cancellation_type_t filter(
113 * boost::asio::cancellation_type_t); @endcode
114 *
115 * The library provides the following pre-defined cancellation filters:
116 *
117 * @li boost::asio::disable_cancellation
118 * @li boost::asio::enable_terminal_cancellation
119 * @li boost::asio::enable_partial_cancellation
120 * @li boost::asio::enable_total_cancellation
121 */
122 template <typename CancellationSlot, typename Filter>
123 constexpr cancellation_state(CancellationSlot slot, Filter filter)
124 : impl_(slot.is_connected()
125 ? &slot.template emplace<impl<Filter, Filter>>(filter, filter)
126 : 0)
127 {
128 }
129
130 /// Construct and attach to a parent slot to create a new child slot.
131 /**
132 * @param slot The parent cancellation slot to which the state will be
133 * attached.
134 *
135 * @param in_filter A function object that is used to transform incoming
136 * cancellation signals as they are received from the parent slot. This
137 * function object must have the signature:
138 * @code boost::asio::cancellation_type_t in_filter(
139 * boost::asio::cancellation_type_t); @endcode
140 *
141 * @param out_filter A function object that is used to transform outcoming
142 * cancellation signals as they are relayed to the child slot. This function
143 * object must have the signature:
144 * @code boost::asio::cancellation_type_t out_filter(
145 * boost::asio::cancellation_type_t); @endcode
146 *
147 * The library provides the following pre-defined cancellation filters:
148 *
149 * @li boost::asio::disable_cancellation
150 * @li boost::asio::enable_terminal_cancellation
151 * @li boost::asio::enable_partial_cancellation
152 * @li boost::asio::enable_total_cancellation
153 */
154 template <typename CancellationSlot, typename InFilter, typename OutFilter>
155 constexpr cancellation_state(CancellationSlot slot,
156 InFilter in_filter, OutFilter out_filter)
157 : impl_(slot.is_connected()
158 ? &slot.template emplace<impl<InFilter, OutFilter>>(
159 static_cast<InFilter&&>(in_filter),
160 static_cast<OutFilter&&>(out_filter))
161 : 0)
162 {
163 }
164
165 /// Returns the single child slot associated with the state.
166 /**
167 * This sub-slot is used with the operations that are being composed.
168 */
169 constexpr cancellation_slot slot() const noexcept
170 {
171 return impl_ ? impl_->signal_.slot() : cancellation_slot();
172 }
173
174 /// Returns the cancellation types that have been triggered.
175 cancellation_type_t cancelled() const noexcept
176 {
177 return impl_ ? impl_->cancelled_ : cancellation_type_t();
178 }
179
180 /// Clears the specified cancellation types, if they have been triggered.
181 void clear(cancellation_type_t mask = cancellation_type::all)
182 noexcept
183 {
184 if (impl_)
185 impl_->cancelled_ &= ~mask;
186 }
187
188private:
189 struct impl_base
190 {
191 impl_base()
192 : cancelled_()
193 {
194 }
195
196 cancellation_signal signal_;
197 cancellation_type_t cancelled_;
198 };
199
200 template <
201 typename InFilter = enable_terminal_cancellation,
202 typename OutFilter = InFilter>
203 struct impl : impl_base
204 {
205 impl()
206 : in_filter_(),
207 out_filter_()
208 {
209 }
210
211 impl(InFilter in_filter, OutFilter out_filter)
212 : in_filter_(static_cast<InFilter&&>(in_filter)),
213 out_filter_(static_cast<OutFilter&&>(out_filter))
214 {
215 }
216
217 void operator()(cancellation_type_t in)
218 {
219 this->cancelled_ = in_filter_(in);
220 cancellation_type_t out = out_filter_(this->cancelled_);
221 if (out != cancellation_type::none)
222 this->signal_.emit(out);
223 }
224
225 InFilter in_filter_;
226 OutFilter out_filter_;
227 };
228
229 impl_base* impl_;
230};
231
232} // namespace asio
233} // namespace boost
234
235#include <boost/asio/detail/pop_options.hpp>
236
237#endif // BOOST_ASIO_CANCELLATION_STATE_HPP
238

source code of boost/libs/asio/include/boost/asio/cancellation_state.hpp