merged RC_1_1 into master

This commit is contained in:
Arvid Norberg 2018-06-06 13:44:02 +02:00
commit e88339378c
6 changed files with 68 additions and 4 deletions

View File

@ -84,6 +84,8 @@
* resume data no longer has timestamps of files
* require C++11 to build libtorrent
* fixed race condition in random number generator
* fix race condition in stat_cache (disk storage)
* improve error handling of failing to change file priority
The API for custom storage implementations was altered
* set the hidden attribute when creating the part file

View File

@ -73,8 +73,8 @@ namespace libtorrent {
// don't add more than this number of alerts, unless it's a
// high priority alert, in which case we try harder to deliver it
// for high priority alerts, double the upper limit
if (m_alerts[m_generation].size() >= m_queue_size_limit
* (1 + T::priority))
if (m_alerts[m_generation].size() / (1 + T::priority)
>= m_queue_size_limit)
{
// record that we dropped an alert of this type
m_dropped.set(T::alert_type);

View File

@ -36,6 +36,7 @@ POSSIBILITY OF SUCH DAMAGE.
#include <vector>
#include <string>
#include <cstdint>
#include <mutex>
#include "libtorrent/config.hpp"
#include "libtorrent/error_code.hpp"
@ -74,6 +75,9 @@ namespace libtorrent {
private:
void set_cache_impl(file_index_t i, std::int64_t size);
void set_error_impl(file_index_t i, error_code const& ec);
// returns the index to the specified error. Either an existing one or a
// newly added entry
int add_error(error_code const& ec);
@ -90,6 +94,8 @@ namespace libtorrent {
std::int64_t file_size;
};
mutable std::mutex m_mutex;
// one entry per file
aux::vector<stat_cache_t, file_index_t> m_stat_cache;

View File

@ -36,6 +36,10 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/aux_/openssl.hpp"
#include "libtorrent/aux_/throw.hpp"
#if defined BOOST_NO_CXX11_THREAD_LOCAL
#include <mutex>
#endif
#if TORRENT_USE_CRYPTOAPI
#include "libtorrent/aux_/win_crypto_provider.hpp"
@ -54,6 +58,15 @@ extern "C" {
#include "libtorrent/aux_/dev_random.hpp"
#endif
#ifdef BOOST_NO_CXX11_THREAD_LOCAL
namespace {
// if the random number generator can't be thread local, just protect it with
// a mutex. Not ideal, but hopefully not too many people are affected by old
// systems
std::mutex rng_mutex;
}
#endif
namespace libtorrent { namespace aux {
std::mt19937& random_engine()
@ -62,8 +75,13 @@ namespace libtorrent { namespace aux {
// make sure random numbers are deterministic. Seed with a fixed number
static std::mt19937 rng(0x82daf973);
#else
static std::random_device dev;
#ifdef BOOST_NO_CXX11_THREAD_LOCAL
static std::mt19937 rng(dev());
#else
thread_local static std::mt19937 rng(dev());
#endif
#endif
return rng;
}
@ -102,6 +120,9 @@ namespace libtorrent { namespace aux {
std::uint32_t random(std::uint32_t const max)
{
#ifdef BOOST_NO_CXX11_THREAD_LOCAL
std::lock_guard<std::mutex> l(rng_mutex);
#endif
return std::uniform_int_distribution<std::uint32_t>(0, max)(aux::random_engine());
}
}

View File

@ -41,6 +41,12 @@ namespace libtorrent {
stat_cache::~stat_cache() = default;
void stat_cache::set_cache(file_index_t const i, std::int64_t const size)
{
std::lock_guard<std::mutex> l(m_mutex);
set_cache_impl(i, size);
}
void stat_cache::set_cache_impl(file_index_t const i, std::int64_t const size)
{
if (i >= m_stat_cache.end_index())
m_stat_cache.resize(static_cast<int>(i) + 1, not_in_cache);
@ -48,6 +54,12 @@ namespace libtorrent {
}
void stat_cache::set_error(file_index_t const i, error_code const& ec)
{
std::lock_guard<std::mutex> l(m_mutex);
set_error_impl(i, ec);
}
void stat_cache::set_error_impl(file_index_t const i, error_code const& ec)
{
if (i >= m_stat_cache.end_index())
m_stat_cache.resize(static_cast<int>(i) + 1, not_in_cache);
@ -58,6 +70,7 @@ namespace libtorrent {
void stat_cache::set_dirty(file_index_t const i)
{
std::lock_guard<std::mutex> l(m_mutex);
if (i >= m_stat_cache.end_index()) return;
m_stat_cache[i].file_size = not_in_cache;
}
@ -65,6 +78,7 @@ namespace libtorrent {
std::int64_t stat_cache::get_filesize(file_index_t const i, file_storage const& fs
, std::string const& save_path, error_code& ec)
{
std::lock_guard<std::mutex> l(m_mutex);
TORRENT_ASSERT(i < fs.end_file());
if (i >= m_stat_cache.end_index()) m_stat_cache.resize(static_cast<int>(i) + 1, not_in_cache);
std::int64_t sz = m_stat_cache[i].file_size;
@ -81,12 +95,12 @@ namespace libtorrent {
stat_file(file_path, &s, ec);
if (ec)
{
set_error(i, ec);
set_error_impl(i, ec);
sz = file_error;
}
else
{
set_cache(i, s.file_size);
set_cache_impl(i, s.file_size);
sz = s.file_size;
}
}
@ -95,11 +109,13 @@ namespace libtorrent {
void stat_cache::reserve(int num_files)
{
std::lock_guard<std::mutex> l(m_mutex);
m_stat_cache.resize(num_files, not_in_cache);
}
void stat_cache::clear()
{
std::lock_guard<std::mutex> l(m_mutex);
m_stat_cache.clear();
m_stat_cache.shrink_to_fit();
m_errors.clear();

View File

@ -80,6 +80,25 @@ TORRENT_TEST(limit)
TEST_EQUAL(alerts.size(), 201);
}
TORRENT_TEST(limit_int_max)
{
int const inf = std::numeric_limits<int>::max();
alert_manager mgr(inf, alert::all_categories);
TEST_EQUAL(mgr.alert_queue_size_limit(), inf);
for (piece_index_t i{0}; i < piece_index_t{600}; ++i)
mgr.emplace_alert<piece_finished_alert>(torrent_handle(), i);
for (piece_index_t i{0}; i < piece_index_t{600}; ++i)
mgr.emplace_alert<torrent_removed_alert>(torrent_handle(), sha1_hash());
std::vector<alert*> alerts;
mgr.get_all(alerts);
TEST_EQUAL(alerts.size(), 1200);
}
TORRENT_TEST(priority_limit)
{
alert_manager mgr(100, alert::all_categories);