merged RC_1_1 into master

This commit is contained in:
arvidn 2018-04-28 03:25:36 +02:00
commit 8621477239
18 changed files with 87 additions and 67 deletions

View File

@ -753,6 +753,8 @@ void bind_session()
.def_readwrite("added_time", &add_torrent_params::added_time)
.def_readwrite("completed_time", &add_torrent_params::completed_time)
.def_readwrite("last_seen_complete", &add_torrent_params::last_seen_complete)
.def_readwrite("last_download", &add_torrent_params::last_download)
.def_readwrite("last_upload", &add_torrent_params::last_upload)
.def_readwrite("num_complete", &add_torrent_params::num_complete)
.def_readwrite("num_incomplete", &add_torrent_params::num_incomplete)
.def_readwrite("num_downloaded", &add_torrent_params::num_downloaded)

View File

@ -167,9 +167,11 @@ class test_torrent_handle(unittest.TestCase):
sessionStart = datetime.datetime.now().replace(microsecond=0)
self.setup()
st = self.h.status()
for attr in dir(st):
print('%s: %s' % (attr, getattr(st, attr)))
# last upload and download times are at session start time
self.assertLessEqual(abs(st.last_upload - sessionStart), datetime.timedelta(seconds=1))
self.assertLessEqual(abs(st.last_download - sessionStart), datetime.timedelta(seconds=1))
self.assertEqual(st.last_upload, None)
self.assertEqual(st.last_download, None)
def test_serialize_trackers(self):
"""Test to ensure the dict contains only python built-in types"""

View File

@ -434,6 +434,12 @@ The file format is a bencoded dictionary containing the following fields:
| ``seeding_time`` | integer. The number of seconds this torrent has been active |
| | and seeding. |
+--------------------------+--------------------------------------------------------------+
| ``last_upload`` | integer. The number of seconds since epoch when we last |
| | uploaded payload to a peer on this torrent. |
+--------------------------+--------------------------------------------------------------+
| ``last_download`` | integer. The number of seconds since epoch when we last |
| | downloaded payload from a peer on this torrent. |
+--------------------------+--------------------------------------------------------------+
| ``upload_rate_limit`` | integer. In case this torrent has a per-torrent upload rate |
| | limit, this is that limit. In bytes per second. |
+--------------------------+--------------------------------------------------------------+

View File

