Don't copy completion handlers:

All asynchronous operations will now be able to use move-only
CompletionHandlers.

Signed-off-by: Damian Jarek <damian.jarek93@gmail.com>
This commit is contained in:
Damian Jarek
2017-12-02 12:59:30 +01:00
committed by Vinnie Falco
parent 3361df142c
commit 200e898f7e
15 changed files with 69 additions and 75 deletions

View File

@ -5,6 +5,7 @@ Version 149:
* Fix CMakeLists.txt variable
* Protect calls from macros
* pausation always allocates
* Don't copy completion handlers
--------------------------------------------------------------------------------

View File

@ -109,7 +109,7 @@ public:
boost::asio::associated_allocator_t<Handler>;
bound_handler(bound_handler&&) = default;
bound_handler(bound_handler const&) = default;
bound_handler(bound_handler const&) = delete;
template<class DeducedHandler>
explicit

View File

@ -37,7 +37,7 @@ class buffered_read_stream<
public:
read_some_op(read_some_op&&) = default;
read_some_op(read_some_op const&) = default;
read_some_op(read_some_op const&) = delete;
template<class DeducedHandler, class... Args>
read_some_op(DeducedHandler&& h,
@ -237,7 +237,7 @@ async_read_some(
void(error_code, std::size_t)> init{handler};
read_some_op<MutableBufferSequence, BOOST_ASIO_HANDLER_TYPE(
ReadHandler, void(error_code, std::size_t))>{
init.completion_handler, *this, buffers}(
std::move(init.completion_handler), *this, buffers}(
error_code{}, 0);
return init.result.get();
}

View File

@ -52,7 +52,7 @@ template<class T, class Signature>
using is_completion_handler = std::integral_constant<bool, ...>;
#else
using is_completion_handler = std::integral_constant<bool,
std::is_copy_constructible<typename std::decay<T>::type>::value &&
std::is_move_constructible<typename std::decay<T>::type>::value &&
detail::is_invocable<T, Signature>::value>;
#endif

View File

@ -344,7 +344,7 @@ class write_some_win32_op
public:
write_some_win32_op(write_some_win32_op&&) = default;
write_some_win32_op(write_some_win32_op const&) = default;
write_some_win32_op(write_some_win32_op const&) = delete;
template<class DeducedHandler>
write_some_win32_op(
@ -422,7 +422,10 @@ operator()()
(std::min<std::uint64_t>)(r.body_.last_ - r.pos_, sr_.limit()),
(std::numeric_limits<boost::winapi::DWORD_>::max)()));
boost::asio::windows::overlapped_ptr overlapped{
sock_.get_executor().context(), *this};
sock_.get_executor().context(), std::move(*this)};
// Note that we have moved *this, so we cannot access
// the handler since it is now moved-from. We can still
// access simple things like references and built-in types.
auto& ov = *overlapped.get();
ov.Offset = lowPart(r.pos_);
ov.OffsetHigh = highPart(r.pos_);
@ -569,7 +572,7 @@ async_write_some(
BOOST_ASIO_HANDLER_TYPE(WriteHandler,
void(error_code, std::size_t)),
isRequest, Fields>{
init.completion_handler, sock, sr}();
std::move(init.completion_handler), sock, sr}();
return init.result.get();
}

View File

