Avoid copying resume data when loading torrents

PR #22899.
This commit is contained in:
Vladimir Golovnev 2025-06-23 12:20:01 +03:00 committed by GitHub
parent f6ee6b92a4
commit 71af105a89
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 21 additions and 25 deletions

View file

@ -71,8 +71,8 @@ QList<BitTorrent::LoadedResumeData> BitTorrent::ResumeDataStorage::fetchLoadedRe
return loadedResumeData; 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}; const QMutexLocker locker {&m_loadedResumeDataMutex};
m_loadedResumeData.append({torrentID, loadResumeDataResult}); m_loadedResumeData.append({.torrentID = torrentID, .result = std::move(loadResumeDataResult)});
} }

View file

@ -72,7 +72,7 @@ namespace BitTorrent
void loadFinished(); void loadFinished();
protected: protected:
void onResumeDataLoaded(const TorrentID &torrentID, const LoadResumeDataResult &loadResumeDataResult) const; void onResumeDataLoaded(const TorrentID &torrentID, LoadResumeDataResult loadResumeDataResult) const;
private: private:
virtual void doLoadAll() const = 0; virtual void doLoadAll() const = 0;

View file

@ -1463,15 +1463,13 @@ void SessionImpl::handleLoadedResumeData(ResumeSessionContext *context)
void SessionImpl::processNextResumeData(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 #ifdef QBT_USES_LIBTORRENT2
if (context->skippedIDs.contains(torrentID)) if (context->skippedIDs.contains(torrentID))
return; return;
#endif #endif
const nonstd::expected<LoadTorrentParams, QString> &loadResumeDataResult = loadedResumeDataItem.result;
if (!loadResumeDataResult) if (!loadResumeDataResult)
{ {
LogMsg(tr("Failed to resume torrent. Torrent: \"%1\". Reason: \"%2\"") LogMsg(tr("Failed to resume torrent. Torrent: \"%1\". Reason: \"%2\"")
@ -1479,7 +1477,7 @@ void SessionImpl::processNextResumeData(ResumeSessionContext *context)
return; return;
} }
LoadTorrentParams resumeData = *loadResumeDataResult; LoadTorrentParams resumeData = std::move(*loadResumeDataResult);
bool needStore = false; bool needStore = false;
const InfoHash infoHash = getInfoHash(resumeData.ltAddTorrentParams); const InfoHash infoHash = getInfoHash(resumeData.ltAddTorrentParams);
@ -1514,11 +1512,10 @@ void SessionImpl::processNextResumeData(ResumeSessionContext *context)
{ {
context->skippedIDs.insert(torrentID); context->skippedIDs.insert(torrentID);
const nonstd::expected<LoadTorrentParams, QString> loadPreferredResumeDataResult = context->startupStorage->load(torrentID); if (nonstd::expected<LoadTorrentParams, QString> loadPreferredResumeDataResult = context->startupStorage->load(torrentID))
if (loadPreferredResumeDataResult)
{ {
std::shared_ptr<lt::torrent_info> ti = resumeData.ltAddTorrentParams.ti; std::shared_ptr<lt::torrent_info> ti = resumeData.ltAddTorrentParams.ti;
resumeData = *loadPreferredResumeDataResult; resumeData = std::move(*loadPreferredResumeDataResult);
if (!resumeData.ltAddTorrentParams.ti) if (!resumeData.ltAddTorrentParams.ti)
resumeData.ltAddTorrentParams.ti = std::move(ti); resumeData.ltAddTorrentParams.ti = std::move(ti);
} }
@ -1621,7 +1618,7 @@ void SessionImpl::processNextResumeData(ResumeSessionContext *context)
qDebug() << "Starting up torrent" << torrentID.toString() << "..."; qDebug() << "Starting up torrent" << torrentID.toString() << "...";
m_nativeSession->async_add_torrent(resumeData.ltAddTorrentParams); 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) if (alert->error)
{ {
@ -1630,7 +1627,7 @@ void SessionImpl::processNextResumeData(ResumeSessionContext *context)
} }
else else
{ {
Torrent *torrent = createTorrent(alert->handle, resumeData); Torrent *torrent = createTorrent(alert->handle, std::move(resumeData));
m_loadedTorrents.append(torrent); m_loadedTorrents.append(torrent);
LogMsg(tr("Restored torrent. Torrent: \"%1\"").arg(torrent->name())); 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_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) if (alert->error)
{ {
@ -3033,7 +3030,7 @@ bool SessionImpl::addTorrent_impl(const TorrentDescriptor &source, const AddTorr
if (loadTorrentParams.addToQueueTop) if (loadTorrentParams.addToQueueTop)
alert->handle.queue_position_top(); alert->handle.queue_position_top();
TorrentImpl *torrent = createTorrent(alert->handle, loadTorrentParams); TorrentImpl *torrent = createTorrent(alert->handle, std::move(loadTorrentParams));
m_loadedTorrents.append(torrent); m_loadedTorrents.append(torrent);
torrent->requestResumeData(lt::torrent_handle::save_info_dict); torrent->requestResumeData(lt::torrent_handle::save_info_dict);
@ -3203,7 +3200,7 @@ bool SessionImpl::downloadMetadata(const TorrentDescriptor &torrentDescr)
// Adding torrent to libtorrent session // Adding torrent to libtorrent session
m_nativeSession->async_add_torrent(p); m_nativeSession->async_add_torrent(p);
m_downloadedMetadata.insert(id, {}); 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) if (alert->error)
{ {
@ -5501,7 +5498,7 @@ lt::torrent_handle SessionImpl::reloadTorrent(const lt::torrent_handle &currentH
#endif #endif
// libtorrent will post an add_torrent_alert anyway, so we have to add an empty handler to ignore it. // 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)); 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]] if (m_addTorrentAlertHandlers.isEmpty()) [[unlikely]]
return; return;
if (const AddTorrentAlertHandler handleAlert = m_addTorrentAlertHandlers.dequeue()) if (const AddTorrentAlertHandler handleAlert = m_addTorrentAlertHandlers.takeFirst())
handleAlert(alert); handleAlert(alert);
} }
@ -5963,9 +5960,9 @@ void SessionImpl::handleAlert(lt::alert *alert)
} }
} }
TorrentImpl *SessionImpl::createTorrent(const lt::torrent_handle &nativeHandle, const LoadTorrentParams &params) 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); m_torrents.insert(torrent->id(), torrent);
if (const InfoHash infoHash = torrent->infoHash(); infoHash.isHybrid()) if (const InfoHash infoHash = torrent->infoHash(); infoHash.isHybrid())
m_hybridTorrentsByAltID.insert(TorrentID::fromSHA1Hash(infoHash.v1()), torrent); m_hybridTorrentsByAltID.insert(TorrentID::fromSHA1Hash(infoHash.v1()), torrent);

View file

@ -45,7 +45,6 @@
#include <QMap> #include <QMap>
#include <QMutex> #include <QMutex>
#include <QPointer> #include <QPointer>
#include <QQueue>
#include <QSet> #include <QSet>
#include <QThreadPool> #include <QThreadPool>
@ -618,7 +617,7 @@ namespace BitTorrent
void handleTorrentCheckedAlert(const lt::torrent_checked_alert *alert); void handleTorrentCheckedAlert(const lt::torrent_checked_alert *alert);
void handleTorrentFinishedAlert(const lt::torrent_finished_alert *alert); void handleTorrentFinishedAlert(const lt::torrent_finished_alert *alert);
TorrentImpl *createTorrent(const lt::torrent_handle &nativeHandle, const LoadTorrentParams &params); TorrentImpl *createTorrent(const lt::torrent_handle &nativeHandle, LoadTorrentParams params);
TorrentImpl *getTorrent(const lt::torrent_handle &nativeHandle) const; TorrentImpl *getTorrent(const lt::torrent_handle &nativeHandle) const;
void saveResumeData(); void saveResumeData();
@ -827,7 +826,7 @@ namespace BitTorrent
TorrentContentRemover *m_torrentContentRemover = nullptr; TorrentContentRemover *m_torrentContentRemover = nullptr;
using AddTorrentAlertHandler = std::function<void (const lt::add_torrent_alert *alert)>; using AddTorrentAlertHandler = std::function<void (const lt::add_torrent_alert *alert)>;
QQueue<AddTorrentAlertHandler> m_addTorrentAlertHandlers; QList<AddTorrentAlertHandler> m_addTorrentAlertHandlers;
QHash<TorrentID, lt::torrent_handle> m_downloadedMetadata; QHash<TorrentID, lt::torrent_handle> m_downloadedMetadata;

View file

@ -299,7 +299,7 @@ namespace
// TorrentImpl // TorrentImpl
TorrentImpl::TorrentImpl(SessionImpl *session, const lt::torrent_handle &nativeHandle, const LoadTorrentParams &params) TorrentImpl::TorrentImpl(SessionImpl *session, const lt::torrent_handle &nativeHandle, LoadTorrentParams params)
: Torrent(session) : Torrent(session)
, m_session(session) , m_session(session)
, m_nativeHandle(nativeHandle) , m_nativeHandle(nativeHandle)
@ -324,7 +324,7 @@ TorrentImpl::TorrentImpl(SessionImpl *session, const lt::torrent_handle &nativeH
, m_useAutoTMM(params.useAutoTMM) , m_useAutoTMM(params.useAutoTMM)
, m_isStopped(params.stopped) , m_isStopped(params.stopped)
, m_sslParams(params.sslParameters) , m_sslParams(params.sslParameters)
, m_ltAddTorrentParams(params.ltAddTorrentParams) , m_ltAddTorrentParams(std::move(params.ltAddTorrentParams))
, m_downloadLimit(cleanLimitValue(m_ltAddTorrentParams.download_limit)) , m_downloadLimit(cleanLimitValue(m_ltAddTorrentParams.download_limit))
, m_uploadLimit(cleanLimitValue(m_ltAddTorrentParams.upload_limit)) , m_uploadLimit(cleanLimitValue(m_ltAddTorrentParams.upload_limit))
{ {

View file

@ -94,7 +94,7 @@ namespace BitTorrent
Q_DISABLE_COPY_MOVE(TorrentImpl) Q_DISABLE_COPY_MOVE(TorrentImpl)
public: public:
TorrentImpl(SessionImpl *session, const lt::torrent_handle &nativeHandle, const LoadTorrentParams &params); TorrentImpl(SessionImpl *session, const lt::torrent_handle &nativeHandle, LoadTorrentParams params);
~TorrentImpl() override; ~TorrentImpl() override;
bool isValid() const; bool isValid() const;