Allow to set torrent stop condition

PR #17814.

Closes #17792.
Closes #929.

(Actually it should close all issues about lack of ability to stop torrent after metadata downloaded or after files are initially checked.)

Also makes explicit the temporary start of the torrent in the case when recheck of the stopped torrent is performed.
This commit is contained in:
Vladimir Golovnev
2022-10-09 16:07:16 +03:00
committed by GitHub
parent ce7d8dee28
commit 67357e9964
19 changed files with 295 additions and 87 deletions

View File

@@ -295,6 +295,8 @@ TorrentImpl::TorrentImpl(SessionImpl *session, lt::session *nativeSession
}
}
setStopCondition(params.stopCondition);
const auto *extensionData = static_cast<ExtensionData *>(m_ltAddTorrentParams.userdata);
m_trackerEntries.reserve(static_cast<decltype(m_trackerEntries)::size_type>(extensionData->trackers.size()));
for (const lt::announce_entry &announceEntry : extensionData->trackers)
@@ -993,9 +995,7 @@ void TorrentImpl::updateState()
else
m_state = isForced() ? TorrentState::ForcedDownloadingMetadata : TorrentState::DownloadingMetadata;
}
else if ((m_nativeStatus.state == lt::torrent_status::checking_files)
&& (!isPaused() || (m_nativeStatus.flags & lt::torrent_flags::auto_managed)
|| !(m_nativeStatus.flags & lt::torrent_flags::paused)))
else if ((m_nativeStatus.state == lt::torrent_status::checking_files) && !isPaused())
{
// If the torrent is not just in the "checking" state, but is being actually checked
m_state = m_hasSeedStatus ? TorrentState::CheckingUploading : TorrentState::CheckingDownloading;
@@ -1423,8 +1423,8 @@ void TorrentImpl::forceRecheck()
if (isPaused())
{
// When "force recheck" is applied on paused torrent, we temporarily resume it
// (really we just allow libtorrent to resume it by enabling auto management for it).
m_nativeHandle.set_flags(lt::torrent_flags::stop_when_ready | lt::torrent_flags::auto_managed);
resume();
setStopCondition(StopCondition::FilesChecked);
}
}
@@ -1581,6 +1581,17 @@ void TorrentImpl::endReceivedMetadataHandling(const Path &savePath, const PathLi
p.save_path = savePath.toString().toStdString();
p.ti = metadata;
if (stopCondition() == StopCondition::MetadataReceived)
{
m_stopCondition = StopCondition::None;
m_isStopped = true;
p.flags |= lt::torrent_flags::paused;
p.flags &= ~lt::torrent_flags::auto_managed;
m_session->handleTorrentPaused(this);
}
reload();
// If first/last piece priority was specified when adding this torrent,
@@ -1639,6 +1650,7 @@ void TorrentImpl::pause()
{
if (!m_isStopped)
{
m_stopCondition = StopCondition::None;
m_isStopped = true;
m_session->handleTorrentNeedSaveResumeData(this);
m_session->handleTorrentPaused(this);
@@ -1674,10 +1686,6 @@ void TorrentImpl::resume(const TorrentOperatingMode mode)
if (m_isStopped)
{
// Torrent may have been temporarily resumed to perform checking files
// so we have to ensure it will not pause after checking is done.
m_nativeHandle.unset_flags(lt::torrent_flags::stop_when_ready);
m_isStopped = false;
m_session->handleTorrentNeedSaveResumeData(this);
m_session->handleTorrentResumed(this);
@@ -1756,13 +1764,13 @@ void TorrentImpl::handleTorrentCheckedAlert(const lt::torrent_checked_alert *p)
return;
}
if (stopCondition() == StopCondition::FilesChecked)
pause();
m_statusUpdatedTriggers.enqueue([this]()
{
qDebug("\"%s\" have just finished checking.", qUtf8Printable(name()));
if (m_nativeStatus.need_save_resume)
m_session->handleTorrentNeedSaveResumeData(this);
if (!m_hasMissingFiles)
{
if ((progress() < 1.0) && (wantedSize() > 0))
@@ -1772,8 +1780,20 @@ void TorrentImpl::handleTorrentCheckedAlert(const lt::torrent_checked_alert *p)
adjustStorageLocation();
manageIncompleteFiles();
if (!isPaused())
{
// torrent is internally paused using NativeTorrentExtension after files checked
// so we need to resume it if there is no corresponding "stop condition" set
setAutoManaged(m_operatingMode == TorrentOperatingMode::AutoManaged);
if (m_operatingMode == TorrentOperatingMode::Forced)
m_nativeHandle.resume();
}
}
if (m_nativeStatus.need_save_resume)
m_session->handleTorrentNeedSaveResumeData(this);
m_session->handleTorrentChecked(this);
});
}
@@ -1909,6 +1929,7 @@ void TorrentImpl::prepareResumeData(const lt::add_torrent_params &params)
resumeData.firstLastPiecePriority = m_hasFirstLastPiecePriority;
resumeData.hasSeedStatus = m_hasSeedStatus;
resumeData.stopped = m_isStopped;
resumeData.stopCondition = m_stopCondition;
resumeData.operatingMode = m_operatingMode;
resumeData.ltAddTorrentParams = m_ltAddTorrentParams;
resumeData.useAutoTMM = m_useAutoTMM;
@@ -2166,6 +2187,28 @@ bool TorrentImpl::setMetadata(const TorrentInfo &torrentInfo)
#endif
}
Torrent::StopCondition TorrentImpl::stopCondition() const
{
return m_stopCondition;
}
void TorrentImpl::setStopCondition(const StopCondition stopCondition)
{
if (stopCondition == m_stopCondition)
return;
if (isPaused())
return;
if ((stopCondition == StopCondition::MetadataReceived) && hasMetadata())
return;
if ((stopCondition == StopCondition::FilesChecked) && hasMetadata() && !isChecking())
return;
m_stopCondition = stopCondition;
}
bool TorrentImpl::isMoveInProgress() const
{
return m_storageIsMoving;