@ -50,7 +50,7 @@ class read_some_op
public:
read_some_op(read_some_op&&) = default;
read_some_op(read_some_op const&) = default;
read_some_op(read_some_op const&) = delete;
template<class DeducedHandler>
read_some_op(DeducedHandler&& h, Stream& s,
@ -208,7 +208,7 @@ class read_op
public:
read_op(read_op&&) = default;
read_op(read_op const&) = default;
read_op(read_op const&) = delete;
template<class DeducedHandler>
read_op(DeducedHandler&& h, Stream& s,
@ -331,7 +331,7 @@ class read_msg_op
public:
read_msg_op(read_msg_op&&) = default;
read_msg_op(read_msg_op const&) = default;
read_msg_op(read_msg_op const&) = delete;
template<class DeducedHandler, class... Args>
read_msg_op(DeducedHandler&& h, Stream& s, Args&&... args)
@ -531,7 +531,7 @@ async_read_some(
detail::read_some_op<AsyncReadStream,
DynamicBuffer, isRequest, Derived, BOOST_ASIO_HANDLER_TYPE(
ReadHandler, void(error_code, std::size_t))>{
init.completion_handler, stream, buffer, parser}(
std::move(init.completion_handler), stream, buffer, parser}(
{}, 0, false);
return init.result.get();
}
@ -619,8 +619,8 @@ async_read_header(
detail::read_op<AsyncReadStream, DynamicBuffer,
isRequest, Derived, detail::parser_is_header_done,
BOOST_ASIO_HANDLER_TYPE(ReadHandler, void(error_code, std::size_t))>{
init.completion_handler, stream, buffer, parser}(
{}, 0, false);
std::move(init.completion_handler), stream,
buffer, parser}({}, 0, false);
return init.result.get();
}
@ -708,7 +708,7 @@ async_read(
detail::read_op<AsyncReadStream, DynamicBuffer,
isRequest, Derived, detail::parser_is_done,
BOOST_ASIO_HANDLER_TYPE(ReadHandler, void(error_code, std::size_t))>{
init.completion_handler, stream, buffer, parser}(
std::move(init.completion_handler), stream, buffer, parser}(
{}, 0, false);
return init.result.get();
}
@ -803,7 +803,7 @@ async_read(
isRequest, Body, Allocator,
BOOST_ASIO_HANDLER_TYPE(
ReadHandler, void(error_code, std::size_t))>{
init.completion_handler, stream, buffer, msg}(
std::move(init.completion_handler), stream, buffer, msg}(
{}, 0, false);
return init.result.get();
}

View File

@ -67,7 +67,7 @@ class write_some_op
public:
write_some_op(write_some_op&&) = default;
write_some_op(write_some_op const&) = default;
write_some_op(write_some_op const&) = delete;
template<class DeducedHandler>
write_some_op(DeducedHandler&& h, Stream& s,
@ -203,7 +203,7 @@ class write_op
public:
write_op(write_op&&) = default;
write_op(write_op const&) = default;
write_op(write_op const&) = delete;
template<class DeducedHandler>
write_op(DeducedHandler&& h, Stream& s,
@ -318,7 +318,7 @@ class write_msg_op
public:
write_msg_op(write_msg_op&&) = default;
write_msg_op(write_msg_op const&) = default;
write_msg_op(write_msg_op const&) = delete;
template<class DeducedHandler, class... Args>
write_msg_op(DeducedHandler&& h, Stream& s, Args&&... args)
@ -479,7 +479,7 @@ async_write_some_impl(
BOOST_ASIO_HANDLER_TYPE(WriteHandler,
void(error_code, std::size_t)),
isRequest, Body, Fields>{
init.completion_handler, stream, sr}();
std::move(init.completion_handler), stream, sr}();
return init.result.get();
}
@ -638,7 +638,7 @@ async_write_header(
void(error_code, std::size_t)),
detail::serializer_is_header_done,
isRequest, Body, Fields>{
init.completion_handler, stream, sr}();
std::move(init.completion_handler), stream, sr}();
return init.result.get();
}
@ -715,7 +715,7 @@ async_write(
void(error_code, std::size_t)),
detail::serializer_is_done,
isRequest, Body, Fields>{
init.completion_handler, stream, sr}();
std::move(init.completion_handler), stream, sr}();
return init.result.get();
}
@ -788,7 +788,7 @@ async_write(
BOOST_ASIO_HANDLER_TYPE(WriteHandler,
void(error_code, std::size_t)),
isRequest, Body, Fields>{
init.completion_handler, stream, msg}();
std::move(init.completion_handler), stream, msg}();
return init.result.get();
}

View File