@ -331,6 +331,9 @@ namespace libtorrent {
// applied before the torrent is added.
aux::noexcept_movable<std::map<file_index_t, std::string>> renamed_files;
std::time_t last_download = 0;
std::time_t last_upload = 0;
#ifndef TORRENT_NO_DEPRECATE
// deprecated in 1.2

View File

@ -195,7 +195,7 @@ namespace detail {
break;
case entry::preformatted_t:
std::copy(e.preformatted().begin(), e.preformatted().end(), out);
ret += int(e.preformatted().size());
ret += static_cast<int>(e.preformatted().size());
break;
case entry::undefined_t:

View File

@ -442,7 +442,8 @@ namespace aux {
// used to convert dirty blocks into non-dirty ones
// i.e. from being part of the write cache to being part
// of the read cache. it's used when flushing blocks to disk
void blocks_flushed(cached_piece_entry* pe, int const* flushed, int num_flushed);
// returns true if the piece entry was freed
bool blocks_flushed(cached_piece_entry* pe, int const* flushed, int num_flushed);
// adds a block to the cache, marks it as dirty and
// associates the job with it. When the block is

View File

@ -450,7 +450,8 @@ namespace aux {
, span<iovec_t> iov, span<int> flushing, int block_base_index = 0);
void flush_iovec(cached_piece_entry* pe, span<iovec_t const> iov, span<int const> flushing
, int num_blocks, storage_error& error);
void iovec_flushed(cached_piece_entry* pe
// returns true if the piece entry was freed
bool iovec_flushed(cached_piece_entry* pe
, int* flushing, int num_blocks, int block_offset
, storage_error const& error
, jobqueue_t& completed_jobs);

View File

@ -1620,9 +1620,8 @@ namespace libtorrent {
// ----
// the timestamp of the last piece passed for this torrent specified in
// session_time. This is signed because it must be able to represent time
// before the session started
time_point32 m_last_download = aux::time_now32();
// seconds since epoch.
time_point32 m_last_download{seconds32(0)};
// the number of peer connections to seeds. This should be the same as
// counting the peer connections that say true for is_seed()
@ -1633,9 +1632,8 @@ namespace libtorrent {
std::uint16_t m_num_connecting_seeds = 0;
// the timestamp of the last byte uploaded from this torrent specified in
// session_time. This is signed because it must be able to represent time
// before the session started.
time_point32 m_last_upload = aux::time_now32();
// seconds since epoch.
time_point32 m_last_upload{seconds32(0)};
// ----
@ -1667,7 +1665,7 @@ namespace libtorrent {
// the timestamp of the last scrape request to one of the trackers in
// this torrent specified in session_time. This is signed because it must
// be able to represent time before the session started
std::int16_t m_last_scrape = (std::numeric_limits<std::int16_t>::min)();
time_point32 m_last_scrape{seconds32(0)};
#endif
// ----

View File

@ -588,9 +588,7 @@ namespace libtorrent {
// the info-hash for this torrent
sha1_hash info_hash;
// This value is not persistent and get set to session start time.
time_point last_upload;
// This value is not persistent and get set to session start time.
time_point last_download;
seconds active_duration;

View File

@ -97,9 +97,9 @@ TORRENT_TEST(status_timers)
TEST_EQUAL(st.finished_duration.count(), since_finish.count());
// does not upload without peers
TEST_CHECK(st.last_upload == start_time);
TEST_CHECK(st.last_upload == time_point(seconds(0)));
// does not download in seeding mode
TEST_CHECK(st.last_download == start_time);
TEST_CHECK(st.last_download == time_point(seconds(0)));
}
return false;
});
@ -110,7 +110,6 @@ TORRENT_TEST(status_timers_last_upload)
{
bool ran_to_completion = false;
lt::time_point32 start_time;
lt::torrent_handle handle;
setup_swarm(2, swarm_test::upload
@ -123,13 +122,12 @@ TORRENT_TEST(status_timers_last_upload)
if (auto ta = alert_cast<add_torrent_alert>(a))
{
TEST_CHECK(!handle.is_valid());
start_time = time_now();
handle = ta->handle;
torrent_status st = handle.status();
// test last upload and download state before wo go throgh
// torrent states
TEST_CHECK(st.last_download == start_time);
TEST_CHECK(st.last_upload == start_time);
TEST_CHECK(st.last_upload == time_point(seconds(0)));
TEST_CHECK(st.last_download == time_point(seconds(0)));
}
}
// terminate
@ -145,7 +143,7 @@ TORRENT_TEST(status_timers_last_upload)
// uploadtime is 0 seconds behind now
TEST_CHECK(eq(st.last_upload, time_now()));
// does not download in seeding mode
TEST_CHECK(eq(st.last_download, start_time));
TEST_CHECK(st.last_download == time_point(seconds(0)));
return false;
});
TEST_CHECK(ran_to_completion);
@ -155,7 +153,6 @@ TORRENT_TEST(status_timers_time_shift_with_active_torrent)
{
bool ran_to_completion = false;
lt::time_point32 start_time;
lt::torrent_handle handle;
seconds expected_active_duration = seconds(1);
bool tick_is_in_active_range = false;
@ -171,13 +168,12 @@ TORRENT_TEST(status_timers_time_shift_with_active_torrent)
if (auto ta = alert_cast<add_torrent_alert>(a))
{
TEST_CHECK(!handle.is_valid());
start_time = time_now();
handle = ta->handle;
torrent_status st = handle.status();
// test last upload and download state before wo go throgh
// torrent states
TEST_CHECK(st.last_download == start_time);
TEST_CHECK(st.last_upload == start_time);
TEST_CHECK(st.last_download == time_point(seconds(0)));
TEST_CHECK(st.last_upload == time_point(seconds(0)));
}
}
// terminate
@ -224,9 +220,9 @@ TORRENT_TEST(status_timers_time_shift_with_active_torrent)
TEST_EQUAL(st.seeding_duration.count(), expected_active_duration.count());
TEST_EQUAL(st.finished_duration.count(), expected_active_duration.count());
// does not upload without peers
TEST_CHECK(st.last_upload == start_time);
TEST_CHECK(st.last_upload == time_point(seconds(0)));
// does not download in seeding mode
TEST_CHECK(st.last_download == start_time);
TEST_CHECK(st.last_download == time_point(seconds(0)));
}
return false;
});
@ -237,7 +233,6 @@ TORRENT_TEST(finish_time_shift_active)
{
bool ran_to_completion = false;
lt::time_point32 start_time;
lt::torrent_handle handle;
seconds expected_active_duration = seconds(1);
bool tick_is_in_active_range = false;
@ -252,13 +247,12 @@ TORRENT_TEST(finish_time_shift_active)
if (auto ta = alert_cast<add_torrent_alert>(a))
{
TEST_CHECK(!handle.is_valid());
start_time = time_now();
handle = ta->handle;
torrent_status st = handle.status();
// test last upload and download state before wo go throgh
// torrent states
TEST_CHECK(st.last_download == start_time);
TEST_CHECK(st.last_upload == start_time);
TEST_CHECK(st.last_download == time_point(seconds(0)));
TEST_CHECK(st.last_upload == time_point(seconds(0)));
}
}
// terminate
@ -298,9 +292,9 @@ TORRENT_TEST(finish_time_shift_active)
TEST_EQUAL(st.seeding_duration.count(), expected_active_duration.count());
TEST_EQUAL(st.finished_duration.count(), expected_active_duration.count());
// does not upload without peers
TEST_CHECK(st.last_upload == start_time);
TEST_CHECK(st.last_upload == time_point(seconds(0)));
// does not download in seeding mode
TEST_CHECK(st.last_download == start_time);
TEST_CHECK(st.last_download == time_point(seconds(0)));
}
return false;
});
@ -311,7 +305,6 @@ TORRENT_TEST(finish_time_shift_paused)
{
bool ran_to_completion = false;
lt::time_point32 start_time;
lt::torrent_handle handle;
seconds expected_active_duration = seconds(1);
bool tick_is_in_active_range = false;
@ -326,13 +319,12 @@ TORRENT_TEST(finish_time_shift_paused)
if (auto ta = alert_cast<add_torrent_alert>(a))
{
TEST_CHECK(!handle.is_valid());
start_time = time_now();
handle = ta->handle;
torrent_status st = handle.status();
// test last upload and download state before wo go throgh
// torrent states
TEST_CHECK(eq(st.last_download, start_time));
TEST_CHECK(eq(st.last_upload, start_time));
TEST_CHECK(st.last_upload == time_point(seconds(0)));
TEST_CHECK(st.last_download == time_point(seconds(0)));
}
}
// terminate
@ -374,9 +366,9 @@ TORRENT_TEST(finish_time_shift_paused)
TEST_EQUAL(st.seeding_duration.count(), expected_active_duration.count());
TEST_EQUAL(st.finished_duration.count(), expected_active_duration.count());
// does not upload without peers
TEST_CHECK(st.last_upload == start_time);
TEST_CHECK(st.last_upload == time_point(seconds(0)));
// does not download in seeding mode
TEST_CHECK(st.last_download == start_time);
TEST_CHECK(st.last_download == time_point(seconds(0)));
}
return false;
});

