@@ -52,22 +52,70 @@ class saved_handler::impl final : public base
5252 using alloc_traits =
5353 beast::detail::allocator_traits<alloc_type>;
5454
55- struct storage
55+ class cancel_op
5656 {
57- alloc_type a ;
58- impl* p ;
57+ impl* p_ ;
58+ net::cancellation_type accepted_ct_ ;
5959
60+ public:
61+ cancel_op (impl* p, net::cancellation_type accepted_ct)
62+ : p_(p)
63+ , accepted_ct_(accepted_ct)
64+ {
65+ }
66+
67+ void
68+ operator ()(net::cancellation_type ct)
69+ {
70+ if ((ct & accepted_ct_) != net::cancellation_type::none)
71+ p_->self_complete ();
72+ }
73+ };
74+
75+ class storage
76+ {
77+ alloc_type a_;
78+ impl* p_;
79+ bool c_;
80+
81+ public:
6082 explicit
61- storage (Alloc const & a_)
62- : a(a_)
63- , p(alloc_traits::allocate(a, 1 ))
83+ storage (Alloc const & a)
84+ : a_(a)
85+ , p_(alloc_traits::allocate(a_, 1 ))
86+ , c_(false )
6487 {
6588 }
6689
90+ template <class Handler_ >
91+ void
92+ construct (Handler_&& h, saved_handler* owner)
93+ {
94+ alloc_traits::construct (
95+ a_, p_, a_, std::forward<Handler_>(h), owner);
96+ c_ = true ;
97+ }
98+
99+ impl*
100+ get () noexcept
101+ {
102+ return p_;
103+ }
104+
105+ impl*
106+ release () noexcept
107+ {
108+ return boost::exchange (p_, nullptr );
109+ }
110+
67111 ~storage ()
68112 {
69- if (p)
70- alloc_traits::deallocate (a, p, 1 );
113+ if (p_)
114+ {
115+ if (c_)
116+ alloc_traits::destroy (a_, p_);
117+ alloc_traits::deallocate (a_, p_, 1 );
118+ }
71119 }
72120 };
73121
@@ -138,45 +186,26 @@ class saved_handler::impl final : public base
138186template <class Handler , class Allocator >
139187void
140188saved_handler::
141- emplace (Handler&& handler, Allocator const & alloc,
142- net::cancellation_type cancel_type)
189+ emplace (
190+ Handler&& handler,
191+ Allocator const & alloc,
192+ net::cancellation_type cancel_type)
143193{
144194 // Can't delete a handler before invoking
145195 BOOST_ASSERT (! has_value ());
146196 using impl_type =
147197 impl<typename std::decay<Handler>::type, Allocator>;
148198
149199 typename impl_type::storage s (alloc);
150- impl_type::alloc_traits::construct (s.a , s.p ,
151- s.a , std::forward<Handler>(handler), this );
152-
153- auto tmp = boost::exchange (s.p , nullptr );
154- p_ = tmp;
200+ auto c_slot = net::get_associated_cancellation_slot (handler);
155201
156- auto c_slot = net::get_associated_cancellation_slot (tmp->v_ .h );
157- if (c_slot.is_connected ())
158- {
159- class cancel_op
160- {
161- impl_type* p_;
162- net::cancellation_type accepted_ct_;
202+ s.construct (std::forward<Handler>(handler), this );
163203
164- public:
165- cancel_op (impl_type* p, net::cancellation_type accepted_ct)
166- : p_(p)
167- , accepted_ct_(accepted_ct)
168- {
169- }
204+ if (c_slot.is_connected ())
205+ c_slot.template emplace <
206+ typename impl_type::cancel_op>(s.get (), cancel_type);
170207
171- void
172- operator ()(net::cancellation_type ct)
173- {
174- if ((ct & accepted_ct_) != net::cancellation_type::none)
175- p_->self_complete ();
176- }
177- };
178- c_slot.template emplace <cancel_op>(tmp, cancel_type);
179- }
208+ p_ = s.release ();
180209}
181210
182211template <class Handler >
0 commit comments