@ -58,7 +58,7 @@ class stream<NextLayer>::response_op
public:
response_op(response_op&&) = default;
response_op(response_op const&) = default;
response_op(response_op const&) = delete;
template<class DeducedHandler, class... Args>
response_op(DeducedHandler&& h,
@ -154,7 +154,7 @@ class stream<NextLayer>::accept_op
public:
accept_op(accept_op&&) = default;
accept_op(accept_op const&) = default;
accept_op(accept_op const&) = delete;
template<class DeducedHandler, class... Args>
accept_op(DeducedHandler&& h,
@ -545,7 +545,7 @@ async_accept(
decltype(&default_decorate_res),
BOOST_ASIO_HANDLER_TYPE(
AcceptHandler, void(error_code))>{
init.completion_handler,
std::move(init.completion_handler),
*this,
&default_decorate_res}({});
return init.result.get();
@ -574,7 +574,7 @@ async_accept_ex(
ResponseDecorator,
BOOST_ASIO_HANDLER_TYPE(
AcceptHandler, void(error_code))>{
init.completion_handler,
std::move(init.completion_handler),
*this,
decorator}({});
return init.result.get();
@ -605,7 +605,7 @@ async_accept(
decltype(&default_decorate_res),
BOOST_ASIO_HANDLER_TYPE(
AcceptHandler, void(error_code))>{
init.completion_handler,
std::move(init.completion_handler),
*this,
&default_decorate_res}.run(buffers);
return init.result.get();
@ -641,7 +641,7 @@ async_accept_ex(
ResponseDecorator,
BOOST_ASIO_HANDLER_TYPE(
AcceptHandler, void(error_code))>{
init.completion_handler,
std::move(init.completion_handler),
*this,
decorator}.run(buffers);
return init.result.get();
@ -667,7 +667,7 @@ async_accept(
response_op<
BOOST_ASIO_HANDLER_TYPE(
AcceptHandler, void(error_code))>{
init.completion_handler,
std::move(init.completion_handler),
*this,
req,
&default_decorate_res}();
@ -699,7 +699,7 @@ async_accept_ex(
response_op<
BOOST_ASIO_HANDLER_TYPE(
AcceptHandler, void(error_code))>{
init.completion_handler,
std::move(init.completion_handler),
*this,
req,
decorator}();

View File

@ -64,7 +64,7 @@ class stream<NextLayer>::close_op
public:
close_op(close_op&&) = default;
close_op(close_op const&) = default;
close_op(close_op const&) = delete;
template<class DeducedHandler>
close_op(
@ -447,7 +447,7 @@ async_close(close_reason const& cr, CloseHandler&& handler)
void(error_code)> init{handler};
close_op<BOOST_ASIO_HANDLER_TYPE(
CloseHandler, void(error_code))>{
init.completion_handler, *this, cr}(
std::move(init.completion_handler), *this, cr}(
{}, 0, false);
return init.result.get();
}

View File

@ -65,7 +65,7 @@ class stream<NextLayer>::handshake_op
public:
handshake_op(handshake_op&&) = default;
handshake_op(handshake_op const&) = default;
handshake_op(handshake_op const&) = delete;
template<class DeducedHandler, class... Args>
handshake_op(DeducedHandler&& h,
@ -161,7 +161,7 @@ async_handshake(string_view host,
void(error_code)> init{handler};
handshake_op<BOOST_ASIO_HANDLER_TYPE(
HandshakeHandler, void(error_code))>{
init.completion_handler, *this, nullptr, host,
std::move(init.completion_handler), *this, nullptr, host,
target, &default_decorate_req}();
return init.result.get();
}
@ -182,7 +182,7 @@ async_handshake(response_type& res,
void(error_code)> init{handler};
handshake_op<BOOST_ASIO_HANDLER_TYPE(
HandshakeHandler, void(error_code))>{
init.completion_handler, *this, &res, host,
std::move(init.completion_handler), *this, &res, host,
target, &default_decorate_req}();
return init.result.get();
}
@ -206,7 +206,7 @@ async_handshake_ex(string_view host,
void(error_code)> init{handler};
handshake_op<BOOST_ASIO_HANDLER_TYPE(
HandshakeHandler, void(error_code))>{
init.completion_handler, *this, nullptr, host,
std::move(init.completion_handler), *this, nullptr, host,
target, decorator}();
return init.result.get();
}
@ -231,7 +231,7 @@ async_handshake_ex(response_type& res,
void(error_code)> init{handler};
handshake_op<BOOST_ASIO_HANDLER_TYPE(
HandshakeHandler, void(error_code))>{
init.completion_handler, *this, &res, host,
std::move(init.completion_handler), *this, &res, host,
target, decorator}();
return init.result.get();
}

View File

@ -62,7 +62,7 @@ class stream<NextLayer>::ping_op
public:
ping_op(ping_op&&) = default;
ping_op(ping_op const&) = default;
ping_op(ping_op const&) = delete;
template<class DeducedHandler>
ping_op(
@ -241,7 +241,7 @@ async_ping(ping_data const& payload, WriteHandler&& handler)
void(error_code)> init{handler};
ping_op<BOOST_ASIO_HANDLER_TYPE(
WriteHandler, void(error_code))>{
init.completion_handler, *this,
std::move(init.completion_handler), *this,
detail::opcode::ping, payload}();
return init.result.get();
}
@ -259,7 +259,7 @@ async_pong(ping_data const& payload, WriteHandler&& handler)
void(error_code)> init{handler};
ping_op<BOOST_ASIO_HANDLER_TYPE(
WriteHandler, void(error_code))>{
init.completion_handler, *this,
std::move(init.completion_handler), *this,
detail::opcode::pong, payload}();
return init.result.get();
}

View File

@ -59,7 +59,7 @@ class stream<NextLayer>::read_some_op
public:
read_some_op(read_some_op&&) = default;
read_some_op(read_some_op const&) = default;
read_some_op(read_some_op const&) = delete;
template<class DeducedHandler>
read_some_op(
@ -683,7 +683,7 @@ public:
boost::asio::associated_allocator_t<Handler>;
read_op(read_op&&) = default;
read_op(read_op const&) = default;
read_op(read_op const&) = delete;
template<class DeducedHandler>
read_op(
@ -839,7 +839,7 @@ async_read(DynamicBuffer& buffer, ReadHandler&& handler)
DynamicBuffer,
BOOST_ASIO_HANDLER_TYPE(
ReadHandler, void(error_code, std::size_t))>{
init.completion_handler,
std::move(init.completion_handler),
*this,
buffer,
0,
@ -927,7 +927,7 @@ async_read_some(
DynamicBuffer,
BOOST_ASIO_HANDLER_TYPE(
ReadHandler, void(error_code, std::size_t))>{
init.completion_handler,
std::move(init.completion_handler),
*this,
buffer,
limit,
@ -1311,7 +1311,7 @@ async_read_some(
void(error_code, std::size_t)> init{handler};
read_some_op<MutableBufferSequence, BOOST_ASIO_HANDLER_TYPE(
ReadHandler, void(error_code, std::size_t))>{
init.completion_handler,*this, buffers}(
std::move(init.completion_handler), *this, buffers}(
{}, 0, false);
return init.result.get();
}

View File

@ -54,7 +54,7 @@ class stream<NextLayer>::write_some_op
public:
write_some_op(write_some_op&&) = default;
write_some_op(write_some_op const&) = default;
write_some_op(write_some_op const&) = delete;
template<class DeducedHandler>
write_some_op(
@ -728,7 +728,7 @@ async_write_some(bool fin,
void(error_code, std::size_t)> init{handler};
write_some_op<ConstBufferSequence, BOOST_ASIO_HANDLER_TYPE(
WriteHandler, void(error_code, std::size_t))>{
init.completion_handler, *this, fin, bs}(
std::move(init.completion_handler), *this, fin, bs}(
{}, 0, false);
return init.result.get();
}
@ -784,7 +784,7 @@ async_write(
void(error_code, std::size_t)> init{handler};
write_some_op<ConstBufferSequence, BOOST_ASIO_HANDLER_TYPE(
WriteHandler, void(error_code, std::size_t))>{
init.completion_handler, *this, true, bs}(
std::move(init.completion_handler), *this, true, bs}(
{}, 0, false);
return init.result.get();
}

View File

@ -24,7 +24,7 @@ namespace http {
class fields_test : public beast::unit_test::suite
{
public:
template <class T>
template<class T>
class test_allocator
{
public:
@ -32,7 +32,8 @@ public:
test_allocator() noexcept(false) {}
template <typename U, typename = typename std::enable_if<!std::is_same<test_allocator, U>::value>::type>
template<class U, class = typename
std::enable_if<!std::is_same<test_allocator, U>::value>::type>
test_allocator(test_allocator<U> const&) noexcept {}
value_type*
@ -55,7 +56,7 @@ public:
return true;
}
template <class U>
template<class U>
friend
bool
operator!=(test_allocator<T> const& x, test_allocator<U> const& y) noexcept

View File

@ -488,7 +488,7 @@ async_read_some(
return boost::asio::post(
in_->ioc.get_executor(),
bind_handler(
init.completion_handler,
std::move(init.completion_handler),
ec,
0));
}
@ -506,7 +506,7 @@ async_read_some(
boost::asio::post(
in_->ioc.get_executor(),
bind_handler(
init.completion_handler,
std::move(init.completion_handler),
error_code{},
bytes_transferred));
}
@ -522,7 +522,7 @@ async_read_some(
boost::asio::post(
in_->ioc.get_executor(),
bind_handler(
init.completion_handler,
std::move(init.completion_handler),
ec,
0));
}
@ -531,7 +531,7 @@ async_read_some(
in_->op.reset(new read_op_impl<BOOST_ASIO_HANDLER_TYPE(
ReadHandler, void(error_code, std::size_t)),
MutableBufferSequence>{*in_, buffers,
init.completion_handler});
std::move(init.completion_handler)});
}
}
return init.result.get();
@ -605,7 +605,7 @@ async_write_some(ConstBufferSequence const& buffers,
return boost::asio::post(
in_->ioc.get_executor(),
bind_handler(
init.completion_handler,
std::move(init.completion_handler),
boost::asio::error::connection_reset,
0));
BOOST_ASSERT(out->code == status::ok);
@ -616,7 +616,7 @@ async_write_some(ConstBufferSequence const& buffers,
return boost::asio::post(
in_->ioc.get_executor(),
bind_handler(
init.completion_handler,
std::move(init.completion_handler),
ec,
0));
}
@ -632,7 +632,7 @@ async_write_some(ConstBufferSequence const& buffers,
boost::asio::post(
in_->ioc.get_executor(),
bind_handler(
init.completion_handler,
std::move(init.completion_handler),
error_code{},
bytes_transferred));
return init.result.get();
@ -702,18 +702,11 @@ class stream::read_op_impl : public stream::read_op
lambda(lambda&&) = default;
lambda(lambda const&) = default;
lambda(state& s, Buffers const& b, Handler&& h)
template<class DeducedHandler>
lambda(state& s, Buffers const& b, DeducedHandler&& h)
: s_(s)
, b_(b)
, h_(std::move(h))
, work_(s_.ioc.get_executor())
{
}
lambda(state& s, Buffers const& b, Handler const& h)
: s_(s)
, b_(b)
, h_(h)
, h_(std::forward<DeducedHandler>(h))
, work_(s_.ioc.get_executor())
{
}
@ -772,13 +765,9 @@ class stream::read_op_impl : public stream::read_op
lambda fn_;
public:
read_op_impl(state& s, Buffers const& b, Handler&& h)
: fn_(s, b, std::move(h))
{
}
read_op_impl(state& s, Buffers const& b, Handler const& h)
: fn_(s, b, h)
template<class DeducedHandler>
read_op_impl(state& s, Buffers const& b, DeducedHandler&& h)
: fn_(s, b, std::forward<DeducedHandler>(h))
{
}