remove session pool allocator and use the buffer class instead (#2274)

simplify append_buffer by using size() to determine size of the buffer. make the move explicit in chained_buffer::init_buffer_entry
This commit is contained in:
Arvid Norberg 2017-08-28 11:37:53 +02:00 committed by GitHub
parent cc3f73de96
commit 1075ae3b8d
20 changed files with 54 additions and 218 deletions

View File

@ -173,7 +173,6 @@ set(includes include ed25519/src)
option(shared "build libtorrent as a shared library" ON) option(shared "build libtorrent as a shared library" ON)
option(static_runtime "build libtorrent with static runtime" OFF) option(static_runtime "build libtorrent with static runtime" OFF)
option(pool-allocators "Uses a pool allocator for disk and piece buffers" ON)
option(encryption "link against openssl and enable encryption" ON) option(encryption "link against openssl and enable encryption" ON)
option(dht "enable support for Mainline DHT" ON) option(dht "enable support for Mainline DHT" ON)
option(deprecated-functions "enable deprecated functions for backwards compatibility" ON) option(deprecated-functions "enable deprecated functions for backwards compatibility" ON)
@ -308,10 +307,6 @@ if (libiconv)
target_link_libraries(torrent-rasterbar ${ICONV_LIBRARIES}) target_link_libraries(torrent-rasterbar ${ICONV_LIBRARIES})
endif (libiconv) endif (libiconv)
if (NOT pool-allocators)
target_compile_definitions(torrent-rasterbar PUBLIC TORRENT_DISABLE_POOL_ALLOCATOR)
endif()
if (NOT deprecated-functions) if (NOT deprecated-functions)
target_compile_definitions(torrent-rasterbar PUBLIC TORRENT_NO_DEPRECATE) target_compile_definitions(torrent-rasterbar PUBLIC TORRENT_NO_DEPRECATE)
endif() endif()

14
Jamfile
View File

@ -110,8 +110,6 @@ rule linking ( properties * )
if <target-os>windows in $(properties) if <target-os>windows in $(properties)
&& ( <asserts>on in $(properties) && ( <asserts>on in $(properties)
|| <asserts>production in $(properties) || <asserts>production in $(properties)
|| <pool-allocators>debug in $(properties)
|| <allocator>debug in $(properties)
|| <asio-debugging>on in $(properties) ) || <asio-debugging>on in $(properties) )
{ {
result += <library>dbghelp ; result += <library>dbghelp ;
@ -177,8 +175,6 @@ rule linking ( properties * )
&& <target-os>linux in $(properties) && <target-os>linux in $(properties)
&& ( <asserts>on in $(properties) && ( <asserts>on in $(properties)
|| <asserts>production in $(properties) || <asserts>production in $(properties)
|| <pool-allocators>debug in $(properties)
|| <allocator>debug in $(properties)
|| <asio-debugging>on in $(properties) ) || <asio-debugging>on in $(properties) )
{ {
# for backtraces in assertion failures # for backtraces in assertion failures
@ -436,15 +432,6 @@ feature.compose <picker-debugging>on : <define>TORRENT_DEBUG_REFCOUNTS ;
feature simulator : off on : composite propagated link-incompatible ; feature simulator : off on : composite propagated link-incompatible ;
feature.compose <simulator>on : <define>TORRENT_BUILD_SIMULATOR ; feature.compose <simulator>on : <define>TORRENT_BUILD_SIMULATOR ;
# deprecated use allocator=pool instead
feature pool-allocators : on off debug : composite propagated link-incompatible ;
feature.compose <pool-allocators>off : <define>TORRENT_DISABLE_POOL_ALLOCATOR ;
feature.compose <pool-allocators>debug : <define>TORRENT_DISABLE_POOL_ALLOCATOR <define>TORRENT_DEBUG_BUFFERS ;
feature allocator : pool system debug : composite propagated ;
feature.compose <allocator>system : <define>TORRENT_DISABLE_POOL_ALLOCATOR ;
feature.compose <allocator>debug : <define>TORRENT_DISABLE_POOL_ALLOCATOR <define>TORRENT_DEBUG_BUFFERS ;
feature piece-allocator : valloc memalign posix_memalign : composite propagated ; feature piece-allocator : valloc memalign posix_memalign : composite propagated ;
feature.compose <piece-allocator>memalign : <define>TORRENT_USE_MEMALIGN=1 ; feature.compose <piece-allocator>memalign : <define>TORRENT_USE_MEMALIGN=1 ;
feature.compose <piece-allocator>posix_memalign : <define>TORRENT_USE_POSIX_MEMALIGN=1 ; feature.compose <piece-allocator>posix_memalign : <define>TORRENT_USE_POSIX_MEMALIGN=1 ;
@ -516,7 +503,6 @@ variant test_release : release
; ;
variant test_debug : debug variant test_debug : debug
: <logging>on : <logging>on
<allocator>debug
<invariant-checks>full <boost-link>shared <invariant-checks>full <boost-link>shared
<export-extra>on <debug-iterators>on <threading>multi <asserts>on <export-extra>on <debug-iterators>on <threading>multi <asserts>on
; ;

View File

@ -216,15 +216,6 @@ AC_ARG_ENABLE(
[[ARG_ENABLE_FULL_EXPORT=no]] [[ARG_ENABLE_FULL_EXPORT=no]]
) )
AC_ARG_ENABLE(
[pool-allocators],
[AS_HELP_STRING(
[--enable-pool-allocators],
[enable pool allocators for send buffers [default=yes]])],
[[ARG_ENABLE_POOL_ALLOC=$enableval]],
[[ARG_ENABLE_POOL_ALLOC=yes]]
)
AC_ARG_ENABLE( AC_ARG_ENABLE(
[invariant-checks], [invariant-checks],
[AS_HELP_STRING( [AS_HELP_STRING(
@ -395,19 +386,6 @@ AS_CASE(["$ARG_ENABLE_DHT"],
AC_MSG_ERROR([Unknown option "$ARG_ENABLE_DHT". Use either "yes", "no" or "logging".])] AC_MSG_ERROR([Unknown option "$ARG_ENABLE_DHT". Use either "yes", "no" or "logging".])]
) )
AC_MSG_CHECKING([whether pool allocators should be enabled])
AS_CASE(["$ARG_ENABLE_POOL_ALLOC"],
["yes"|"on"], [
AC_MSG_RESULT([yes])
],
["no"|"off"], [
AC_MSG_RESULT([no])
AC_DEFINE([TORRENT_DISABLE_POOL_ALLOCATOR],[1],[Define to disable use of boost::pool for pool allocators.])
],
[AC_MSG_RESULT([$ARG_ENABLE_POOL_ALLOC])
AC_MSG_ERROR([Unknown option "$ARG_ENABLE_POOL_ALLOC". Use either "yes" or "no".])]
)
AS_IF([test "x$ac_cv_hidden_visibility_attribute" = "xyes"], [ AS_IF([test "x$ac_cv_hidden_visibility_attribute" = "xyes"], [
AS_IF([test "x$ARG_ENABLE_FULL_EXPORT" = "xno"], [ AS_IF([test "x$ARG_ENABLE_FULL_EXPORT" = "xno"], [
CXXFLAGS="$CXXFLAGS -fvisibility=hidden -fvisibility-inlines-hidden" CXXFLAGS="$CXXFLAGS -fvisibility=hidden -fvisibility-inlines-hidden"
@ -597,7 +575,6 @@ Build options:
Features: Features:
encryption support: ${ARG_ENABLE_ENCRYPTION:-yes} encryption support: ${ARG_ENABLE_ENCRYPTION:-yes}
dht support: ${ARG_ENABLE_DHT:-yes} dht support: ${ARG_ENABLE_DHT:-yes}
pool allocators: ${ARG_ENABLE_POOL_ALLOC:-yes}
Extra builds: Extra builds:
examples: ${ARG_ENABLE_EXAMPLES:-no} examples: ${ARG_ENABLE_EXAMPLES:-no}

View File

@ -532,8 +532,6 @@ defines you can use to control the build.
| | checks in the storage, including logging of | | | checks in the storage, including logging of |
| | piece sorting. | | | piece sorting. |
+----------------------------------------+-------------------------------------------------+ +----------------------------------------+-------------------------------------------------+
| ``TORRENT_DISABLE_POOL_ALLOCATOR`` | Disables use of ``boost::pool<>``. |
+----------------------------------------+-------------------------------------------------+
| ``TORRENT_DISABLE_MUTABLE_TORRENTS`` | Disables mutable torrent support (`BEP 38`_) | | ``TORRENT_DISABLE_MUTABLE_TORRENTS`` | Disables mutable torrent support (`BEP 38`_) |
+----------------------------------------+-------------------------------------------------+ +----------------------------------------+-------------------------------------------------+
| ``TORRENT_LINKING_SHARED`` | If this is defined when including the | | ``TORRENT_LINKING_SHARED`` | If this is defined when including the |

View File

@ -201,7 +201,6 @@ nobase_include_HEADERS = \
aux_/vector.hpp \ aux_/vector.hpp \
aux_/win_crypto_provider.hpp \ aux_/win_crypto_provider.hpp \
aux_/win_util.hpp \ aux_/win_util.hpp \
aux_/non_owning_handle.hpp \
aux_/storage_utils.hpp \ aux_/storage_utils.hpp \
aux_/numeric_cast.hpp \ aux_/numeric_cast.hpp \
aux_/unique_ptr.hpp \ aux_/unique_ptr.hpp \

View File

@ -1,49 +0,0 @@
/*
Copyright (c) 2016, Arvid Norberg
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the distribution.
* Neither the name of the author nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef TORRENT_NON_OWNING_HANDLE_HPP_INCLUDED
#define TORRENT_NON_OWNING_HANDLE_HPP_INCLUDED
namespace libtorrent { namespace aux {
// internal
struct non_owning_handle
{
explicit non_owning_handle(char* b) : m_buf(b) {}
char* get() const { return m_buf; }
private:
char* m_buf;
};
}}
#endif

View File

@ -239,9 +239,6 @@ namespace aux {
, aux::error_handler_interface , aux::error_handler_interface
, std::enable_shared_from_this<session_impl> , std::enable_shared_from_this<session_impl>
{ {
// the size of each allocation that is chained in the send buffer
static constexpr int send_buffer_size_impl = 128;
// plugin feature-index key map // plugin feature-index key map
enum enum
{ {
@ -644,13 +641,9 @@ namespace aux {
void deferred_submit_jobs() override; void deferred_submit_jobs() override;
ses_buffer_holder allocate_buffer() override;
torrent_peer* allocate_peer_entry(int type); torrent_peer* allocate_peer_entry(int type);
void free_peer_entry(torrent_peer* p); void free_peer_entry(torrent_peer* p);
void free_buffer(char* buf) override;
int send_buffer_size() const override { return send_buffer_size_impl; }
// implements dht_observer // implements dht_observer
virtual void set_external_address(aux::listen_socket_handle const& iface virtual void set_external_address(aux::listen_socket_handle const& iface
, address const& ip, address const& source) override; , address const& ip, address const& source) override;
@ -792,12 +785,6 @@ namespace aux {
// by torrent::get_download_queue. // by torrent::get_download_queue.
std::vector<block_info> m_block_info_storage; std::vector<block_info> m_block_info_storage;
#ifndef TORRENT_DISABLE_POOL_ALLOCATOR
// this pool is used to allocate and recycle send
// buffers from.
boost::pool<> m_send_buffers{send_buffer_size_impl};
#endif
io_service& m_io_service; io_service& m_io_service;
#ifdef TORRENT_USE_OPENSSL #ifdef TORRENT_USE_OPENSSL

View File

@ -118,8 +118,6 @@ namespace libtorrent { namespace aux {
}; };
#endif // TORRENT_DISABLE_LOGGING || TORRENT_USE_ASSERTS #endif // TORRENT_DISABLE_LOGGING || TORRENT_USE_ASSERTS
struct ses_buffer_holder;
// TODO: 2 make this interface a lot smaller. It could be split up into // TODO: 2 make this interface a lot smaller. It could be split up into
// several smaller interfaces. Each subsystem could then limit the size // several smaller interfaces. Each subsystem could then limit the size
// of the mock object to test it. // of the mock object to test it.
@ -190,10 +188,6 @@ namespace libtorrent { namespace aux {
virtual void close_connection(peer_connection* p) = 0; virtual void close_connection(peer_connection* p) = 0;
virtual int num_connections() const = 0; virtual int num_connections() const = 0;
virtual ses_buffer_holder allocate_buffer() = 0;
virtual void free_buffer(char* buf) = 0;
virtual int send_buffer_size() const = 0;
virtual void deferred_submit_jobs() = 0; virtual void deferred_submit_jobs() = 0;
virtual std::uint16_t listen_port() const = 0; virtual std::uint16_t listen_port() const = 0;
@ -322,29 +316,6 @@ namespace libtorrent { namespace aux {
protected: protected:
~session_interface() {} ~session_interface() {}
}; };
struct ses_buffer_holder
{
ses_buffer_holder(session_interface& ses, char* buf)
: m_ses(&ses), m_buf(buf) {}
~ses_buffer_holder() { if (m_buf) m_ses->free_buffer(m_buf); }
ses_buffer_holder(ses_buffer_holder const&) = delete;
ses_buffer_holder& operator=(ses_buffer_holder const&) = delete;
ses_buffer_holder(ses_buffer_holder&& rhs) noexcept
: m_ses(rhs.m_ses), m_buf(rhs.m_buf) { rhs.m_buf = nullptr; }
ses_buffer_holder& operator=(ses_buffer_holder&& rhs) noexcept
{
if (m_buf) m_ses->free_buffer(m_buf);
m_buf = rhs.m_buf;
m_ses = rhs.m_ses;
rhs.m_buf = nullptr;
return *this;
}
char* get() const noexcept { return m_buf; }
private:
session_interface* m_ses;
char* m_buf;
};
}} }}
#endif #endif

View File

@ -331,21 +331,20 @@ namespace libtorrent {
// is true, otherwise it passes the call to the // is true, otherwise it passes the call to the
// peer_connection functions of the same names // peer_connection functions of the same names
template <typename Holder> template <typename Holder>
void append_const_send_buffer(Holder buffer, int size) void append_const_send_buffer(Holder holder, int size)
{ {
#if !defined(TORRENT_DISABLE_ENCRYPTION) && !defined(TORRENT_DISABLE_EXTENSIONS) #if !defined(TORRENT_DISABLE_ENCRYPTION) && !defined(TORRENT_DISABLE_EXTENSIONS)
if (!m_enc_handler.is_send_plaintext()) if (!m_enc_handler.is_send_plaintext())
{ {
// if we're encrypting this buffer, we need to make a copy // if we're encrypting this buffer, we need to make a copy
// since we'll mutate it // since we'll mutate it
std::unique_ptr<char[]> buf(new char[size]); buffer buf(std::size_t(size), {holder.data(), std::size_t(size)});
std::copy(buffer.get(), buffer.get() + size, buf.get());
append_send_buffer(std::move(buf), size); append_send_buffer(std::move(buf), size);
} }
else else
#endif #endif
{ {
append_send_buffer(std::move(buffer), size); append_send_buffer(std::move(holder), size);
} }
} }

View File

@ -127,23 +127,23 @@ namespace libtorrent {
void pop_front(int bytes_to_pop); void pop_front(int bytes_to_pop);
template <typename Holder> template <typename Holder>
void append_buffer(Holder buffer, int s, int used_size) void append_buffer(Holder buffer, int used_size)
{ {
TORRENT_ASSERT(is_single_thread()); TORRENT_ASSERT(is_single_thread());
TORRENT_ASSERT(s >= used_size); TORRENT_ASSERT(int(buffer.size()) >= used_size);
m_vec.emplace_back(); m_vec.emplace_back();
buffer_t& b = m_vec.back(); buffer_t& b = m_vec.back();
init_buffer_entry<Holder>(b, buffer, s, used_size); init_buffer_entry<Holder>(b, std::move(buffer), used_size);
} }
template <typename Holder> template <typename Holder>
void prepend_buffer(Holder buffer, int s, int used_size) void prepend_buffer(Holder buffer, int used_size)
{ {
TORRENT_ASSERT(is_single_thread()); TORRENT_ASSERT(is_single_thread());
TORRENT_ASSERT(s >= used_size); TORRENT_ASSERT(int(buffer.size()) >= used_size);
m_vec.emplace_front(); m_vec.emplace_front();
buffer_t& b = m_vec.front(); buffer_t& b = m_vec.front();
init_buffer_entry<Holder>(b, buffer, s, used_size); init_buffer_entry<Holder>(b, std::move(buffer), used_size);
} }
// returns the number of bytes available at the // returns the number of bytes available at the
@ -171,12 +171,12 @@ namespace libtorrent {
private: private:
template <typename Holder> template <typename Holder>
void init_buffer_entry(buffer_t& b, Holder& buffer, int s, int used_size) void init_buffer_entry(buffer_t& b, Holder buf, int used_size)
{ {
static_assert(sizeof(Holder) <= sizeof(b.holder), "buffer holder too large"); static_assert(sizeof(Holder) <= sizeof(b.holder), "buffer holder too large");
b.buf = buffer.get(); b.buf = buf.data();
b.size = s; b.size = static_cast<int>(buf.size());
b.used_size = used_size; b.used_size = used_size;
#ifdef _MSC_VER #ifdef _MSC_VER
@ -196,10 +196,11 @@ namespace libtorrent {
#pragma warning(pop) #pragma warning(pop)
#endif #endif
new (&b.holder) Holder(std::move(buffer)); new (&b.holder) Holder(std::move(buf));
m_bytes += used_size; m_bytes += used_size;
m_capacity += s; TORRENT_ASSERT(m_capacity < std::numeric_limits<int>::max() - b.size);
m_capacity += b.size;
TORRENT_ASSERT(m_bytes <= m_capacity); TORRENT_ASSERT(m_bytes <= m_capacity);
} }

View File

@ -48,10 +48,6 @@ POSSIBILITY OF SUCH DAMAGE.
#include <linux/version.h> // for LINUX_VERSION_CODE and KERNEL_VERSION #include <linux/version.h> // for LINUX_VERSION_CODE and KERNEL_VERSION
#endif // __linux #endif // __linux
#if defined TORRENT_DEBUG_BUFFERS && !defined TORRENT_DISABLE_POOL_ALLOCATOR
#error TORRENT_DEBUG_BUFFERS only works if you also disable pool allocators with TORRENT_DISABLE_POOL_ALLOCATOR
#endif
#if !defined BOOST_ASIO_SEPARATE_COMPILATION && !defined BOOST_ASIO_DYN_LINK #if !defined BOOST_ASIO_SEPARATE_COMPILATION && !defined BOOST_ASIO_DYN_LINK
#define BOOST_ASIO_SEPARATE_COMPILATION #define BOOST_ASIO_SEPARATE_COMPILATION
#endif #endif

View File

@ -58,8 +58,8 @@ namespace libtorrent {
// when it's destructed, unless it's released. ``release`` returns the disk // when it's destructed, unless it's released. ``release`` returns the disk
// buffer and transfers ownership and responsibility to free it to the caller. // buffer and transfers ownership and responsibility to free it to the caller.
// //
// ``get()`` returns the pointer without transferring ownership. If // ``data()`` returns the pointer without transferring ownership. If
// this buffer has been released, ``get()`` will return nullptr. // this buffer has been released, ``data()`` will return nullptr.
struct TORRENT_EXTRA_EXPORT disk_buffer_holder struct TORRENT_EXTRA_EXPORT disk_buffer_holder
{ {
// internal // internal
@ -86,6 +86,7 @@ namespace libtorrent {
char* release() noexcept; char* release() noexcept;
// return a pointer to the held buffer // return a pointer to the held buffer
char* data() const noexcept { return m_buf; }
char* get() const noexcept { return m_buf; } char* get() const noexcept { return m_buf; }
// set the holder object to hold the specified buffer // set the holder object to hold the specified buffer
@ -109,6 +110,8 @@ namespace libtorrent {
// buffer // buffer
explicit operator bool() const noexcept { return m_buf != nullptr; } explicit operator bool() const noexcept { return m_buf != nullptr; }
std::size_t size() const { return 0x4000; }
private: private:
buffer_allocator_interface* m_allocator; buffer_allocator_interface* m_allocator;

View File

@ -41,7 +41,7 @@ POSSIBILITY OF SUCH DAMAGE.
#include <tuple> #include <tuple>
#include "libtorrent/config.hpp" #include "libtorrent/config.hpp"
#include "libtorrent/buffer.hpp" #include "libtorrent/span.hpp"
namespace libtorrent { namespace libtorrent {

View File

@ -633,7 +633,7 @@ namespace aux {
void append_send_buffer(Holder buffer, int size) void append_send_buffer(Holder buffer, int size)
{ {
TORRENT_ASSERT(is_single_thread()); TORRENT_ASSERT(is_single_thread());
m_send_buffer.append_buffer(std::move(buffer), size, size); m_send_buffer.append_buffer(std::move(buffer), size);
} }
int outstanding_bytes() const { return m_outstanding_bytes; } int outstanding_bytes() const { return m_outstanding_bytes; }

View File

@ -33,9 +33,9 @@ POSSIBILITY OF SUCH DAMAGE.
#ifndef TORRENT_RECEIVE_BUFFER_HPP_INCLUDED #ifndef TORRENT_RECEIVE_BUFFER_HPP_INCLUDED
#define TORRENT_RECEIVE_BUFFER_HPP_INCLUDED #define TORRENT_RECEIVE_BUFFER_HPP_INCLUDED
#include <libtorrent/buffer.hpp> #include "libtorrent/buffer.hpp"
#include <libtorrent/disk_buffer_holder.hpp> #include "libtorrent/disk_buffer_holder.hpp"
#include <libtorrent/sliding_average.hpp> #include "libtorrent/sliding_average.hpp"
#include <climits> #include <climits>

View File

@ -31,6 +31,7 @@ POSSIBILITY OF SUCH DAMAGE.
*/ */
#include <cctype> #include <cctype>
#include <cstring>
#include <algorithm> #include <algorithm>
#include <cstdlib> #include <cstdlib>

View File

@ -63,7 +63,7 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/close_reason.hpp" #include "libtorrent/close_reason.hpp"
#include "libtorrent/aux_/has_block.hpp" #include "libtorrent/aux_/has_block.hpp"
#include "libtorrent/aux_/time.hpp" #include "libtorrent/aux_/time.hpp"
#include "libtorrent/aux_/non_owning_handle.hpp" #include "libtorrent/buffer.hpp"
#if TORRENT_USE_ASSERTS #if TORRENT_USE_ASSERTS
#include <set> #include <set>
@ -5360,14 +5360,14 @@ namespace libtorrent {
if (channel == download_channel) if (channel == download_channel)
{ {
return std::max((std::max)(m_outstanding_bytes return std::max(std::max(m_outstanding_bytes
, m_recv_buffer.packet_bytes_remaining()) + 30 , m_recv_buffer.packet_bytes_remaining()) + 30
, int(std::int64_t(m_statistics.download_rate()) * 2 , int(std::int64_t(m_statistics.download_rate()) * 2
* tick_interval / 1000)); * tick_interval / 1000));
} }
else else
{ {
return std::max((std::max)(m_reading_bytes return std::max(std::max(m_reading_bytes
, m_send_buffer.size()) , m_send_buffer.size())
, int((std::int64_t(m_statistics.upload_rate()) * 2 , int((std::int64_t(m_statistics.upload_rate()) * 2
* tick_interval) / 1000)); * tick_interval) / 1000));
@ -5472,18 +5472,18 @@ namespace libtorrent {
{ {
std::vector<span<char>> vec; std::vector<span<char>> vec;
// limit outgoing crypto messages to 1MB // limit outgoing crypto messages to 1MB
int const send_bytes = (std::min)(m_send_buffer.size(), 1024*1024); int const send_bytes = std::min(m_send_buffer.size(), 1024*1024);
m_send_buffer.build_mutable_iovec(send_bytes, vec); m_send_buffer.build_mutable_iovec(send_bytes, vec);
int next_barrier; int next_barrier;
span<span<char const>> inject_vec; span<span<char const>> inject_vec;
std::tie(next_barrier, inject_vec) = hit_send_barrier(vec); std::tie(next_barrier, inject_vec) = hit_send_barrier(vec);
for (auto i = inject_vec.rbegin(); i != inject_vec.rend(); ++i) for (auto i = inject_vec.rbegin(); i != inject_vec.rend(); ++i)
{ {
int const size = int(i->size());
// this const_cast is a here because chained_buffer need to be // this const_cast is a here because chained_buffer need to be
// fixed. // fixed.
char* ptr = const_cast<char*>(i->data()); char* ptr = const_cast<char*>(i->data());
m_send_buffer.prepend_buffer(aux::non_owning_handle(ptr), size, size); m_send_buffer.prepend_buffer(span<char>(ptr, i->size())
, static_cast<int>(i->size()));
} }
set_send_barrier(next_barrier); set_send_barrier(next_barrier);
} }
@ -5693,7 +5693,7 @@ namespace libtorrent {
std::size_t(m_send_buffer.space_in_last_buffer()), buf.size()); std::size_t(m_send_buffer.space_in_last_buffer()), buf.size());
if (free_space > 0) if (free_space > 0)
{ {
char* dst = m_send_buffer.append(buf.subspan(0, free_space)); char* dst = m_send_buffer.append(buf.first(free_space));
// this should always succeed, because we checked how much space // this should always succeed, because we checked how much space
// there was up-front // there was up-front
@ -5703,17 +5703,10 @@ namespace libtorrent {
} }
if (buf.size() <= 0) return; if (buf.size() <= 0) return;
while (buf.size() > 0) // allocate a buffer and initialize the beginning of it with 'buf'
{ buffer snd_buf(std::max(buf.size(), std::size_t(128)), buf);
aux::ses_buffer_holder session_buf = m_ses.allocate_buffer(); m_send_buffer.append_buffer(std::move(snd_buf), int(buf.size()));
int const alloc_buf_size = m_ses.send_buffer_size();
int const buf_size = std::min(alloc_buf_size, int(buf.size()));
std::copy(buf.data(), buf.data() + buf_size, session_buf.get());
buf = buf.subspan(std::size_t(buf_size));
m_send_buffer.append_buffer(std::move(session_buf)
, alloc_buf_size, buf_size);
}
setup_send(); setup_send();
} }

View File

@ -6831,29 +6831,6 @@ namespace {
#endif #endif
} }
ses_buffer_holder session_impl::allocate_buffer()
{
TORRENT_ASSERT(is_single_thread());
#ifdef TORRENT_DISABLE_POOL_ALLOCATOR
std::size_t num_bytes = aux::numeric_cast<std::size_t>(send_buffer_size());
return ses_buffer_holder(*this, static_cast<char*>(std::malloc(num_bytes)));
#else
return ses_buffer_holder(*this, static_cast<char*>(m_send_buffers.malloc()));
#endif
}
void session_impl::free_buffer(char* buf)
{
TORRENT_ASSERT(is_single_thread());
#ifdef TORRENT_DISABLE_POOL_ALLOCATOR
free(buf);
#else
m_send_buffers.free(buf);
#endif
}
#if TORRENT_USE_INVARIANT_CHECKS #if TORRENT_USE_INVARIANT_CHECKS
void session_impl::check_invariant() const void session_impl::check_invariant() const
{ {

View File

@ -52,7 +52,6 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/io.hpp" #include "libtorrent/io.hpp"
#include "libtorrent/performance_counters.hpp" // for counters #include "libtorrent/performance_counters.hpp" // for counters
#include "libtorrent/aux_/time.hpp" #include "libtorrent/aux_/time.hpp"
#include "libtorrent/aux_/non_owning_handle.hpp"
namespace libtorrent {namespace { namespace libtorrent {namespace {
@ -285,7 +284,7 @@ namespace libtorrent {namespace {
if (metadata_piece_size) if (metadata_piece_size)
{ {
m_pc.append_const_send_buffer( m_pc.append_const_send_buffer(
aux::non_owning_handle(const_cast<char*>(metadata)), metadata_piece_size); span<char>(const_cast<char*>(metadata), std::size_t(metadata_piece_size)), metadata_piece_size);
} }
m_pc.stats_counters().inc_stats_counter(counters::num_outgoing_extended); m_pc.stats_counters().inc_stats_counter(counters::num_outgoing_extended);

View File

@ -182,21 +182,24 @@ bool compare_chained_buffer(chained_buffer& b, char const* mem, int size)
struct holder struct holder
{ {
explicit holder(char* buf) : m_buf(buf) {} holder(char* buf, std::size_t size) : m_buf(buf), m_size(size) {}
~holder() { if (m_buf) free_buffer(m_buf); } ~holder() { if (m_buf) free_buffer(m_buf); }
holder(holder const&) = delete; holder(holder const&) = delete;
holder& operator=(holder const&) = delete; holder& operator=(holder const&) = delete;
holder(holder&& rhs) noexcept : m_buf(rhs.m_buf) { rhs.m_buf = nullptr; } holder(holder&& rhs) noexcept : m_buf(rhs.m_buf), m_size(rhs.m_size) { rhs.m_buf = nullptr; }
holder& operator=(holder&& rhs) noexcept holder& operator=(holder&& rhs) noexcept
{ {
if (m_buf) free_buffer(m_buf); if (m_buf) free_buffer(m_buf);
m_buf = rhs.m_buf; m_buf = rhs.m_buf;
m_size = rhs.m_size;
rhs.m_buf = nullptr; rhs.m_buf = nullptr;
return *this; return *this;
} }
char* get() const { return m_buf; } char* data() const { return m_buf; }
std::size_t size() const { return m_size; }
private: private:
char* m_buf; char* m_buf;
std::size_t m_size;
}; };
TORRENT_TEST(chained_buffer) TORRENT_TEST(chained_buffer)
@ -217,7 +220,7 @@ TORRENT_TEST(chained_buffer)
char* b1 = allocate_buffer(512); char* b1 = allocate_buffer(512);
std::memcpy(b1, data, 6); std::memcpy(b1, data, 6);
b.append_buffer(holder(b1), 512, 6); b.append_buffer(holder(b1, 512), 6);
TEST_EQUAL(buffer_list.size(), 1); TEST_EQUAL(buffer_list.size(), 1);
TEST_EQUAL(b.capacity(), 512); TEST_EQUAL(b.capacity(), 512);
@ -247,12 +250,12 @@ TORRENT_TEST(chained_buffer)
char* b2 = allocate_buffer(512); char* b2 = allocate_buffer(512);
std::memcpy(b2, data, 6); std::memcpy(b2, data, 6);
b.append_buffer(holder(b2), 512, 6); b.append_buffer(holder(b2, 512), 6);
TEST_EQUAL(buffer_list.size(), 2); TEST_EQUAL(buffer_list.size(), 2);
char* b3 = allocate_buffer(512); char* b3 = allocate_buffer(512);
std::memcpy(b3, data, 6); std::memcpy(b3, data, 6);
b.append_buffer(holder(b3), 512, 6); b.append_buffer(holder(b3, 512), 6);
TEST_EQUAL(buffer_list.size(), 3); TEST_EQUAL(buffer_list.size(), 3);
TEST_EQUAL(b.capacity(), 512 * 3 - 3); TEST_EQUAL(b.capacity(), 512 * 3 - 3);
@ -267,7 +270,7 @@ TORRENT_TEST(chained_buffer)
b.pop_front(5 + 6); b.pop_front(5 + 6);
TEST_CHECK(buffer_list.size() == 2); TEST_EQUAL(buffer_list.size(), 2);
TEST_EQUAL(b.capacity(), 512 * 2 - 2); TEST_EQUAL(b.capacity(), 512 * 2 - 2);
TEST_EQUAL(b.size(), 10); TEST_EQUAL(b.size(), 10);
TEST_CHECK(!b.empty()); TEST_CHECK(!b.empty());
@ -281,30 +284,30 @@ TORRENT_TEST(chained_buffer)
b.pop_front(1); b.pop_front(1);
++str; ++str;
TEST_CHECK(compare_chained_buffer(b, str, 8 - i)); TEST_CHECK(compare_chained_buffer(b, str, 8 - i));
TEST_CHECK(b.size() == 9 - i); TEST_EQUAL(b.size(), 9 - i);
} }
char* b4 = allocate_buffer(20); char* b4 = allocate_buffer(20);
std::memcpy(b4, data, 6); std::memcpy(b4, data, 6);
std::memcpy(b4 + 6, data, 6); std::memcpy(b4 + 6, data, 6);
b.append_buffer(holder(b4), 20, 12); b.append_buffer(holder(b4, 20), 12);
TEST_CHECK(b.space_in_last_buffer() == 8); TEST_EQUAL(b.space_in_last_buffer(), 8);
ret = b.append({data, 6}) != nullptr; ret = b.append({data, 6}) != nullptr;
TEST_CHECK(ret == true); TEST_CHECK(ret == true);
TEST_CHECK(b.space_in_last_buffer() == 2); TEST_EQUAL(b.space_in_last_buffer(), 2);
std::cout << b.space_in_last_buffer() << std::endl; std::cout << b.space_in_last_buffer() << std::endl;
ret = b.append({data, 2}) != nullptr; ret = b.append({data, 2}) != nullptr;
TEST_CHECK(ret == true); TEST_CHECK(ret == true);
TEST_CHECK(b.space_in_last_buffer() == 0); TEST_EQUAL(b.space_in_last_buffer(), 0);
std::cout << b.space_in_last_buffer() << std::endl; std::cout << b.space_in_last_buffer() << std::endl;
char* b5 = allocate_buffer(20); char* b5 = allocate_buffer(20);
std::memcpy(b5, data, 6); std::memcpy(b5, data, 6);
b.append_buffer(holder(b5), 20, 6); b.append_buffer(holder(b5, 20), 6);
b.pop_front(22); b.pop_front(22);
TEST_CHECK(b.size() == 5); TEST_EQUAL(b.size(), 5);
} }
TEST_CHECK(buffer_list.empty()); TEST_CHECK(buffer_list.empty());
} }