From d4dddec1c09eaa9012f770bf88f73f37f51c27c7 Mon Sep 17 00:00:00 2001 From: Vinnie Falco Date: Fri, 22 Feb 2019 20:08:20 -0800 Subject: [PATCH] Reduce template instantiations --- include/boost/beast/core/detail/impl/read.hpp | 250 +----------------- .../boost/beast/core/impl/saved_handler.hpp | 45 ---- .../boost/beast/core/impl/saved_handler.ipp | 66 +++++ include/boost/beast/core/saved_handler.hpp | 3 + include/boost/beast/src.hpp | 2 + include/boost/beast/websocket/stream.hpp | 2 +- 6 files changed, 84 insertions(+), 284 deletions(-) create mode 100644 include/boost/beast/core/impl/saved_handler.ipp diff --git a/include/boost/beast/core/detail/impl/read.hpp b/include/boost/beast/core/detail/impl/read.hpp index 007261fc..7a4d7b14 100644 --- a/include/boost/beast/core/detail/impl/read.hpp +++ b/include/boost/beast/core/detail/impl/read.hpp @@ -44,6 +44,7 @@ class read_op Stream& s_; DynamicBuffer& b_; Condition cond_; + error_code ec_; std::size_t total_ = 0; public: @@ -72,13 +73,14 @@ public: std::size_t bytes_transferred, bool cont = true) { + ec_ = ec; std::size_t max_size; std::size_t max_prepare; BOOST_ASIO_CORO_REENTER(*this) { for(;;) { - max_size = cond_(ec, total_, b_); + max_size = cond_(ec_, total_, b_); max_prepare = std::min( std::max( 512, b_.capacity() - b_.size()), @@ -92,115 +94,21 @@ public: b_.commit(bytes_transferred); total_ += bytes_transferred; } - this->invoke(cont, ec, total_); + if(! cont) + { + // run this handler "as-if" using net::post + // to reduce template instantiations + BOOST_ASIO_CORO_YIELD + s_.async_read_some( + b_.prepare(0), std::move(*this)); + } + this->invoke_now(ec_, total_); } } }; //------------------------------------------------------------------------------ -#ifdef BOOST_BEAST_ENABLE_NON_BLOCKING -// EXPERIMENTAL -// optimized non-blocking read algorithm -template< - class Protocol, class Executor, - class DynamicBuffer, - class Condition, - class Handler> -class read_non_blocking_op - : public net::coroutine - , public async_op_base -{ - net::basic_stream_socket< - Protocol, Executor>& s_; - DynamicBuffer& b_; - Condition cond_; - std::size_t limit_; - std::size_t total_ = 0; - -public: - read_non_blocking_op(read_non_blocking_op&&) = default; - read_non_blocking_op(read_non_blocking_op const&) = delete; - - template - read_non_blocking_op( - Handler_&& h, - net::basic_stream_socket< - Protocol, Executor>& s, - DynamicBuffer& b, - Condition cond) - : async_op_base( - s.get_executor(), std::forward(h)) - , s_(s) - , b_(b) - , cond_(std::forward(cond)) - { - (*this)({}, false); - } - - void - operator()(error_code ec, bool cont = true) - { - std::size_t n; - std::size_t bytes_transferred; - BOOST_ASIO_CORO_REENTER(*this) - { - limit_ = cond_(ec, total_, b_); - for(;;) - { - n = detail::min( - limit_, b_.max_size() - b_.size()); - if(n == 0) - break; - BOOST_ASIO_CORO_YIELD - s_.async_wait( - net::socket_base::wait_read, std::move(*this)); - if(b_.size() <= default_max_stack_buffer) - { - flat_static_buffer< - default_max_stack_buffer> sb; - bytes_transferred = net::buffer_copy( - sb.prepare(b_.size()), b_.data()); - sb.commit(bytes_transferred); - b_.consume(bytes_transferred); - //detail::shrink_to_fit(b_); - n = detail::min( - limit_, - sb.capacity() - sb.size(), - b_.max_size() - sb.size()); - BOOST_ASSERT(n > 0); - bytes_transferred = - s_.read_some(sb.prepare(n), ec); - sb.commit(bytes_transferred); - total_ += bytes_transferred; - limit_ = cond_(ec, total_, sb); - b_.commit(net::buffer_copy( - b_.prepare(sb.size()), sb.data())); - } - else - { - n = detail::min( - limit_, - s_.available(), - b_.max_size() - b_.size(), - std::max( - 512, b_.capacity() - b_.size())); - BOOST_ASSERT(n > 0); - bytes_transferred = s_.read_some( - b_.prepare(n), ec); - b_.commit(bytes_transferred); - total_ += bytes_transferred; - limit_ = cond_(ec, total_, b_); - } - } - this->invoke(cont, ec, total_); - } - } - -}; - -#endif - struct run_read_op { template< @@ -235,54 +143,6 @@ struct run_read_op std::forward(c)); } -#if BOOST_BEAST_ENABLE_NON_BLOCKING - template< - class Protocol, class Executor, - class DynamicBuffer, - class Condition, - class ReadHandler> - void - operator()( - net::basic_stream_socket& s, - DynamicBuffer& b, - Condition&& c, - ReadHandler&& h) - { - // If you get an error on the following line it means - // that your handler does not meet the documented type - // requirements for the handler. - - static_assert( - beast::detail::is_invocable::value, - "ReadHandler type requirements not met"); - - if(s.non_blocking()) - { - read_non_blocking_op< - Protocol, Executor, - DynamicBuffer, - typename std::decay::type, - typename std::decay::type>( - std::forward(h), - s, - b, - std::forward(c)); - } - else - { - read_op< - net::basic_stream_socket, - DynamicBuffer, - typename std::decay::type, - typename std::decay::type>( - std::forward(h), - s, - b, - std::forward(c)); - } - } -#endif }; }; @@ -360,92 +220,6 @@ read( return total; } -#ifdef BOOST_BEAST_ENABLE_NON_BLOCKING -template< - class Protocol, - class DynamicBuffer, - class CompletionCondition> -std::size_t -read( - net::basic_stream_socket& socket, - DynamicBuffer& buffer, - CompletionCondition cond, - error_code& ec) -{ - static_assert( - net::is_dynamic_buffer::value, - "DynamicBuffer type requirements not met"); - static_assert( - detail::is_invocable::value, - "CompletionCondition type requirements not met"); - ec = {}; - std::size_t n; - std::size_t limit; - std::size_t total = 0; - std::size_t bytes_transferred; - limit = cond(ec, total, buffer); - for(;;) - { - n = detail::min( - limit, buffer.max_size() - buffer.size()); - if(n == 0) - break; - socket.non_blocking(false); - socket.wait(net::socket_base::wait_read, ec); - socket.non_blocking(true); - if(ec) - { - limit = cond(ec, total, buffer); - } - else if(buffer.size() <= default_max_stack_buffer) - { - flat_static_buffer< - default_max_stack_buffer> sb; - bytes_transferred = net::buffer_copy( - sb.prepare(buffer.size()), buffer.data()); - sb.commit(bytes_transferred); - buffer.consume(bytes_transferred); - //detail::shrink_to_fit(buffer); - n = detail::min( - limit, - sb.capacity() - sb.size(), - buffer.max_size() - sb.size()); - BOOST_ASSERT(n > 0); - bytes_transferred = - socket.read_some(sb.prepare(n), ec); - if(ec != net::error::would_block) - { - sb.commit(bytes_transferred); - total += bytes_transferred; - limit = cond(ec, total, sb); - } - buffer.commit(net::buffer_copy( - buffer.prepare(sb.size()), sb.data())); - } - else - { - n = detail::min( - limit, - socket.available(), - buffer.max_size() - buffer.size(), - std::max( - 512, buffer.capacity() - buffer.size())); - BOOST_ASSERT(n > 0); - bytes_transferred = socket.read_some( - buffer.prepare(n), ec); - if(ec != net::error::would_block) - { - buffer.commit(bytes_transferred); - total += bytes_transferred; - limit = cond(ec, total, buffer); - } - } - } - return total; -} -#endif - template< class AsyncReadStream, class DynamicBuffer, diff --git a/include/boost/beast/core/impl/saved_handler.hpp b/include/boost/beast/core/impl/saved_handler.hpp index 1f89f751..a2642f59 100644 --- a/include/boost/beast/core/impl/saved_handler.hpp +++ b/include/boost/beast/core/impl/saved_handler.hpp @@ -17,7 +17,6 @@ #include #include #include -#include #include namespace boost { @@ -95,29 +94,6 @@ public: //------------------------------------------------------------------------------ -saved_handler:: -~saved_handler() -{ - if(p_) - p_->destroy(); -} - -saved_handler:: -saved_handler(saved_handler&& other) noexcept - : p_(boost::exchange(other.p_, nullptr)) -{ -} - -saved_handler& -saved_handler:: -operator=(saved_handler&& other) noexcept -{ - // Can't delete a handler before invoking - BOOST_ASSERT(! has_value()); - p_ = boost::exchange(other.p_, nullptr); - return *this; -} - template void saved_handler:: @@ -169,27 +145,6 @@ emplace(Handler&& handler) net::get_associated_allocator(handler)); } -void -saved_handler:: -invoke() -{ - // Can't invoke without a value - BOOST_ASSERT(has_value()); - boost::exchange( - p_, nullptr)->invoke(); -} - -bool -saved_handler:: -maybe_invoke() -{ - if(! p_) - return false; - boost::exchange( - p_, nullptr)->invoke(); - return true; -} - } // beast } // boost diff --git a/include/boost/beast/core/impl/saved_handler.ipp b/include/boost/beast/core/impl/saved_handler.ipp new file mode 100644 index 00000000..779339c6 --- /dev/null +++ b/include/boost/beast/core/impl/saved_handler.ipp @@ -0,0 +1,66 @@ +// +// Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// Official repository: https://github.com/boostorg/beast +// + +#ifndef BOOST_BEAST_CORE_IMPL_SAVED_HANDLER_IPP +#define BOOST_BEAST_CORE_IMPL_SAVED_HANDLER_IPP + +#include +#include + +namespace boost { +namespace beast { + +saved_handler:: +~saved_handler() +{ + if(p_) + p_->destroy(); +} + +saved_handler:: +saved_handler(saved_handler&& other) noexcept + : p_(boost::exchange(other.p_, nullptr)) +{ +} + +saved_handler& +saved_handler:: +operator=(saved_handler&& other) noexcept +{ + // Can't delete a handler before invoking + BOOST_ASSERT(! has_value()); + p_ = boost::exchange(other.p_, nullptr); + return *this; +} + +void +saved_handler:: +invoke() +{ + // Can't invoke without a value + BOOST_ASSERT(has_value()); + boost::exchange( + p_, nullptr)->invoke(); +} + +bool +saved_handler:: +maybe_invoke() +{ + if(! p_) + return false; + boost::exchange( + p_, nullptr)->invoke(); + return true; +} + +} // beast +} // boost + +#endif diff --git a/include/boost/beast/core/saved_handler.hpp b/include/boost/beast/core/saved_handler.hpp index f6987675..08aafdbc 100644 --- a/include/boost/beast/core/saved_handler.hpp +++ b/include/boost/beast/core/saved_handler.hpp @@ -120,5 +120,8 @@ public: } // boost #include +#ifdef BOOST_BEAST_HEADER_ONLY +#include +#endif #endif diff --git a/include/boost/beast/src.hpp b/include/boost/beast/src.hpp index c7e5ab88..dbdf6ce0 100644 --- a/include/boost/beast/src.hpp +++ b/include/boost/beast/src.hpp @@ -34,6 +34,8 @@ the program, with the macro BOOST_BEAST_SPLIT_COMPILATION defined. #include #include #include +#include +#include #include #include diff --git a/include/boost/beast/websocket/stream.hpp b/include/boost/beast/websocket/stream.hpp index c0bae5c8..3834fbdb 100644 --- a/include/boost/beast/websocket/stream.hpp +++ b/include/boost/beast/websocket/stream.hpp @@ -2727,7 +2727,7 @@ private: @see stream::secure_prng */ -BOOST_BEAST_DECL +inline void seed_prng(std::seed_seq& ss) {