View File

@ -766,7 +766,7 @@ cached_piece_entry* block_cache::add_dirty_block(disk_io_job* j)
// (since these blocks now are part of the read cache) the refcounts of the
// blocks are also decremented by this function. They are expected to have been
// incremented by the caller.
void block_cache::blocks_flushed(cached_piece_entry* pe, int const* flushed, int num_flushed)
bool block_cache::blocks_flushed(cached_piece_entry* pe, int const* flushed, int num_flushed)
{
TORRENT_PIECE_ASSERT(pe->in_use, pe);
@ -790,7 +790,7 @@ void block_cache::blocks_flushed(cached_piece_entry* pe, int const* flushed, int
pe->num_dirty -= num_flushed;
update_cache_state(pe);
maybe_free_piece(pe);
return maybe_free_piece(pe);
}
std::pair<block_cache::const_iterator, block_cache::const_iterator> block_cache::all_pieces() const

View File

@ -62,9 +62,10 @@ POSSIBILITY OF SUCH DAMAGE.
#define DEBUG_DISK_THREAD 0
#if DEBUG_DISK_THREAD
#include <cstdarg>
#include <cstdarg> // for va_list
#include <sstream>
#include <cstdio> // for vsnprintf
#define DLOG(...) debug_log(__VA_ARGS__)
#else
#define DLOG(...) do {} while(false)
@ -727,7 +728,7 @@ constexpr disk_job_flags_t disk_interface::cache_hit;
// It is necessary to call this function with the blocks produced by
// build_iovec, to reset their state to not being flushed anymore
// the cache needs to be locked when calling this function
void disk_io_thread::iovec_flushed(cached_piece_entry* pe
bool disk_io_thread::iovec_flushed(cached_piece_entry* pe
, int* flushing, int const num_blocks, int const block_offset
, storage_error const& error
, jobqueue_t& completed_jobs)
@ -742,7 +743,8 @@ constexpr disk_job_flags_t disk_interface::cache_hit;
DLOG("%d ", flushing[i]);
DLOG("]\n");
#endif
m_disk_cache.blocks_flushed(pe, flushing, num_blocks);
if (m_disk_cache.blocks_flushed(pe, flushing, num_blocks))
return true;
if (error)
{
@ -770,6 +772,8 @@ constexpr disk_job_flags_t disk_interface::cache_hit;
j = next;
}
}
return false;
}
// issues write operations for blocks in the given
@ -802,9 +806,8 @@ constexpr disk_job_flags_t disk_interface::cache_hit;
flush_iovec(pe, iov, flushing, iov_len, error);
}
iovec_flushed(pe, flushing.data(), iov_len, 0, error, completed_jobs);
m_disk_cache.maybe_free_piece(pe);
if (!iovec_flushed(pe, flushing.data(), iov_len, 0, error, completed_jobs))
m_disk_cache.maybe_free_piece(pe);
// if the cache is under high pressure, we need to evict
// the blocks we just flushed to make room for more write pieces

