mirror of
https://github.com/qbittorrent/qBittorrent.git
synced 2025-01-06 15:04:34 +08:00
Merge pull request #9580 from glassez/start_paused
Improve handling of torrent startup/recheck
This commit is contained in:
commit
46ec72f688
@ -2194,15 +2194,6 @@ bool Session::addTorrent_impl(CreateTorrentParams params, const MagnetUri &magne
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (params.restored && !fromMagnetUri) {
|
|
||||||
// Set torrent fast resume data
|
|
||||||
p.resume_data = {fastresumeData.constData(), fastresumeData.constData() + fastresumeData.size()};
|
|
||||||
p.flags |= libt::add_torrent_params::flag_use_resume_save_path;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
p.file_priorities = {params.filePriorities.begin(), params.filePriorities.end()};
|
|
||||||
}
|
|
||||||
|
|
||||||
// We should not add torrent if it already
|
// We should not add torrent if it already
|
||||||
// processed or adding to session
|
// processed or adding to session
|
||||||
if (m_addingTorrents.contains(hash) || m_loadedMetadata.contains(hash)) return false;
|
if (m_addingTorrents.contains(hash) || m_loadedMetadata.contains(hash)) return false;
|
||||||
@ -2236,6 +2227,23 @@ bool Session::addTorrent_impl(CreateTorrentParams params, const MagnetUri &magne
|
|||||||
else
|
else
|
||||||
p.flags &= ~libt::add_torrent_params::flag_seed_mode;
|
p.flags &= ~libt::add_torrent_params::flag_seed_mode;
|
||||||
|
|
||||||
|
if (!fromMagnetUri) {
|
||||||
|
if (params.restored) {
|
||||||
|
// Set torrent fast resume data
|
||||||
|
p.resume_data = {fastresumeData.constData(), fastresumeData.constData() + fastresumeData.size()};
|
||||||
|
p.flags |= libt::add_torrent_params::flag_use_resume_save_path;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
p.file_priorities = {params.filePriorities.begin(), params.filePriorities.end()};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (params.restored && !params.paused) {
|
||||||
|
// Make sure the torrent will restored in "paused" state
|
||||||
|
// Then we will start it if needed
|
||||||
|
p.flags |= libt::add_torrent_params::flag_stop_when_ready;
|
||||||
|
}
|
||||||
|
|
||||||
// Limits
|
// Limits
|
||||||
p.max_connections = maxConnectionsPerTorrent();
|
p.max_connections = maxConnectionsPerTorrent();
|
||||||
p.max_uploads = maxUploadsPerTorrent();
|
p.max_uploads = maxUploadsPerTorrent();
|
||||||
@ -4565,8 +4573,10 @@ namespace
|
|||||||
torrentParams.hasRootFolder = fast.dict_find_int_value("qBt-hasRootFolder");
|
torrentParams.hasRootFolder = fast.dict_find_int_value("qBt-hasRootFolder");
|
||||||
|
|
||||||
magnetUri = MagnetUri(QString::fromStdString(fast.dict_find_string_value("qBt-magnetUri")));
|
magnetUri = MagnetUri(QString::fromStdString(fast.dict_find_string_value("qBt-magnetUri")));
|
||||||
torrentParams.paused = fast.dict_find_int_value("qBt-paused");
|
const bool isAutoManaged = fast.dict_find_int_value("auto_managed");
|
||||||
torrentParams.forced = fast.dict_find_int_value("qBt-forced");
|
const bool isPaused = fast.dict_find_int_value("paused");
|
||||||
|
torrentParams.paused = fast.dict_find_int_value("qBt-paused", (isPaused && !isAutoManaged));
|
||||||
|
torrentParams.forced = fast.dict_find_int_value("qBt-forced", (!isPaused && !isAutoManaged));
|
||||||
torrentParams.firstLastPiecePriority = fast.dict_find_int_value("qBt-firstLastPiecePriority");
|
torrentParams.firstLastPiecePriority = fast.dict_find_int_value("qBt-firstLastPiecePriority");
|
||||||
torrentParams.sequential = fast.dict_find_int_value("qBt-sequential");
|
torrentParams.sequential = fast.dict_find_int_value("qBt-sequential");
|
||||||
|
|
||||||
|
@ -190,7 +190,7 @@ TorrentHandle::TorrentHandle(Session *session, const libtorrent::torrent_handle
|
|||||||
, m_hasMissingFiles(false)
|
, m_hasMissingFiles(false)
|
||||||
, m_hasRootFolder(params.hasRootFolder)
|
, m_hasRootFolder(params.hasRootFolder)
|
||||||
, m_needsToSetFirstLastPiecePriority(false)
|
, m_needsToSetFirstLastPiecePriority(false)
|
||||||
, m_pauseAfterRecheck(false)
|
, m_needsToStartForced(params.forced)
|
||||||
{
|
{
|
||||||
if (m_useAutoTMM)
|
if (m_useAutoTMM)
|
||||||
m_savePath = Utils::Fs::toNativePath(m_session->categorySavePath(m_category));
|
m_savePath = Utils::Fs::toNativePath(m_session->categorySavePath(m_category));
|
||||||
@ -220,14 +220,14 @@ TorrentHandle::TorrentHandle(Session *session, const libtorrent::torrent_handle
|
|||||||
// When torrent added/restored in "paused" state it become "started" immediately after construction.
|
// When torrent added/restored in "paused" state it become "started" immediately after construction.
|
||||||
// When it is added/restored in "resumed" state, it become "started" after it is really resumed
|
// When it is added/restored in "resumed" state, it become "started" after it is really resumed
|
||||||
// (i.e. after receiving "torrent resumed" alert).
|
// (i.e. after receiving "torrent resumed" alert).
|
||||||
m_started = (params.restored && hasMetadata() ? isPaused() : params.paused);
|
if (params.paused) {
|
||||||
|
m_startupState = Started;
|
||||||
if (!m_started) {
|
}
|
||||||
if (!params.restored || !hasMetadata()) {
|
else if (!params.restored) {
|
||||||
// Resume torrent because it was added in "resumed" state
|
// Resume torrent because it was added in "resumed" state
|
||||||
// but it's actually paused during initialization
|
// but it's actually paused during initialization
|
||||||
resume(params.forced);
|
m_startupState = Starting;
|
||||||
}
|
resume(params.forced);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1274,11 +1274,9 @@ void TorrentHandle::forceRecheck()
|
|||||||
m_unchecked = false;
|
m_unchecked = false;
|
||||||
|
|
||||||
if (isPaused()) {
|
if (isPaused()) {
|
||||||
m_pauseAfterRecheck = true;
|
m_nativeHandle.stop_when_ready(true);
|
||||||
resume_impl(true, true);
|
resume_impl(true, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_nativeHandle.force_recheck();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TorrentHandle::setSequentialDownload(bool b)
|
void TorrentHandle::setSequentialDownload(bool b)
|
||||||
@ -1363,7 +1361,12 @@ void TorrentHandle::resume_impl(bool forced, bool uploadMode)
|
|||||||
{
|
{
|
||||||
if (hasError())
|
if (hasError())
|
||||||
m_nativeHandle.clear_error();
|
m_nativeHandle.clear_error();
|
||||||
m_hasMissingFiles = false;
|
|
||||||
|
if (m_hasMissingFiles) {
|
||||||
|
m_hasMissingFiles = false;
|
||||||
|
m_nativeHandle.force_recheck();
|
||||||
|
}
|
||||||
|
|
||||||
m_nativeHandle.auto_managed(!forced);
|
m_nativeHandle.auto_managed(!forced);
|
||||||
m_nativeHandle.set_upload_mode(uploadMode);
|
m_nativeHandle.set_upload_mode(uploadMode);
|
||||||
m_nativeHandle.resume();
|
m_nativeHandle.resume();
|
||||||
@ -1555,21 +1558,32 @@ void TorrentHandle::handleTrackerErrorAlert(const libtorrent::tracker_error_aler
|
|||||||
void TorrentHandle::handleTorrentCheckedAlert(const libtorrent::torrent_checked_alert *p)
|
void TorrentHandle::handleTorrentCheckedAlert(const libtorrent::torrent_checked_alert *p)
|
||||||
{
|
{
|
||||||
Q_UNUSED(p);
|
Q_UNUSED(p);
|
||||||
qDebug("%s have just finished checking", qUtf8Printable(hash()));
|
qDebug("\"%s\" have just finished checking", qUtf8Printable(name()));
|
||||||
|
|
||||||
|
if (m_startupState == NotStarted) {
|
||||||
|
if (!m_hasMissingFiles) {
|
||||||
|
// Resume torrent because it was added in "resumed" state
|
||||||
|
// but it's actually paused during initialization.
|
||||||
|
m_startupState = Starting;
|
||||||
|
resume(m_needsToStartForced);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Torrent that has missing files is marked as "started"
|
||||||
|
// but it remains paused.
|
||||||
|
m_startupState = Started;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
updateStatus();
|
updateStatus();
|
||||||
|
|
||||||
if ((progress() < 1.0) && (wantedSize() > 0))
|
if (!m_hasMissingFiles) {
|
||||||
m_hasSeedStatus = false;
|
if ((progress() < 1.0) && (wantedSize() > 0))
|
||||||
else if (progress() == 1.0)
|
m_hasSeedStatus = false;
|
||||||
m_hasSeedStatus = true;
|
else if (progress() == 1.0)
|
||||||
|
m_hasSeedStatus = true;
|
||||||
|
|
||||||
adjustActualSavePath();
|
adjustActualSavePath();
|
||||||
manageIncompleteFiles();
|
manageIncompleteFiles();
|
||||||
|
|
||||||
if (m_pauseAfterRecheck) {
|
|
||||||
m_pauseAfterRecheck = false;
|
|
||||||
pause();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
m_session->handleTorrentChecked(this);
|
m_session->handleTorrentChecked(this);
|
||||||
@ -1578,7 +1592,7 @@ void TorrentHandle::handleTorrentCheckedAlert(const libtorrent::torrent_checked_
|
|||||||
void TorrentHandle::handleTorrentFinishedAlert(const libtorrent::torrent_finished_alert *p)
|
void TorrentHandle::handleTorrentFinishedAlert(const libtorrent::torrent_finished_alert *p)
|
||||||
{
|
{
|
||||||
Q_UNUSED(p);
|
Q_UNUSED(p);
|
||||||
qDebug("Got a torrent finished alert for %s", qUtf8Printable(name()));
|
qDebug("Got a torrent finished alert for \"%s\"", qUtf8Printable(name()));
|
||||||
qDebug("Torrent has seed status: %s", m_hasSeedStatus ? "yes" : "no");
|
qDebug("Torrent has seed status: %s", m_hasSeedStatus ? "yes" : "no");
|
||||||
if (m_hasSeedStatus) return;
|
if (m_hasSeedStatus) return;
|
||||||
|
|
||||||
@ -1605,19 +1619,22 @@ void TorrentHandle::handleTorrentFinishedAlert(const libtorrent::torrent_finishe
|
|||||||
void TorrentHandle::handleTorrentPausedAlert(const libtorrent::torrent_paused_alert *p)
|
void TorrentHandle::handleTorrentPausedAlert(const libtorrent::torrent_paused_alert *p)
|
||||||
{
|
{
|
||||||
Q_UNUSED(p);
|
Q_UNUSED(p);
|
||||||
updateStatus();
|
|
||||||
m_speedMonitor.reset();
|
if (m_startupState == Started) {
|
||||||
m_session->handleTorrentPaused(this);
|
updateStatus();
|
||||||
|
m_speedMonitor.reset();
|
||||||
|
m_session->handleTorrentPaused(this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TorrentHandle::handleTorrentResumedAlert(const libtorrent::torrent_resumed_alert *p)
|
void TorrentHandle::handleTorrentResumedAlert(const libtorrent::torrent_resumed_alert *p)
|
||||||
{
|
{
|
||||||
Q_UNUSED(p);
|
Q_UNUSED(p);
|
||||||
|
|
||||||
if (m_started)
|
if (m_startupState == Started)
|
||||||
m_session->handleTorrentResumed(this);
|
m_session->handleTorrentResumed(this);
|
||||||
else
|
else if (m_startupState == Starting)
|
||||||
m_started = true;
|
m_startupState = Started;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TorrentHandle::handleSaveResumeDataAlert(const libtorrent::save_resume_data_alert *p)
|
void TorrentHandle::handleSaveResumeDataAlert(const libtorrent::save_resume_data_alert *p)
|
||||||
@ -1668,7 +1685,6 @@ void TorrentHandle::handleFastResumeRejectedAlert(const libtorrent::fastresume_r
|
|||||||
{
|
{
|
||||||
if (p->error.value() == libt::errors::mismatching_file_size) {
|
if (p->error.value() == libt::errors::mismatching_file_size) {
|
||||||
// Mismatching file size (files were probably moved)
|
// Mismatching file size (files were probably moved)
|
||||||
pause();
|
|
||||||
m_hasMissingFiles = true;
|
m_hasMissingFiles = true;
|
||||||
LogMsg(tr("File sizes mismatch for torrent '%1', pausing it.").arg(name()), Log::CRITICAL);
|
LogMsg(tr("File sizes mismatch for torrent '%1', pausing it.").arg(name()), Log::CRITICAL);
|
||||||
}
|
}
|
||||||
@ -1703,7 +1719,9 @@ void TorrentHandle::handleFileRenamedAlert(const libtorrent::file_renamed_alert
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
updateStatus();
|
// We don't really need to call updateStatus() in this place.
|
||||||
|
// All we need to do is make sure we have a valid instance of the TorrentInfo object.
|
||||||
|
m_torrentInfo = TorrentInfo {m_nativeHandle.torrent_file()};
|
||||||
|
|
||||||
--m_renameCount;
|
--m_renameCount;
|
||||||
while (!isMoveInProgress() && (m_renameCount == 0) && !m_moveFinishedTriggers.isEmpty())
|
while (!isMoveInProgress() && (m_renameCount == 0) && !m_moveFinishedTriggers.isEmpty())
|
||||||
@ -1721,7 +1739,9 @@ void TorrentHandle::handleFileRenameFailedAlert(const libtorrent::file_rename_fa
|
|||||||
|
|
||||||
void TorrentHandle::handleFileCompletedAlert(const libtorrent::file_completed_alert *p)
|
void TorrentHandle::handleFileCompletedAlert(const libtorrent::file_completed_alert *p)
|
||||||
{
|
{
|
||||||
updateStatus();
|
// We don't really need to call updateStatus() in this place.
|
||||||
|
// All we need to do is make sure we have a valid instance of the TorrentInfo object.
|
||||||
|
m_torrentInfo = TorrentInfo {m_nativeHandle.torrent_file()};
|
||||||
|
|
||||||
qDebug("A file completed download in torrent \"%s\"", qUtf8Printable(name()));
|
qDebug("A file completed download in torrent \"%s\"", qUtf8Printable(name()));
|
||||||
if (m_session->isAppendExtensionEnabled()) {
|
if (m_session->isAppendExtensionEnabled()) {
|
||||||
@ -1984,8 +2004,6 @@ void TorrentHandle::setDownloadLimit(int limit)
|
|||||||
void TorrentHandle::setSuperSeeding(bool enable)
|
void TorrentHandle::setSuperSeeding(bool enable)
|
||||||
{
|
{
|
||||||
m_nativeHandle.super_seeding(enable);
|
m_nativeHandle.super_seeding(enable);
|
||||||
if (superSeeding() != enable)
|
|
||||||
updateStatus();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TorrentHandle::flushCache()
|
void TorrentHandle::flushCache()
|
||||||
@ -2078,8 +2096,6 @@ void TorrentHandle::prioritizeFiles(const QVector<int> &priorities)
|
|||||||
// Restore first/last piece first option if necessary
|
// Restore first/last piece first option if necessary
|
||||||
if (firstLastPieceFirst)
|
if (firstLastPieceFirst)
|
||||||
setFirstLastPiecePriorityImpl(true, priorities);
|
setFirstLastPiecePriorityImpl(true, priorities);
|
||||||
|
|
||||||
updateStatus();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QVector<qreal> TorrentHandle::availableFileFractions() const
|
QVector<qreal> TorrentHandle::availableFileFractions() const
|
||||||
|
@ -461,11 +461,18 @@ namespace BitTorrent
|
|||||||
bool m_hasMissingFiles;
|
bool m_hasMissingFiles;
|
||||||
bool m_hasRootFolder;
|
bool m_hasRootFolder;
|
||||||
bool m_needsToSetFirstLastPiecePriority;
|
bool m_needsToSetFirstLastPiecePriority;
|
||||||
|
bool m_needsToStartForced;
|
||||||
|
|
||||||
bool m_pauseAfterRecheck;
|
|
||||||
QHash<QString, TrackerInfo> m_trackerInfos;
|
QHash<QString, TrackerInfo> m_trackerInfos;
|
||||||
|
|
||||||
bool m_started = false;
|
enum StartupState
|
||||||
|
{
|
||||||
|
NotStarted,
|
||||||
|
Starting,
|
||||||
|
Started
|
||||||
|
};
|
||||||
|
|
||||||
|
StartupState m_startupState = NotStarted;
|
||||||
bool m_unchecked = false;
|
bool m_unchecked = false;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user