Skip to content

Commit fcad5fb

Browse files
committed
Fix test::stream cancellation
1 parent 83dc972 commit fcad5fb

File tree

4 files changed

+51
-27
lines changed

4 files changed

+51
-27
lines changed

include/boost/beast2/impl/read.hpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,11 @@ class read_until_op
6464
pr_.parse(ec);
6565
if(ec == http_proto::condition::need_more_input)
6666
{
67+
if(!!self.cancelled())
68+
{
69+
ec = asio::error::operation_aborted;
70+
goto upcall;
71+
}
6772
// specific to http_io::async_read_some
6873
if(total_bytes_ != 0 && condition_(pr_))
6974
{

include/boost/beast2/test/detail/stream_state.hpp

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -116,9 +116,6 @@ struct stream_state
116116

117117
void
118118
notify_read();
119-
120-
void
121-
cancel_read();
122119
};
123120

124121
//------------------------------------------------------------------------------
@@ -236,22 +233,6 @@ notify_read()
236233
cv.notify_all();
237234
}
238235
}
239-
240-
inline
241-
void
242-
stream_state::
243-
cancel_read()
244-
{
245-
std::unique_ptr<stream_read_op_base> p;
246-
{
247-
std::lock_guard<std::mutex> lock(m);
248-
code = stream_status::eof;
249-
p = std::move(op);
250-
}
251-
if(p != nullptr)
252-
(*p)(asio::error::operation_aborted);
253-
}
254-
255236
} // detail
256237
} // test
257238
} // beast2

include/boost/beast2/test/impl/stream.hpp

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -74,10 +74,18 @@ class basic_stream<Executor>::read_op : public detail::stream_read_op_base
7474
void
7575
operator()(asio::cancellation_type type) const
7676
{
77-
if (type != asio::cancellation_type::none)
77+
if(type != asio::cancellation_type::none)
7878
{
79-
if (auto sp = wp_.lock())
80-
sp->cancel_read();
79+
if(auto sp = wp_.lock())
80+
{
81+
std::unique_ptr<stream_read_op_base> p;
82+
{
83+
std::lock_guard<std::mutex> lock(sp->m);
84+
p = std::move(sp->op);
85+
}
86+
if(p != nullptr)
87+
(*p)(asio::error::operation_aborted);
88+
}
8189
}
8290
}
8391

@@ -515,7 +523,11 @@ void
515523
basic_stream<Executor>::
516524
close()
517525
{
518-
in_->cancel_read();
526+
{
527+
std::lock_guard<std::mutex> lock(in_->m);
528+
in_->code = detail::stream_status::eof;
529+
in_->notify_read();
530+
}
519531

520532
// disconnect
521533
{

test/unit/read.cpp

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -133,18 +133,44 @@ class read_test
133133
pr.reset();
134134
pr.start();
135135

136-
// read header
136+
// async_read_some cancels after reading 0 bytes
137+
async_read_some(
138+
ts,
139+
pr,
140+
asio::bind_cancellation_slot(
141+
c_signal.slot(),
142+
[](system::error_code ec, std::size_t n)
143+
{
144+
BOOST_TEST_EQ(n, 0);
145+
BOOST_TEST_EQ(ec, asio::error::operation_aborted);
146+
}));
147+
c_signal.emit(asio::cancellation_type::total);
148+
test::run(ioc);
149+
150+
// append 8 bytes of the msg
151+
ts.append(msg.substr(0, 8));
152+
153+
// async_read_some cancels after reading 8 bytes
137154
async_read_some(
138155
ts,
139156
pr,
140157
asio::bind_cancellation_slot(
141158
c_signal.slot(),
142-
test::fail_handler(asio::error::operation_aborted)));
159+
[](system::error_code ec, std::size_t n)
160+
{
161+
BOOST_TEST_EQ(n, 8);
162+
BOOST_TEST_EQ(ec, asio::error::operation_aborted);
163+
}));
164+
c_signal.emit(asio::cancellation_type::total);
165+
test::run(ioc);
143166

144-
// send a cancellation
145-
asio::post(ioc, [&](){ c_signal.emit(asio::cancellation_type::total); });
167+
// append rest of the msg
168+
ts.append(msg.substr(8, msg.npos));
146169

170+
// async_read_some succeeds
171+
async_read_some(ts, pr, test::success_handler());
147172
test::run(ioc);
173+
BOOST_TEST(pr.got_header());
148174
}
149175
}
150176

0 commit comments

Comments
 (0)