View File

@ -121,6 +121,9 @@ namespace {
ret.last_seen_complete = std::time_t(rd.dict_find_int_value("last_seen_complete"));
ret.last_download = rd.dict_find_int_value("last_download", 0);
ret.last_upload = rd.dict_find_int_value("last_upload", 0);
// scrape data cache
ret.num_complete = int(rd.dict_find_int_value("num_complete", -1));
ret.num_incomplete = int(rd.dict_find_int_value("num_incomplete", -1));

View File

@ -308,6 +308,8 @@ namespace {
atp.seeding_time = resume_data.seeding_time;
atp.last_seen_complete = resume_data.last_seen_complete;
atp.last_upload = resume_data.last_upload;
atp.last_download = resume_data.last_download;
atp.url = resume_data.url;
atp.uuid = resume_data.uuid;

View File

@ -97,6 +97,8 @@ POSSIBILITY OF SUCH DAMAGE.
// for logging stat layout
#include "libtorrent/stat.hpp"
#include <cstdarg> // for va_list
// for logging the size of DHT structures
#ifndef TORRENT_DISABLE_DHT
#include <libtorrent/kademlia/find_data.hpp>

View File

@ -181,6 +181,8 @@ bool is_downloading_state(int const st)
, bool const session_paused
, add_torrent_params const& p)
: torrent_hot_members(ses, p, session_paused)
, m_total_uploaded(p.total_uploaded)
, m_total_downloaded(p.total_downloaded)
, m_tracker_timer(ses.get_io_service())
, m_inactivity_timer(ses.get_io_service())
, m_trackerid(p.trackerid)
@ -224,6 +226,8 @@ bool is_downloading_state(int const st)
, m_announce_to_dht(!(p.flags & torrent_flags::paused))
, m_ssl_torrent(false)
, m_deleted(false)
, m_last_download(seconds32(p.last_download))
, m_last_upload(seconds32(p.last_upload))
, m_auto_managed(p.flags & torrent_flags::auto_managed)
, m_current_gauge_state(static_cast<std::uint32_t>(no_gauge_state))
, m_moving_storage(false)
@ -2968,7 +2972,7 @@ bool is_downloading_state(int const st)
{
TORRENT_ASSERT(is_single_thread());
#ifndef TORRENT_NO_DEPRECATE
m_last_scrape = std::int16_t(m_ses.session_time());
m_last_scrape = aux::time_now32();
#endif
if (m_trackers.empty()) return;
@ -3151,7 +3155,7 @@ bool is_downloading_state(int const st)
#ifndef TORRENT_NO_DEPRECATE
if (resp.complete >= 0 && resp.incomplete >= 0)
m_last_scrape = std::int16_t(m_ses.session_time());
m_last_scrape = aux::time_now32();
#endif
#ifndef TORRENT_DISABLE_LOGGING
@ -6110,6 +6114,8 @@ bool is_downloading_state(int const st)
ret.finished_time = static_cast<int>(total_seconds(finished_time()));
ret.seeding_time = static_cast<int>(total_seconds(seeding_time()));
ret.last_seen_complete = m_last_seen_complete;
ret.last_upload = total_seconds(m_last_upload.time_since_epoch());
ret.last_download = total_seconds(m_last_download.time_since_epoch());
ret.num_complete = m_complete;
ret.num_incomplete = m_incomplete;
@ -8296,14 +8302,7 @@ bool is_downloading_state(int const st)
if (a < b) return 0;
return std::uint16_t(a - b);
}
#ifndef TORRENT_NO_DEPRECATE
std::int16_t clamped_subtract_s16(int a, int b)
{
if (a + std::numeric_limits<std::int16_t>::min() < b)
return std::numeric_limits<std::int16_t>::min();
return std::int16_t(a - b);
}
#endif
} // anonymous namespace
// this is called every time the session timer takes a step back. Since the
@ -8324,10 +8323,6 @@ bool is_downloading_state(int const st)
pe->last_connected = clamped_subtract_u16(pe->last_connected, seconds);
}
}
#ifndef TORRENT_NO_DEPRECATE
m_last_scrape = clamped_subtract_s16(m_last_scrape, seconds);
#endif
}
// the higher seed rank, the more important to seed
@ -10637,8 +10632,7 @@ bool is_downloading_state(int const st)
st->completed_time = m_completed_time;
#ifndef TORRENT_NO_DEPRECATE
st->last_scrape = m_last_scrape == std::numeric_limits<std::int16_t>::min() ? -1
: clamped_subtract_u16(m_ses.session_time(), m_last_scrape);
st->last_scrape = static_cast<int>(total_seconds(aux::time_now32() - m_last_scrape));
#endif
#ifndef TORRENT_NO_DEPRECATE
@ -10667,10 +10661,12 @@ bool is_downloading_state(int const st)
st->active_time = int(total_seconds(active_time()));
st->seeding_time = int(total_seconds(seeding_time()));
st->time_since_upload = int(total_seconds(aux::time_now()
- m_last_upload));
st->time_since_download = int(total_seconds(aux::time_now()
- m_last_download));
time_point32 const unset{seconds32(0)};
st->time_since_upload = m_last_upload == unset ? -1
: static_cast<int>(total_seconds(aux::time_now32() - m_last_upload));
st->time_since_download = m_last_download == unset ? -1
: static_cast<int>(total_seconds(aux::time_now32() - m_last_download));
#endif
st->finished_duration = finished_time();

View File

@ -63,6 +63,8 @@ namespace libtorrent {
ret["finished_time"] = atp.finished_time;
ret["seeding_time"] = atp.seeding_time;
ret["last_seen_complete"] = atp.last_seen_complete;
ret["last_download"] = atp.last_download;
ret["last_upload"] = atp.last_upload;
ret["num_complete"] = atp.num_complete;
ret["num_incomplete"] = atp.num_incomplete;

View File

@ -111,6 +111,8 @@ std::vector<char> generate_resume_data(torrent_info* ti
rd["super_seeding"] = 0;
rd["added_time"] = 1347;
rd["completed_time"] = 1348;
rd["last_download"] = 2;
rd["last_upload"] = 3;
rd["finished_time"] = 1352;
if (file_priorities && file_priorities[0])
{
@ -208,6 +210,13 @@ void default_tests(torrent_status const& s)
#ifndef TORRENT_NO_DEPRECATE
TEST_CHECK(s.active_time >= 1339);
TEST_CHECK(s.active_time < 1339 + 10);
auto const now = duration_cast<seconds>(clock_type::now().time_since_epoch()).count();
TEST_CHECK(s.time_since_download >= now - 2);
TEST_CHECK(s.time_since_upload >= now - 3);
TEST_CHECK(s.time_since_download < now - 2 + 10);
TEST_CHECK(s.time_since_upload < now - 3 + 10);
#endif
using lt::seconds;