forked from premiere/premiere-libtorrent
fix to make active_time, seeding_time, finished_time and upload_only_time all work for torrents that are not being ticked
This commit is contained in:
parent
7bc35c1e63
commit
db788c9180
|
@ -447,6 +447,10 @@ namespace libtorrent
|
|||
void do_pause();
|
||||
void do_resume();
|
||||
|
||||
int finished_time() const;
|
||||
int active_time() const;
|
||||
int seeding_time() const;
|
||||
|
||||
bool is_paused() const;
|
||||
bool allows_peers() const { return m_allow_peers; }
|
||||
bool is_torrent_paused() const { return !m_allow_peers || m_graceful_pause_mode; }
|
||||
|
@ -686,7 +690,7 @@ namespace libtorrent
|
|||
void announce_with_tracker(boost::uint8_t e
|
||||
= tracker_request::none
|
||||
, address const& bind_interface = address_v4::any());
|
||||
int seconds_since_last_scrape() const { return m_last_scrape; }
|
||||
int seconds_since_last_scrape() const { return m_ses.session_time() - m_last_scrape; }
|
||||
|
||||
#ifndef TORRENT_DISABLE_DHT
|
||||
void dht_announce();
|
||||
|
@ -1028,7 +1032,7 @@ namespace libtorrent
|
|||
// that are not private
|
||||
void lsd_announce();
|
||||
|
||||
void update_last_upload() { m_last_upload = 0; }
|
||||
void update_last_upload() { m_last_upload = m_ses.session_time(); }
|
||||
|
||||
void set_apply_ip_filter(bool b);
|
||||
bool apply_ip_filter() const { return m_apply_ip_filter; }
|
||||
|
@ -1307,6 +1311,14 @@ namespace libtorrent
|
|||
// hours to keep the timestamps fit in 16 bits
|
||||
boost::uint16_t m_started;
|
||||
|
||||
// if we're a seed, this is the session time
|
||||
// timestamp of when we became one
|
||||
boost::uint16_t m_became_seed;
|
||||
|
||||
// if we're finished, this is the session time
|
||||
// timestamp of when we finished
|
||||
boost::uint16_t m_became_finished;
|
||||
|
||||
// when checking, this is the first piece we have not
|
||||
// issued a hash job for
|
||||
int m_checking_piece;
|
||||
|
@ -1357,8 +1369,9 @@ namespace libtorrent
|
|||
// 8 bits after each one
|
||||
// ==============================
|
||||
|
||||
// the number of seconds we've been in upload mode
|
||||
unsigned int m_upload_mode_time:24;
|
||||
// the session time timestamp of when we entered upload mode
|
||||
// if we're currently in upload-mode
|
||||
boost::uint16_t m_upload_mode_time;
|
||||
|
||||
// true when this torrent should anncounce to
|
||||
// trackers
|
||||
|
@ -1551,9 +1564,11 @@ namespace libtorrent
|
|||
|
||||
// ----
|
||||
|
||||
// the number of seconds since the last piece passed for
|
||||
// this torrent
|
||||
boost::uint64_t m_last_download:24;
|
||||
// the timestamp of the last piece passed for this torrent
|
||||
// specified in session_time
|
||||
boost::uint16_t m_last_download;
|
||||
|
||||
// TODO: 8 bits free here
|
||||
|
||||
// this is a second count-down to when we should tick the
|
||||
// storage for this torrent. Ticking the storage is used
|
||||
|
@ -1565,9 +1580,11 @@ namespace libtorrent
|
|||
|
||||
// ----
|
||||
|
||||
// the number of seconds since the last byte was uploaded
|
||||
// from this torrent
|
||||
boost::uint64_t m_last_upload:24;
|
||||
// the timestamp of the last byte uploaded from this torrent
|
||||
// specified in session_time
|
||||
boost::uint16_t m_last_upload;
|
||||
|
||||
// TODO: 8 bits here
|
||||
|
||||
// if this is true, libtorrent may pause and resume
|
||||
// this torrent depending on queuing rules. Torrents
|
||||
|
@ -1596,9 +1613,10 @@ namespace libtorrent
|
|||
// is optional and may be 0xffffff
|
||||
unsigned int m_downloaded:24;
|
||||
|
||||
// the number of seconds since the last scrape request to
|
||||
// the timestamp of the last scrape request to
|
||||
// one of the trackers in this torrent
|
||||
boost::uint64_t m_last_scrape:16;
|
||||
// specified in session_time
|
||||
boost::uint16_t m_last_scrape;
|
||||
|
||||
// ----
|
||||
|
||||
|
|
156
src/torrent.cpp
156
src/torrent.cpp
|
@ -167,6 +167,8 @@ namespace libtorrent
|
|||
, m_num_verified(0)
|
||||
, m_last_saved_resume(ses.session_time())
|
||||
, m_started(ses.session_time())
|
||||
, m_became_seed(0)
|
||||
, m_became_finished(0)
|
||||
, m_checking_piece(0)
|
||||
, m_num_checked_pieces(0)
|
||||
, m_refcount(0)
|
||||
|
@ -1023,7 +1025,7 @@ namespace libtorrent
|
|||
p->cancel_all_requests();
|
||||
}
|
||||
// this is used to try leaving upload only mode periodically
|
||||
m_upload_mode_time = 0;
|
||||
m_upload_mode_time = m_ses.session_time();
|
||||
}
|
||||
else if (m_policy)
|
||||
{
|
||||
|
@ -2758,7 +2760,7 @@ namespace libtorrent
|
|||
if (i->verified) ++verified_trackers;
|
||||
|
||||
if (verified_trackers > 0)
|
||||
debug_log("DHT: only using DHT as callback, and there are %d working trackers", verified_trackers);
|
||||
debug_log("DHT: only using DHT as fallback, and there are %d working trackers", verified_trackers);
|
||||
}
|
||||
#endif
|
||||
return;
|
||||
|
@ -3033,7 +3035,7 @@ namespace libtorrent
|
|||
void torrent::scrape_tracker()
|
||||
{
|
||||
TORRENT_ASSERT(m_ses.is_single_thread());
|
||||
m_last_scrape = 0;
|
||||
m_last_scrape = m_ses.session_time();
|
||||
|
||||
if (m_trackers.empty()) return;
|
||||
|
||||
|
@ -3169,7 +3171,7 @@ namespace libtorrent
|
|||
update_tracker_timer(now);
|
||||
|
||||
if (complete >= 0 && incomplete >= 0)
|
||||
m_last_scrape = 0;
|
||||
m_last_scrape = m_ses.session_time();
|
||||
|
||||
#if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING
|
||||
debug_log("TRACKER RESPONSE\n"
|
||||
|
@ -4023,7 +4025,7 @@ namespace libtorrent
|
|||
// is deallocated by the torrent once it starts seeding
|
||||
}
|
||||
|
||||
m_last_download = 0;
|
||||
m_last_download = m_ses.session_time();
|
||||
|
||||
if (m_share_mode)
|
||||
recalc_share_mode();
|
||||
|
@ -6455,10 +6457,6 @@ namespace libtorrent
|
|||
}
|
||||
super_seeding(rd.dict_find_int_value("super_seeding", 0));
|
||||
|
||||
m_last_scrape = rd.dict_find_int_value("last_scrape", 0);
|
||||
m_last_download = rd.dict_find_int_value("last_download", 0);
|
||||
m_last_upload = rd.dict_find_int_value("last_upload", 0);
|
||||
|
||||
if (!m_use_resume_save_path)
|
||||
{
|
||||
std::string p = rd.dict_find_string_value("save_path");
|
||||
|
@ -6674,9 +6672,9 @@ namespace libtorrent
|
|||
ret["total_uploaded"] = m_total_uploaded;
|
||||
ret["total_downloaded"] = m_total_downloaded;
|
||||
|
||||
ret["active_time"] = m_active_time;
|
||||
ret["finished_time"] = m_finished_time;
|
||||
ret["seeding_time"] = m_seeding_time;
|
||||
ret["active_time"] = active_time();
|
||||
ret["finished_time"] = finished_time();
|
||||
ret["seeding_time"] = seeding_time();
|
||||
ret["last_seen_complete"] = m_last_seen_complete;
|
||||
|
||||
ret["num_complete"] = m_complete;
|
||||
|
@ -6691,10 +6689,6 @@ namespace libtorrent
|
|||
ret["added_time"] = m_added_time;
|
||||
ret["completed_time"] = m_completed_time;
|
||||
|
||||
ret["last_scrape"] = m_last_scrape;
|
||||
ret["last_download"] = m_last_download;
|
||||
ret["last_upload"] = m_last_upload;
|
||||
|
||||
ret["save_path"] = m_save_path;
|
||||
|
||||
if (!m_url.empty()) ret["url"] = m_url;
|
||||
|
@ -7828,6 +7822,8 @@ namespace libtorrent
|
|||
set_state(torrent_status::finished);
|
||||
set_queue_position(-1);
|
||||
|
||||
m_became_finished = m_ses.session_time();
|
||||
|
||||
// we have to call completed() before we start
|
||||
// disconnecting peers, since there's an assert
|
||||
// to make sure we're cleared the piece picker
|
||||
|
@ -7939,6 +7935,8 @@ namespace libtorrent
|
|||
maybe_done_flushing();
|
||||
|
||||
set_state(torrent_status::seeding);
|
||||
m_became_seed = m_ses.session_time();
|
||||
|
||||
// no need for this anymore
|
||||
std::vector<boost::uint64_t>().swap(m_file_progress);
|
||||
if (!m_announcing) return;
|
||||
|
@ -8672,6 +8670,19 @@ namespace libtorrent
|
|||
}
|
||||
}
|
||||
|
||||
int clamped_subtract(int a, int b)
|
||||
{
|
||||
if (a < b) return 0;
|
||||
return a - b;
|
||||
}
|
||||
|
||||
// this is called every time the session timer takes a step back. Since the
|
||||
// session time is meant to fit in 16 bits, it only covers a range of
|
||||
// about 18 hours. This means every few hours the whole epoch of this
|
||||
// clock is shifted forward. All timestamp in this clock must then be
|
||||
// shifted backwards to remain the same. Anything that's shifted back
|
||||
// beyond the new epoch is clamped to 0 (to represent the oldest timestamp
|
||||
// currently representable by the session_time)
|
||||
void torrent::step_session_time(int seconds)
|
||||
{
|
||||
if (m_policy)
|
||||
|
@ -8681,22 +8692,36 @@ namespace libtorrent
|
|||
{
|
||||
torrent_peer* pe = *j;
|
||||
|
||||
if (pe->last_optimistically_unchoked < seconds)
|
||||
pe->last_optimistically_unchoked = 0;
|
||||
else
|
||||
pe->last_optimistically_unchoked -= seconds;
|
||||
|
||||
if (pe->last_connected < seconds)
|
||||
pe->last_connected = 0;
|
||||
else
|
||||
pe->last_connected -= seconds;
|
||||
pe->last_optimistically_unchoked
|
||||
= clamped_subtract(pe->last_optimistically_unchoked, seconds);
|
||||
pe->last_connected = clamped_subtract(pe->last_connected, seconds);
|
||||
}
|
||||
}
|
||||
|
||||
if (m_started < seconds) m_started = 0;
|
||||
else m_started -= seconds;
|
||||
if (m_last_saved_resume < seconds) m_last_saved_resume = 0;
|
||||
else m_last_saved_resume -= seconds;
|
||||
if (m_started < seconds)
|
||||
{
|
||||
// the started time just got shifted out of the valid window of
|
||||
// session time. Record this "lost time" by incrementing the
|
||||
// counters that are supposed to keep track of the total time we've
|
||||
// been in certain states
|
||||
int lost_seconds = m_started - seconds;
|
||||
if (!is_paused())
|
||||
m_active_time += lost_seconds;
|
||||
|
||||
if (is_seed())
|
||||
m_seeding_time += lost_seconds;
|
||||
|
||||
if (is_finished())
|
||||
m_finished_time += lost_seconds;
|
||||
}
|
||||
|
||||
m_started = clamped_subtract(m_started, seconds);
|
||||
|
||||
m_last_upload = clamped_subtract(m_last_upload, seconds);
|
||||
m_last_download = clamped_subtract(m_last_download, seconds);
|
||||
m_last_scrape = clamped_subtract(m_last_scrape, seconds);
|
||||
m_last_saved_resume = clamped_subtract(m_last_saved_resume, seconds);
|
||||
m_upload_mode_time = clamped_subtract(m_upload_mode_time, seconds);
|
||||
}
|
||||
|
||||
// the higher seed rank, the more important to seed
|
||||
|
@ -8718,16 +8743,16 @@ namespace libtorrent
|
|||
|
||||
int ret = 0;
|
||||
|
||||
size_type finished_time = m_finished_time;
|
||||
size_type download_time = int(m_active_time) - finished_time;
|
||||
size_type fin_time = finished_time();
|
||||
size_type download_time = int(active_time()) - fin_time;
|
||||
|
||||
// if we haven't yet met the seed limits, set the seed_ratio_not_met
|
||||
// flag. That will make this seed prioritized
|
||||
// downloaded may be 0 if the torrent is 0-sized
|
||||
size_type downloaded = (std::max)(m_total_downloaded, m_torrent_file->total_size());
|
||||
if (finished_time < s.get_int(settings_pack::seed_time_limit)
|
||||
if (fin_time < s.get_int(settings_pack::seed_time_limit)
|
||||
&& (download_time > 1
|
||||
&& finished_time * 100 / download_time < s.get_int(settings_pack::seed_time_ratio_limit))
|
||||
&& fin_time * 100 / download_time < s.get_int(settings_pack::seed_time_ratio_limit))
|
||||
&& downloaded > 0
|
||||
&& m_total_uploaded * 100 / downloaded < s.get_int(settings_pack::share_ratio_limit))
|
||||
ret |= seed_ratio_not_met;
|
||||
|
@ -8931,8 +8956,17 @@ namespace libtorrent
|
|||
}
|
||||
#endif
|
||||
|
||||
m_need_connect_boost = true;
|
||||
m_inactive = false;
|
||||
|
||||
m_active_time += m_ses.session_time() - m_started;
|
||||
|
||||
if (is_seed())
|
||||
m_seeding_time += m_ses.session_time() - m_became_seed;
|
||||
|
||||
if (is_finished())
|
||||
m_finished_time += m_ses.session_time() - m_became_finished;
|
||||
|
||||
state_updated();
|
||||
update_want_peers();
|
||||
update_want_scrape();
|
||||
|
@ -9136,6 +9170,9 @@ namespace libtorrent
|
|||
alerts().post_alert(torrent_resumed_alert(get_handle()));
|
||||
|
||||
m_started = m_ses.session_time();
|
||||
if (is_seed()) m_became_seed = m_started;
|
||||
if (is_finished()) m_became_finished = m_started;
|
||||
|
||||
clear_error();
|
||||
|
||||
state_updated();
|
||||
|
@ -9144,6 +9181,8 @@ namespace libtorrent
|
|||
update_want_scrape();
|
||||
|
||||
start_announcing();
|
||||
|
||||
do_connect_boost();
|
||||
}
|
||||
|
||||
void torrent::update_tracker_timer(ptime now)
|
||||
|
@ -9307,7 +9346,25 @@ namespace libtorrent
|
|||
announce_with_tracker(tracker_request::stopped);
|
||||
}
|
||||
|
||||
void torrent::second_tick(int tick_interval_ms, int residual)
|
||||
int torrent::finished_time() const
|
||||
{
|
||||
return m_finished_time + ((!is_finished() || is_paused()) ? 0
|
||||
: (m_ses.session_time() - m_became_finished));
|
||||
}
|
||||
|
||||
int torrent::active_time() const
|
||||
{
|
||||
return m_active_time + (is_paused() ? 0
|
||||
: m_ses.session_time() - m_started);
|
||||
}
|
||||
|
||||
int torrent::seeding_time() const
|
||||
{
|
||||
return m_seeding_time + ((!is_seed() || is_paused()) ? 0
|
||||
: m_ses.session_time() - m_became_seed);
|
||||
}
|
||||
|
||||
void torrent::second_tick(int tick_interval_ms, int /* residual */)
|
||||
{
|
||||
TORRENT_ASSERT(want_tick());
|
||||
TORRENT_ASSERT(m_ses.is_single_thread());
|
||||
|
@ -9330,7 +9387,8 @@ namespace libtorrent
|
|||
// if we're in upload only mode and we're auto-managed
|
||||
// leave upload mode every 10 minutes hoping that the error
|
||||
// condition has been fixed
|
||||
if (m_upload_mode && m_auto_managed && int(m_upload_mode_time)
|
||||
if (m_upload_mode && m_auto_managed
|
||||
&& int(m_ses.session_time() - m_upload_mode_time)
|
||||
>= settings().get_int(settings_pack::optimistic_disk_retry))
|
||||
{
|
||||
set_upload_mode(false);
|
||||
|
@ -9405,16 +9463,6 @@ namespace libtorrent
|
|||
}
|
||||
}
|
||||
|
||||
int seconds_since_last_tick = 1 + residual;
|
||||
|
||||
if (is_seed()) m_seeding_time += seconds_since_last_tick;
|
||||
if (is_finished()) m_finished_time += seconds_since_last_tick;
|
||||
if (m_upload_mode) m_upload_mode_time += seconds_since_last_tick;
|
||||
m_last_scrape += seconds_since_last_tick;
|
||||
m_active_time += seconds_since_last_tick;
|
||||
m_last_download += seconds_since_last_tick;
|
||||
m_last_upload += seconds_since_last_tick;
|
||||
|
||||
// ---- TIME CRITICAL PIECES ----
|
||||
|
||||
#if TORRENT_DEBUG_STREAMING > 0
|
||||
|
@ -9499,6 +9547,8 @@ namespace libtorrent
|
|||
if (m_stat.low_pass_upload_rate() > 0 || m_stat.low_pass_download_rate() > 0)
|
||||
state_updated();
|
||||
|
||||
// TODO: 4 this logic doesn't work for seeding torrents that are not ticked
|
||||
|
||||
// this section determines whether the torrent is active or not. When it
|
||||
// changes state, it may also trigger the auto-manage logic to reconsider
|
||||
// which torrents should be queued and started. There is a low pass
|
||||
|
@ -11035,7 +11085,9 @@ namespace libtorrent
|
|||
st->added_time = m_added_time;
|
||||
st->completed_time = m_completed_time;
|
||||
|
||||
st->last_scrape = m_last_scrape;
|
||||
st->last_scrape = m_last_scrape == 0 ? -1
|
||||
: m_ses.session_time() - m_last_scrape;
|
||||
|
||||
st->share_mode = m_share_mode;
|
||||
st->upload_mode = m_upload_mode;
|
||||
st->up_bandwidth_queue = 0;
|
||||
|
@ -11062,11 +11114,13 @@ namespace libtorrent
|
|||
st->all_time_download = m_total_downloaded;
|
||||
|
||||
// activity time
|
||||
st->finished_time = m_finished_time;
|
||||
st->active_time = m_active_time;
|
||||
st->seeding_time = m_seeding_time;
|
||||
st->time_since_upload = m_last_upload;
|
||||
st->time_since_download = m_last_download;
|
||||
st->finished_time = finished_time();
|
||||
st->active_time = active_time();
|
||||
st->seeding_time = seeding_time();
|
||||
st->time_since_upload = m_last_upload == 0 ? -1
|
||||
: m_ses.session_time() - m_last_upload;
|
||||
st->time_since_download = m_last_download == 0 ? -1
|
||||
: m_ses.session_time() - m_last_download;
|
||||
|
||||
st->storage_mode = (storage_mode_t)m_storage_mode;
|
||||
|
||||
|
|
Loading…
Reference in New Issue