From 71af105a897e3632e2e02fd6bfd85e30df3f7f81 Mon Sep 17 00:00:00 2001 From: Vladimir Golovnev Date: Mon, 23 Jun 2025 12:20:01 +0300 Subject: [PATCH] Avoid copying resume data when loading torrents PR #22899. --- src/base/bittorrent/resumedatastorage.cpp | 4 ++-- src/base/bittorrent/resumedatastorage.h | 2 +- src/base/bittorrent/sessionimpl.cpp | 29 ++++++++++------------- src/base/bittorrent/sessionimpl.h | 5 ++-- src/base/bittorrent/torrentimpl.cpp | 4 ++-- src/base/bittorrent/torrentimpl.h | 2 +- 6 files changed, 21 insertions(+), 25 deletions(-) diff --git a/src/base/bittorrent/resumedatastorage.cpp b/src/base/bittorrent/resumedatastorage.cpp index f21d3c832..e74ec1123 100644 --- a/src/base/bittorrent/resumedatastorage.cpp +++ b/src/base/bittorrent/resumedatastorage.cpp @@ -71,8 +71,8 @@ QList BitTorrent::ResumeDataStorage::fetchLoadedRe return loadedResumeData; } -void BitTorrent::ResumeDataStorage::onResumeDataLoaded(const TorrentID &torrentID, const LoadResumeDataResult &loadResumeDataResult) const +void BitTorrent::ResumeDataStorage::onResumeDataLoaded(const TorrentID &torrentID, LoadResumeDataResult loadResumeDataResult) const { const QMutexLocker locker {&m_loadedResumeDataMutex}; - m_loadedResumeData.append({torrentID, loadResumeDataResult}); + m_loadedResumeData.append({.torrentID = torrentID, .result = std::move(loadResumeDataResult)}); } diff --git a/src/base/bittorrent/resumedatastorage.h b/src/base/bittorrent/resumedatastorage.h index 187a3eb37..17f857602 100644 --- a/src/base/bittorrent/resumedatastorage.h +++ b/src/base/bittorrent/resumedatastorage.h @@ -72,7 +72,7 @@ namespace BitTorrent void loadFinished(); protected: - void onResumeDataLoaded(const TorrentID &torrentID, const LoadResumeDataResult &loadResumeDataResult) const; + void onResumeDataLoaded(const TorrentID &torrentID, LoadResumeDataResult loadResumeDataResult) const; private: virtual void doLoadAll() const = 0; diff --git a/src/base/bittorrent/sessionimpl.cpp b/src/base/bittorrent/sessionimpl.cpp index 9c0ae9eb4..3bdd9ff13 100644 --- a/src/base/bittorrent/sessionimpl.cpp +++ b/src/base/bittorrent/sessionimpl.cpp @@ -1463,15 +1463,13 @@ void SessionImpl::handleLoadedResumeData(ResumeSessionContext *context) void SessionImpl::processNextResumeData(ResumeSessionContext *context) { - const LoadedResumeData loadedResumeDataItem = context->loadedResumeData.takeFirst(); + auto [torrentID, loadResumeDataResult] = context->loadedResumeData.takeFirst(); - TorrentID torrentID = loadedResumeDataItem.torrentID; #ifdef QBT_USES_LIBTORRENT2 if (context->skippedIDs.contains(torrentID)) return; #endif - const nonstd::expected &loadResumeDataResult = loadedResumeDataItem.result; if (!loadResumeDataResult) { LogMsg(tr("Failed to resume torrent. Torrent: \"%1\". Reason: \"%2\"") @@ -1479,7 +1477,7 @@ void SessionImpl::processNextResumeData(ResumeSessionContext *context) return; } - LoadTorrentParams resumeData = *loadResumeDataResult; + LoadTorrentParams resumeData = std::move(*loadResumeDataResult); bool needStore = false; const InfoHash infoHash = getInfoHash(resumeData.ltAddTorrentParams); @@ -1514,11 +1512,10 @@ void SessionImpl::processNextResumeData(ResumeSessionContext *context) { context->skippedIDs.insert(torrentID); - const nonstd::expected loadPreferredResumeDataResult = context->startupStorage->load(torrentID); - if (loadPreferredResumeDataResult) + if (nonstd::expected loadPreferredResumeDataResult = context->startupStorage->load(torrentID)) { std::shared_ptr ti = resumeData.ltAddTorrentParams.ti; - resumeData = *loadPreferredResumeDataResult; + resumeData = std::move(*loadPreferredResumeDataResult); if (!resumeData.ltAddTorrentParams.ti) resumeData.ltAddTorrentParams.ti = std::move(ti); } @@ -1621,7 +1618,7 @@ void SessionImpl::processNextResumeData(ResumeSessionContext *context) qDebug() << "Starting up torrent" << torrentID.toString() << "..."; m_nativeSession->async_add_torrent(resumeData.ltAddTorrentParams); - m_addTorrentAlertHandlers.enqueue([this, resumeData = std::move(resumeData)](const lt::add_torrent_alert *alert) + m_addTorrentAlertHandlers.append([this, resumeData = std::move(resumeData)](const lt::add_torrent_alert *alert) mutable { if (alert->error) { @@ -1630,7 +1627,7 @@ void SessionImpl::processNextResumeData(ResumeSessionContext *context) } else { - Torrent *torrent = createTorrent(alert->handle, resumeData); + Torrent *torrent = createTorrent(alert->handle, std::move(resumeData)); m_loadedTorrents.append(torrent); LogMsg(tr("Restored torrent. Torrent: \"%1\"").arg(torrent->name())); @@ -3016,7 +3013,7 @@ bool SessionImpl::addTorrent_impl(const TorrentDescriptor &source, const AddTorr } m_nativeSession->async_add_torrent(p); - m_addTorrentAlertHandlers.enqueue([this, loadTorrentParams = std::move(loadTorrentParams)](const lt::add_torrent_alert *alert) + m_addTorrentAlertHandlers.append([this, loadTorrentParams = std::move(loadTorrentParams)](const lt::add_torrent_alert *alert) mutable { if (alert->error) { @@ -3033,7 +3030,7 @@ bool SessionImpl::addTorrent_impl(const TorrentDescriptor &source, const AddTorr if (loadTorrentParams.addToQueueTop) alert->handle.queue_position_top(); - TorrentImpl *torrent = createTorrent(alert->handle, loadTorrentParams); + TorrentImpl *torrent = createTorrent(alert->handle, std::move(loadTorrentParams)); m_loadedTorrents.append(torrent); torrent->requestResumeData(lt::torrent_handle::save_info_dict); @@ -3203,7 +3200,7 @@ bool SessionImpl::downloadMetadata(const TorrentDescriptor &torrentDescr) // Adding torrent to libtorrent session m_nativeSession->async_add_torrent(p); m_downloadedMetadata.insert(id, {}); - m_addTorrentAlertHandlers.enqueue([this](const lt::add_torrent_alert *alert) + m_addTorrentAlertHandlers.append([this](const lt::add_torrent_alert *alert) { if (alert->error) { @@ -5501,7 +5498,7 @@ lt::torrent_handle SessionImpl::reloadTorrent(const lt::torrent_handle ¤tH #endif // libtorrent will post an add_torrent_alert anyway, so we have to add an empty handler to ignore it. - m_addTorrentAlertHandlers.enqueue({}); + m_addTorrentAlertHandlers.emplaceBack(); return m_nativeSession->add_torrent(std::move(params)); } @@ -5833,7 +5830,7 @@ void SessionImpl::handleAddTorrentAlert(const lt::add_torrent_alert *alert) if (m_addTorrentAlertHandlers.isEmpty()) [[unlikely]] return; - if (const AddTorrentAlertHandler handleAlert = m_addTorrentAlertHandlers.dequeue()) + if (const AddTorrentAlertHandler handleAlert = m_addTorrentAlertHandlers.takeFirst()) handleAlert(alert); } @@ -5963,9 +5960,9 @@ void SessionImpl::handleAlert(lt::alert *alert) } } -TorrentImpl *SessionImpl::createTorrent(const lt::torrent_handle &nativeHandle, const LoadTorrentParams ¶ms) +TorrentImpl *SessionImpl::createTorrent(const lt::torrent_handle &nativeHandle, LoadTorrentParams params) { - auto *const torrent = new TorrentImpl(this, nativeHandle, params); + auto *const torrent = new TorrentImpl(this, nativeHandle, std::move(params)); m_torrents.insert(torrent->id(), torrent); if (const InfoHash infoHash = torrent->infoHash(); infoHash.isHybrid()) m_hybridTorrentsByAltID.insert(TorrentID::fromSHA1Hash(infoHash.v1()), torrent); diff --git a/src/base/bittorrent/sessionimpl.h b/src/base/bittorrent/sessionimpl.h index d47e61dec..e923f8a13 100644 --- a/src/base/bittorrent/sessionimpl.h +++ b/src/base/bittorrent/sessionimpl.h @@ -45,7 +45,6 @@ #include #include #include -#include #include #include @@ -618,7 +617,7 @@ namespace BitTorrent void handleTorrentCheckedAlert(const lt::torrent_checked_alert *alert); void handleTorrentFinishedAlert(const lt::torrent_finished_alert *alert); - TorrentImpl *createTorrent(const lt::torrent_handle &nativeHandle, const LoadTorrentParams ¶ms); + TorrentImpl *createTorrent(const lt::torrent_handle &nativeHandle, LoadTorrentParams params); TorrentImpl *getTorrent(const lt::torrent_handle &nativeHandle) const; void saveResumeData(); @@ -827,7 +826,7 @@ namespace BitTorrent TorrentContentRemover *m_torrentContentRemover = nullptr; using AddTorrentAlertHandler = std::function; - QQueue m_addTorrentAlertHandlers; + QList m_addTorrentAlertHandlers; QHash m_downloadedMetadata; diff --git a/src/base/bittorrent/torrentimpl.cpp b/src/base/bittorrent/torrentimpl.cpp index e89c59a67..c3a7c0f2b 100644 --- a/src/base/bittorrent/torrentimpl.cpp +++ b/src/base/bittorrent/torrentimpl.cpp @@ -299,7 +299,7 @@ namespace // TorrentImpl -TorrentImpl::TorrentImpl(SessionImpl *session, const lt::torrent_handle &nativeHandle, const LoadTorrentParams ¶ms) +TorrentImpl::TorrentImpl(SessionImpl *session, const lt::torrent_handle &nativeHandle, LoadTorrentParams params) : Torrent(session) , m_session(session) , m_nativeHandle(nativeHandle) @@ -324,7 +324,7 @@ TorrentImpl::TorrentImpl(SessionImpl *session, const lt::torrent_handle &nativeH , m_useAutoTMM(params.useAutoTMM) , m_isStopped(params.stopped) , m_sslParams(params.sslParameters) - , m_ltAddTorrentParams(params.ltAddTorrentParams) + , m_ltAddTorrentParams(std::move(params.ltAddTorrentParams)) , m_downloadLimit(cleanLimitValue(m_ltAddTorrentParams.download_limit)) , m_uploadLimit(cleanLimitValue(m_ltAddTorrentParams.upload_limit)) { diff --git a/src/base/bittorrent/torrentimpl.h b/src/base/bittorrent/torrentimpl.h index 7b7064fd0..2c1f9af77 100644 --- a/src/base/bittorrent/torrentimpl.h +++ b/src/base/bittorrent/torrentimpl.h @@ -94,7 +94,7 @@ namespace BitTorrent Q_DISABLE_COPY_MOVE(TorrentImpl) public: - TorrentImpl(SessionImpl *session, const lt::torrent_handle &nativeHandle, const LoadTorrentParams ¶ms); + TorrentImpl(SessionImpl *session, const lt::torrent_handle &nativeHandle, LoadTorrentParams params); ~TorrentImpl() override; bool isValid() const;