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:
parent
cc3f73de96
commit
1075ae3b8d
|
@ -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
14
Jamfile
|
@ -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
|
||||||
;
|
;
|
||||||
|
|
23
configure.ac
23
configure.ac
|
@ -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}
|
||||||
|
|
|
@ -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 |
|
||||||
|
|
|
@ -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 \
|
||||||
|
|
|
@ -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
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
||||||
|
|
|
@ -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; }
|
||||||
|
|
|
@ -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>
|
||||||
|
|
||||||
|
|
|
@ -31,6 +31,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <cctype>
|
#include <cctype>
|
||||||
|
#include <cstring>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
{
|
{
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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());
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue