diff --git a/libtransmission/torrent.cc b/libtransmission/torrent.cc index 0303fe1e5..20f3fe0c6 100644 --- a/libtransmission/torrent.cc +++ b/libtransmission/torrent.cc @@ -712,7 +712,6 @@ void tr_torrent::start_in_session_thread() time_t const now = tr_time(); is_running_ = true; - completeness_ = completion_.status(); date_started_ = now; mark_changed(); error().clear(); @@ -947,8 +946,8 @@ void tr_torrent::on_metainfo_completed() else { completion_.set_has_all(); - date_done_ = date_added_; recheck_completeness(); + date_done_ = date_added_; // Must be after recheck_completeness() if (start_when_stable_) { @@ -967,6 +966,8 @@ void tr_torrent::init(tr_ctor const& ctor) TR_ASSERT(session != nullptr); auto const lock = unique_lock(); + auto const now_sec = tr_time(); + queue_position_ = std::size(session->torrents()); on_metainfo_updated(); @@ -1000,7 +1001,7 @@ void tr_torrent::init(tr_ctor const& ctor) mark_changed(); - date_added_ = tr_time(); // this is a default that will be overwritten by the resume file + date_added_ = now_sec; // this is a default that will be overwritten by the resume file tr_resume::fields_t loaded = {}; @@ -1100,6 +1101,12 @@ void tr_torrent::init(tr_ctor const& ctor) { set_local_error_if_files_disappeared(this, has_any_local_data); } + + // Recover from the bug reported at https://github.com/transmission/transmission/issues/6899 + if (is_done() && date_done_ == time_t{}) + { + date_done_ = now_sec; + } } void tr_torrent::set_metainfo(tr_torrent_metainfo tm) @@ -1853,15 +1860,12 @@ void tr_torrent::recheck_completeness() bool const recent_change = bytes_downloaded_.during_this_session() != 0U; bool const was_running = is_running(); - if (recent_change) - { - tr_logAddTraceTor( - this, - fmt::format( - "State changed from {} to {}", - get_completion_string(completeness_), - get_completion_string(new_completeness))); - } + tr_logAddTraceTor( + this, + fmt::format( + "State changed from {} to {}", + get_completion_string(completeness_), + get_completion_string(new_completeness))); completeness_ = new_completeness; session->close_torrent_files(id()); @@ -1870,10 +1874,12 @@ void tr_torrent::recheck_completeness() { if (recent_change) { + // https://www.bittorrent.org/beps/bep_0003.html + // ...and one using completed is sent when the download is complete. + // No completed is sent if the file was complete when started. tr_announcerTorrentCompleted(this); - mark_changed(); - date_done_ = tr_time(); } + date_done_ = tr_time(); if (current_dir() == incomplete_dir()) { @@ -1886,6 +1892,7 @@ void tr_torrent::recheck_completeness() session->onTorrentCompletenessChanged(this, completeness_, was_running); set_dirty(); + mark_changed(); if (is_done()) { @@ -2314,8 +2321,8 @@ void tr_torrent::set_download_dir(std::string_view path, bool is_new_torrent) else { completion_.set_has_all(); - date_done_ = date_added_; recheck_completeness(); + date_done_ = date_added_; // Must be after recheck_completeness() } } else if (error_.error_type() == TR_STAT_LOCAL_ERROR && !set_local_error_if_files_disappeared(this)) diff --git a/libtransmission/torrent.h b/libtransmission/torrent.h index d6e50fe1b..8aa51207a 100644 --- a/libtransmission/torrent.h +++ b/libtransmission/torrent.h @@ -1095,7 +1095,7 @@ private: { n_secs += date_done_ - date_started_; } - else if (date_done_ == 0) + else if (date_done_ == time_t{}) { n_secs += now - date_started_; } @@ -1114,7 +1114,7 @@ private: { n_secs += now - date_done_; } - else if (date_done_ != 0) + else if (date_done_ != time_t{}) { n_secs += now - date_started_; }