From 8e941a06f15a0a8c12f37439cb2815fec73797c3 Mon Sep 17 00:00:00 2001 From: Vladimir Golovnev Date: Mon, 14 Oct 2024 11:51:30 +0300 Subject: [PATCH] Correctly handle "torrent finished after move" event PR #21596. Closes #21576. --- src/base/bittorrent/sessionimpl.cpp | 52 +++++++++++++++++------------ src/base/bittorrent/sessionimpl.h | 1 + 2 files changed, 31 insertions(+), 22 deletions(-) diff --git a/src/base/bittorrent/sessionimpl.cpp b/src/base/bittorrent/sessionimpl.cpp index 17a2ce074..0981ea262 100644 --- a/src/base/bittorrent/sessionimpl.cpp +++ b/src/base/bittorrent/sessionimpl.cpp @@ -5221,6 +5221,9 @@ void SessionImpl::handleMoveTorrentStorageJobFinished(const Path &newPath) if (torrent) { torrent->handleMoveStorageJobFinished(newPath, finishedJob.context, torrentHasOutstandingJob); + // The torrent may become "finished" at the end of the move if it was moved + // from the "incomplete" location after downloading finished. + processPendingFinishedTorrents(); } else if (!torrentHasOutstandingJob) { @@ -5232,6 +5235,32 @@ void SessionImpl::handleMoveTorrentStorageJobFinished(const Path &newPath) } } +void SessionImpl::processPendingFinishedTorrents() +{ + if (m_pendingFinishedTorrents.isEmpty()) + return; + + for (TorrentImpl *torrent : asConst(m_pendingFinishedTorrents)) + { + LogMsg(tr("Torrent download finished. Torrent: \"%1\"").arg(torrent->name())); + emit torrentFinished(torrent); + + if (const Path exportPath = finishedTorrentExportDirectory(); !exportPath.isEmpty()) + exportTorrentFile(torrent, exportPath); + + processTorrentShareLimits(torrent); + } + + m_pendingFinishedTorrents.clear(); + + const bool hasUnfinishedTorrents = std::any_of(m_torrents.cbegin(), m_torrents.cend(), [](const TorrentImpl *torrent) + { + return !(torrent->isFinished() || torrent->isStopped() || torrent->isErrored()); + }); + if (!hasUnfinishedTorrents) + emit allTorrentsFinished(); +} + void SessionImpl::storeCategories() const { QJsonObject jsonObj; @@ -6129,28 +6158,7 @@ void SessionImpl::handleStateUpdateAlert(const lt::state_update_alert *alert) if (!updatedTorrents.isEmpty()) emit torrentsUpdated(updatedTorrents); - if (!m_pendingFinishedTorrents.isEmpty()) - { - for (TorrentImpl *torrent : m_pendingFinishedTorrents) - { - LogMsg(tr("Torrent download finished. Torrent: \"%1\"").arg(torrent->name())); - emit torrentFinished(torrent); - - if (const Path exportPath = finishedTorrentExportDirectory(); !exportPath.isEmpty()) - exportTorrentFile(torrent, exportPath); - - processTorrentShareLimits(torrent); - } - - m_pendingFinishedTorrents.clear(); - - const bool hasUnfinishedTorrents = std::any_of(m_torrents.cbegin(), m_torrents.cend(), [](const TorrentImpl *torrent) - { - return !(torrent->isFinished() || torrent->isStopped() || torrent->isErrored()); - }); - if (!hasUnfinishedTorrents) - emit allTorrentsFinished(); - } + processPendingFinishedTorrents(); if (m_needSaveTorrentsQueue) saveTorrentsQueue(); diff --git a/src/base/bittorrent/sessionimpl.h b/src/base/bittorrent/sessionimpl.h index 9fe3c7ab6..6899fedfc 100644 --- a/src/base/bittorrent/sessionimpl.h +++ b/src/base/bittorrent/sessionimpl.h @@ -598,6 +598,7 @@ namespace BitTorrent void moveTorrentStorage(const MoveStorageJob &job) const; void handleMoveTorrentStorageJobFinished(const Path &newPath); + void processPendingFinishedTorrents(); void loadCategories(); void storeCategories() const;