diff --git a/CHANGELOG.md b/CHANGELOG.md index df471fc2..6e8c760f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ Version 149: * Fix CMakeLists.txt variable * Protect calls from macros * pausation always allocates +* Don't copy completion handlers -------------------------------------------------------------------------------- diff --git a/include/boost/beast/core/detail/bind_handler.hpp b/include/boost/beast/core/detail/bind_handler.hpp index 50b0ce7c..5f5c612b 100644 --- a/include/boost/beast/core/detail/bind_handler.hpp +++ b/include/boost/beast/core/detail/bind_handler.hpp @@ -109,7 +109,7 @@ public: boost::asio::associated_allocator_t; bound_handler(bound_handler&&) = default; - bound_handler(bound_handler const&) = default; + bound_handler(bound_handler const&) = delete; template explicit diff --git a/include/boost/beast/core/impl/buffered_read_stream.ipp b/include/boost/beast/core/impl/buffered_read_stream.ipp index bf92990f..3e6b935f 100644 --- a/include/boost/beast/core/impl/buffered_read_stream.ipp +++ b/include/boost/beast/core/impl/buffered_read_stream.ipp @@ -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 read_some_op(DeducedHandler&& h, @@ -237,7 +237,7 @@ async_read_some( void(error_code, std::size_t)> init{handler}; read_some_op{ - init.completion_handler, *this, buffers}( + std::move(init.completion_handler), *this, buffers}( error_code{}, 0); return init.result.get(); } diff --git a/include/boost/beast/core/type_traits.hpp b/include/boost/beast/core/type_traits.hpp index d622e0e8..3c52d60f 100644 --- a/include/boost/beast/core/type_traits.hpp +++ b/include/boost/beast/core/type_traits.hpp @@ -52,7 +52,7 @@ template using is_completion_handler = std::integral_constant; #else using is_completion_handler = std::integral_constant::type>::value && + std::is_move_constructible::type>::value && detail::is_invocable::value>; #endif diff --git a/include/boost/beast/http/impl/file_body_win32.ipp b/include/boost/beast/http/impl/file_body_win32.ipp index 6d302c96..2ed08da5 100644 --- a/include/boost/beast/http/impl/file_body_win32.ipp +++ b/include/boost/beast/http/impl/file_body_win32.ipp @@ -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 write_some_win32_op( @@ -422,7 +422,10 @@ operator()() (std::min)(r.body_.last_ - r.pos_, sr_.limit()), (std::numeric_limits::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(); } diff --git a/include/boost/beast/http/impl/read.ipp b/include/boost/beast/http/impl/read.ipp index ee55131d..cbabff0f 100644 --- a/include/boost/beast/http/impl/read.ipp +++ b/include/boost/beast/http/impl/read.ipp @@ -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 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 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 read_msg_op(DeducedHandler&& h, Stream& s, Args&&... args) @@ -531,7 +531,7 @@ async_read_some( detail::read_some_op{ - 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{ - 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{ - 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(); } diff --git a/include/boost/beast/http/impl/write.ipp b/include/boost/beast/http/impl/write.ipp index 87434297..c07fe540 100644 --- a/include/boost/beast/http/impl/write.ipp +++ b/include/boost/beast/http/impl/write.ipp @@ -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 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 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 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(); } diff --git a/include/boost/beast/websocket/impl/accept.ipp b/include/boost/beast/websocket/impl/accept.ipp index dd74dad3..8b29de46 100644 --- a/include/boost/beast/websocket/impl/accept.ipp +++ b/include/boost/beast/websocket/impl/accept.ipp @@ -58,7 +58,7 @@ class stream::response_op public: response_op(response_op&&) = default; - response_op(response_op const&) = default; + response_op(response_op const&) = delete; template response_op(DeducedHandler&& h, @@ -154,7 +154,7 @@ class stream::accept_op public: accept_op(accept_op&&) = default; - accept_op(accept_op const&) = default; + accept_op(accept_op const&) = delete; template 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}(); diff --git a/include/boost/beast/websocket/impl/close.ipp b/include/boost/beast/websocket/impl/close.ipp index bf1b043e..e2b61318 100644 --- a/include/boost/beast/websocket/impl/close.ipp +++ b/include/boost/beast/websocket/impl/close.ipp @@ -64,7 +64,7 @@ class stream::close_op public: close_op(close_op&&) = default; - close_op(close_op const&) = default; + close_op(close_op const&) = delete; template close_op( @@ -447,7 +447,7 @@ async_close(close_reason const& cr, CloseHandler&& handler) void(error_code)> init{handler}; close_op{ - init.completion_handler, *this, cr}( + std::move(init.completion_handler), *this, cr}( {}, 0, false); return init.result.get(); } diff --git a/include/boost/beast/websocket/impl/handshake.ipp b/include/boost/beast/websocket/impl/handshake.ipp index 911265f3..18fd1e06 100644 --- a/include/boost/beast/websocket/impl/handshake.ipp +++ b/include/boost/beast/websocket/impl/handshake.ipp @@ -65,7 +65,7 @@ class stream::handshake_op public: handshake_op(handshake_op&&) = default; - handshake_op(handshake_op const&) = default; + handshake_op(handshake_op const&) = delete; template handshake_op(DeducedHandler&& h, @@ -161,7 +161,7 @@ async_handshake(string_view host, void(error_code)> init{handler}; handshake_op{ - 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{ - 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{ - 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{ - init.completion_handler, *this, &res, host, + std::move(init.completion_handler), *this, &res, host, target, decorator}(); return init.result.get(); } diff --git a/include/boost/beast/websocket/impl/ping.ipp b/include/boost/beast/websocket/impl/ping.ipp index 0ce869d1..223d06a7 100644 --- a/include/boost/beast/websocket/impl/ping.ipp +++ b/include/boost/beast/websocket/impl/ping.ipp @@ -62,7 +62,7 @@ class stream::ping_op public: ping_op(ping_op&&) = default; - ping_op(ping_op const&) = default; + ping_op(ping_op const&) = delete; template ping_op( @@ -241,7 +241,7 @@ async_ping(ping_data const& payload, WriteHandler&& handler) void(error_code)> init{handler}; ping_op{ - 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{ - init.completion_handler, *this, + std::move(init.completion_handler), *this, detail::opcode::pong, payload}(); return init.result.get(); } diff --git a/include/boost/beast/websocket/impl/read.ipp b/include/boost/beast/websocket/impl/read.ipp index 369d3977..8ea8204a 100644 --- a/include/boost/beast/websocket/impl/read.ipp +++ b/include/boost/beast/websocket/impl/read.ipp @@ -59,7 +59,7 @@ class stream::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 read_some_op( @@ -683,7 +683,7 @@ public: boost::asio::associated_allocator_t; read_op(read_op&&) = default; - read_op(read_op const&) = default; + read_op(read_op const&) = delete; template 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{ - init.completion_handler,*this, buffers}( + std::move(init.completion_handler), *this, buffers}( {}, 0, false); return init.result.get(); } diff --git a/include/boost/beast/websocket/impl/write.ipp b/include/boost/beast/websocket/impl/write.ipp index c99bdf3b..dfb719dc 100644 --- a/include/boost/beast/websocket/impl/write.ipp +++ b/include/boost/beast/websocket/impl/write.ipp @@ -54,7 +54,7 @@ class stream::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 write_some_op( @@ -728,7 +728,7 @@ async_write_some(bool fin, void(error_code, std::size_t)> init{handler}; write_some_op{ - 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{ - init.completion_handler, *this, true, bs}( + std::move(init.completion_handler), *this, true, bs}( {}, 0, false); return init.result.get(); } diff --git a/test/beast/http/fields.cpp b/test/beast/http/fields.cpp index 0b982db6..7897ed59 100644 --- a/test/beast/http/fields.cpp +++ b/test/beast/http/fields.cpp @@ -24,7 +24,7 @@ namespace http { class fields_test : public beast::unit_test::suite { public: - template + template class test_allocator { public: @@ -32,7 +32,8 @@ public: test_allocator() noexcept(false) {} - template ::value>::type> + template::value>::type> test_allocator(test_allocator const&) noexcept {} value_type* @@ -55,7 +56,7 @@ public: return true; } - template + template friend bool operator!=(test_allocator const& x, test_allocator const& y) noexcept diff --git a/test/extras/include/boost/beast/test/stream.hpp b/test/extras/include/boost/beast/test/stream.hpp index 3352b988..a75bbde4 100644 --- a/test/extras/include/boost/beast/test/stream.hpp +++ b/test/extras/include/boost/beast/test/stream.hpp @@ -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{*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 + 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(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 + read_op_impl(state& s, Buffers const& b, DeducedHandler&& h) + : fn_(s, b, std::forward(h)) { }