mirror of
https://github.com/boostorg/beast.git
synced 2025-08-01 22:04:34 +02:00
Reduce template instantiations
This commit is contained in:
@@ -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::size_t>(
|
||||
std::max<std::size_t>(
|
||||
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<Handler, Executor>
|
||||
{
|
||||
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<class Handler_, class Condition_>
|
||||
read_non_blocking_op(
|
||||
Handler_&& h,
|
||||
net::basic_stream_socket<
|
||||
Protocol, Executor>& s,
|
||||
DynamicBuffer& b,
|
||||
Condition cond)
|
||||
: async_op_base<Handler, Executor>(
|
||||
s.get_executor(), std::forward<Handler_>(h))
|
||||
, s_(s)
|
||||
, b_(b)
|
||||
, cond_(std::forward<Condition_>(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<std::size_t>(
|
||||
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<std::size_t>(
|
||||
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<std::size_t>(
|
||||
limit_,
|
||||
s_.available(),
|
||||
b_.max_size() - b_.size(),
|
||||
std::max<std::size_t>(
|
||||
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<Condition>(c));
|
||||
}
|
||||
|
||||
#if BOOST_BEAST_ENABLE_NON_BLOCKING
|
||||
template<
|
||||
class Protocol, class Executor,
|
||||
class DynamicBuffer,
|
||||
class Condition,
|
||||
class ReadHandler>
|
||||
void
|
||||
operator()(
|
||||
net::basic_stream_socket<Protocol, Executor>& 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<ReadHandler,
|
||||
void(error_code, std::size_t)>::value,
|
||||
"ReadHandler type requirements not met");
|
||||
|
||||
if(s.non_blocking())
|
||||
{
|
||||
read_non_blocking_op<
|
||||
Protocol, Executor,
|
||||
DynamicBuffer,
|
||||
typename std::decay<Condition>::type,
|
||||
typename std::decay<ReadHandler>::type>(
|
||||
std::forward<ReadHandler>(h),
|
||||
s,
|
||||
b,
|
||||
std::forward<Condition>(c));
|
||||
}
|
||||
else
|
||||
{
|
||||
read_op<
|
||||
net::basic_stream_socket<Protocol, Executor>,
|
||||
DynamicBuffer,
|
||||
typename std::decay<Condition>::type,
|
||||
typename std::decay<ReadHandler>::type>(
|
||||
std::forward<ReadHandler>(h),
|
||||
s,
|
||||
b,
|
||||
std::forward<Condition>(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<Protocol>& socket,
|
||||
DynamicBuffer& buffer,
|
||||
CompletionCondition cond,
|
||||
error_code& ec)
|
||||
{
|
||||
static_assert(
|
||||
net::is_dynamic_buffer<DynamicBuffer>::value,
|
||||
"DynamicBuffer type requirements not met");
|
||||
static_assert(
|
||||
detail::is_invocable<CompletionCondition,
|
||||
void(error_code&, std::size_t, DynamicBuffer&)>::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<std::size_t>(
|
||||
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<std::size_t>(
|
||||
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<std::size_t>(
|
||||
limit,
|
||||
socket.available(),
|
||||
buffer.max_size() - buffer.size(),
|
||||
std::max<std::size_t>(
|
||||
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,
|
||||
|
@@ -17,7 +17,6 @@
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/core/empty_value.hpp>
|
||||
#include <boost/core/exchange.hpp>
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
|
||||
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<class Handler, class Allocator>
|
||||
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
|
||||
|
||||
|
66
include/boost/beast/core/impl/saved_handler.ipp
Normal file
66
include/boost/beast/core/impl/saved_handler.ipp
Normal file
@@ -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 <boost/beast/core/saved_handler.hpp>
|
||||
#include <boost/core/exchange.hpp>
|
||||
|
||||
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
|
@@ -120,5 +120,8 @@ public:
|
||||
} // boost
|
||||
|
||||
#include <boost/beast/core/impl/saved_handler.hpp>
|
||||
#ifdef BOOST_BEAST_HEADER_ONLY
|
||||
#include <boost/beast/core/impl/saved_handler.ipp>
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@@ -34,6 +34,8 @@ the program, with the macro BOOST_BEAST_SPLIT_COMPILATION defined.
|
||||
#include <boost/beast/core/impl/file_posix.ipp>
|
||||
#include <boost/beast/core/impl/file_stdio.ipp>
|
||||
#include <boost/beast/core/impl/file_win32.ipp>
|
||||
#include <boost/beast/core/impl/flat_static_buffer.ipp>
|
||||
#include <boost/beast/core/impl/saved_handler.ipp>
|
||||
#include <boost/beast/core/impl/static_buffer.ipp>
|
||||
|
||||
#include <boost/beast/http/impl/error.ipp>
|
||||
|
@@ -2727,7 +2727,7 @@ private:
|
||||
|
||||
@see stream::secure_prng
|
||||
*/
|
||||
BOOST_BEAST_DECL
|
||||
inline
|
||||
void
|
||||
seed_prng(std::seed_seq& ss)
|
||||
{
|
||||
|
Reference in New Issue
Block a user