mirror of
https://github.com/qbittorrent/qBittorrent
synced 2025-07-12 16:23:07 -07:00
Assign add_torrent_alert handler when adding torrent
This commit is contained in:
parent
582dc99cae
commit
9afbd47b52
3 changed files with 110 additions and 91 deletions
|
@ -493,7 +493,6 @@ namespace BitTorrent
|
||||||
void categoryOptionsChanged(const QString &categoryName);
|
void categoryOptionsChanged(const QString &categoryName);
|
||||||
void fullDiskError(Torrent *torrent, const QString &msg);
|
void fullDiskError(Torrent *torrent, const QString &msg);
|
||||||
void IPFilterParsed(bool error, int ruleCount);
|
void IPFilterParsed(bool error, int ruleCount);
|
||||||
void loadTorrentFailed(const QString &error);
|
|
||||||
void metadataDownloaded(const TorrentInfo &info);
|
void metadataDownloaded(const TorrentInfo &info);
|
||||||
void restored();
|
void restored();
|
||||||
void paused();
|
void paused();
|
||||||
|
|
|
@ -1621,15 +1621,33 @@ void SessionImpl::processNextResumeData(ResumeSessionContext *context)
|
||||||
|
|
||||||
qDebug() << "Starting up torrent" << torrentID.toString() << "...";
|
qDebug() << "Starting up torrent" << torrentID.toString() << "...";
|
||||||
m_loadingTorrents.insert(torrentID, resumeData);
|
m_loadingTorrents.insert(torrentID, resumeData);
|
||||||
#ifdef QBT_USES_LIBTORRENT2
|
|
||||||
if (infoHash.isHybrid())
|
|
||||||
{
|
|
||||||
// this allows to know the being added hybrid torrent by its v1 info hash
|
|
||||||
// without having yet another mapping table
|
|
||||||
m_hybridTorrentsByAltID.insert(torrentIDv1, nullptr);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
m_nativeSession->async_add_torrent(resumeData.ltAddTorrentParams);
|
m_nativeSession->async_add_torrent(resumeData.ltAddTorrentParams);
|
||||||
|
m_addTorrentAlertHandlers.enqueue([this](const lt::add_torrent_alert *alert)
|
||||||
|
{
|
||||||
|
if (alert->error)
|
||||||
|
{
|
||||||
|
const QString msg = QString::fromStdString(alert->message());
|
||||||
|
LogMsg(tr("Failed to load torrent. Reason: \"%1\"").arg(msg), Log::WARNING);
|
||||||
|
m_loadingTorrents.remove(getInfoHash(alert->params).toTorrentID());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const TorrentID torrentID = getInfoHash(alert->handle).toTorrentID();
|
||||||
|
|
||||||
|
if (const auto loadingTorrentsIter = m_loadingTorrents.constFind(torrentID)
|
||||||
|
; loadingTorrentsIter != m_loadingTorrents.cend())
|
||||||
|
{
|
||||||
|
const LoadTorrentParams params = loadingTorrentsIter.value();
|
||||||
|
m_loadingTorrents.erase(loadingTorrentsIter);
|
||||||
|
|
||||||
|
Torrent *torrent = createTorrent(alert->handle, params);
|
||||||
|
m_loadedTorrents.append(torrent);
|
||||||
|
|
||||||
|
LogMsg(tr("Restored torrent. Torrent: \"%1\"").arg(torrent->name()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
++context->processingResumeDataCount;
|
++context->processingResumeDataCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2994,8 +3012,6 @@ bool SessionImpl::addTorrent_impl(const TorrentDescriptor &source, const AddTorr
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
m_loadingTorrents.insert(id, loadTorrentParams);
|
m_loadingTorrents.insert(id, loadTorrentParams);
|
||||||
if (infoHash.isHybrid())
|
|
||||||
m_hybridTorrentsByAltID.insert(altID, nullptr);
|
|
||||||
|
|
||||||
const auto resolveFileNames = [&, this]
|
const auto resolveFileNames = [&, this]
|
||||||
{
|
{
|
||||||
|
@ -3027,6 +3043,52 @@ 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](const lt::add_torrent_alert *alert)
|
||||||
|
{
|
||||||
|
if (alert->error)
|
||||||
|
{
|
||||||
|
const QString msg = QString::fromStdString(alert->message());
|
||||||
|
LogMsg(tr("Failed to add torrent. Reason: \"%1\"").arg(msg), Log::WARNING);
|
||||||
|
|
||||||
|
const InfoHash infoHash = getInfoHash(alert->params);
|
||||||
|
if (const auto loadingTorrentsIter = m_loadingTorrents.constFind(TorrentID::fromInfoHash(infoHash))
|
||||||
|
; loadingTorrentsIter != m_loadingTorrents.cend())
|
||||||
|
{
|
||||||
|
const AddTorrentError::Kind errorKind = (alert->error == lt::errors::duplicate_torrent)
|
||||||
|
? AddTorrentError::DuplicateTorrent : AddTorrentError::Other;
|
||||||
|
emit addTorrentFailed(infoHash, {errorKind, msg});
|
||||||
|
m_loadingTorrents.erase(loadingTorrentsIter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const TorrentID torrentID = getInfoHash(alert->handle).toTorrentID();
|
||||||
|
if (const auto loadingTorrentsIter = m_loadingTorrents.constFind(torrentID)
|
||||||
|
; loadingTorrentsIter != m_loadingTorrents.cend())
|
||||||
|
{
|
||||||
|
const LoadTorrentParams params = loadingTorrentsIter.value();
|
||||||
|
m_loadingTorrents.erase(loadingTorrentsIter);
|
||||||
|
|
||||||
|
if (params.addToQueueTop)
|
||||||
|
alert->handle.queue_position_top();
|
||||||
|
|
||||||
|
TorrentImpl *torrent = createTorrent(alert->handle, params);
|
||||||
|
m_loadedTorrents.append(torrent);
|
||||||
|
|
||||||
|
torrent->requestResumeData(lt::torrent_handle::save_info_dict);
|
||||||
|
|
||||||
|
LogMsg(tr("Added new torrent. Torrent: \"%1\"").arg(torrent->name()));
|
||||||
|
emit torrentAdded(torrent);
|
||||||
|
|
||||||
|
// The following is useless for newly added magnet
|
||||||
|
if (torrent->hasMetadata())
|
||||||
|
{
|
||||||
|
if (!torrentExportDirectory().isEmpty())
|
||||||
|
exportTorrentFile(torrent, torrentExportDirectory());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -3181,6 +3243,33 @@ 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)
|
||||||
|
{
|
||||||
|
if (alert->error)
|
||||||
|
{
|
||||||
|
const QString msg = QString::fromStdString(alert->message());
|
||||||
|
LogMsg(tr("Failed to download torrent metadata. Reason: \"%1\"").arg(msg), Log::WARNING);
|
||||||
|
|
||||||
|
m_downloadedMetadata.remove(getInfoHash(alert->params).toTorrentID());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const InfoHash infoHash = getInfoHash(alert->handle);
|
||||||
|
const auto torrentID = TorrentID::fromInfoHash(infoHash);
|
||||||
|
|
||||||
|
if (const auto downloadedMetadataIter = m_downloadedMetadata.find(torrentID)
|
||||||
|
; downloadedMetadataIter != m_downloadedMetadata.end())
|
||||||
|
{
|
||||||
|
downloadedMetadataIter.value() = alert->handle;
|
||||||
|
if (infoHash.isHybrid())
|
||||||
|
{
|
||||||
|
// index hybrid magnet links by both v1 and v2 info hashes
|
||||||
|
const auto altID = TorrentID::fromSHA1Hash(infoHash.v1());
|
||||||
|
m_downloadedMetadata[altID] = alert->handle;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -5453,6 +5542,8 @@ lt::torrent_handle SessionImpl::reloadTorrent(const lt::torrent_handle ¤tH
|
||||||
params.storage = customStorageConstructor;
|
params.storage = customStorageConstructor;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// libtorrent will post an add_torrent_alert anyway, so we have to add an empty handler to ignore it.
|
||||||
|
m_addTorrentAlertHandlers.enqueue({});
|
||||||
return m_nativeSession->add_torrent(std::move(params));
|
return m_nativeSession->add_torrent(std::move(params));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5780,63 +5871,12 @@ void SessionImpl::handleAddTorrentAlert(const lt::add_torrent_alert *alert)
|
||||||
{
|
{
|
||||||
++m_receivedAddTorrentAlertsCount;
|
++m_receivedAddTorrentAlertsCount;
|
||||||
|
|
||||||
if (alert->error)
|
Q_ASSERT(!m_addTorrentAlertHandlers.isEmpty());
|
||||||
{
|
if (m_addTorrentAlertHandlers.isEmpty()) [[unlikely]]
|
||||||
const QString msg = QString::fromStdString(alert->message());
|
|
||||||
LogMsg(tr("Failed to load torrent. Reason: \"%1\"").arg(msg), Log::WARNING);
|
|
||||||
emit loadTorrentFailed(msg);
|
|
||||||
|
|
||||||
const InfoHash infoHash = getInfoHash(alert->params);
|
|
||||||
#ifdef QBT_USES_LIBTORRENT2
|
|
||||||
if (infoHash.isHybrid())
|
|
||||||
m_hybridTorrentsByAltID.remove(TorrentID::fromSHA1Hash(infoHash.v1()));
|
|
||||||
#endif
|
|
||||||
if (const auto loadingTorrentsIter = m_loadingTorrents.constFind(TorrentID::fromInfoHash(infoHash))
|
|
||||||
; loadingTorrentsIter != m_loadingTorrents.cend())
|
|
||||||
{
|
|
||||||
const AddTorrentError::Kind errorKind = (alert->error == lt::errors::duplicate_torrent)
|
|
||||||
? AddTorrentError::DuplicateTorrent : AddTorrentError::Other;
|
|
||||||
emit addTorrentFailed(infoHash, {errorKind, msg});
|
|
||||||
m_loadingTorrents.erase(loadingTorrentsIter);
|
|
||||||
}
|
|
||||||
else if (const auto downloadedMetadataIter = m_downloadedMetadata.constFind(TorrentID::fromInfoHash(infoHash))
|
|
||||||
; downloadedMetadataIter != m_downloadedMetadata.cend())
|
|
||||||
{
|
|
||||||
m_downloadedMetadata.erase(downloadedMetadataIter);
|
|
||||||
if (infoHash.isHybrid())
|
|
||||||
{
|
|
||||||
// index hybrid magnet links by both v1 and v2 info hashes
|
|
||||||
const auto altID = TorrentID::fromSHA1Hash(infoHash.v1());
|
|
||||||
m_downloadedMetadata.remove(altID);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
const InfoHash infoHash = getInfoHash(alert->handle);
|
if (const AddTorrentAlertHandler handleAlert = m_addTorrentAlertHandlers.dequeue())
|
||||||
const auto torrentID = TorrentID::fromInfoHash(infoHash);
|
handleAlert(alert);
|
||||||
|
|
||||||
if (const auto loadingTorrentsIter = m_loadingTorrents.constFind(torrentID)
|
|
||||||
; loadingTorrentsIter != m_loadingTorrents.cend())
|
|
||||||
{
|
|
||||||
const LoadTorrentParams params = loadingTorrentsIter.value();
|
|
||||||
m_loadingTorrents.erase(loadingTorrentsIter);
|
|
||||||
|
|
||||||
Torrent *torrent = createTorrent(alert->handle, params);
|
|
||||||
m_loadedTorrents.append(torrent);
|
|
||||||
}
|
|
||||||
else if (const auto downloadedMetadataIter = m_downloadedMetadata.find(torrentID)
|
|
||||||
; downloadedMetadataIter != m_downloadedMetadata.end())
|
|
||||||
{
|
|
||||||
downloadedMetadataIter.value() = alert->handle;
|
|
||||||
if (infoHash.isHybrid())
|
|
||||||
{
|
|
||||||
// index hybrid magnet links by both v1 and v2 info hashes
|
|
||||||
const auto altID = TorrentID::fromSHA1Hash(infoHash.v1());
|
|
||||||
m_downloadedMetadata[altID] = alert->handle;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SessionImpl::handleAlert(const lt::alert *alert)
|
void SessionImpl::handleAlert(const lt::alert *alert)
|
||||||
|
@ -5989,37 +6029,12 @@ TorrentImpl *SessionImpl::createTorrent(const lt::torrent_handle &nativeHandle,
|
||||||
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);
|
||||||
|
|
||||||
if (isRestored())
|
|
||||||
{
|
|
||||||
if (params.addToQueueTop)
|
|
||||||
nativeHandle.queue_position_top();
|
|
||||||
|
|
||||||
torrent->requestResumeData(lt::torrent_handle::save_info_dict);
|
|
||||||
|
|
||||||
// The following is useless for newly added magnet
|
|
||||||
if (torrent->hasMetadata())
|
|
||||||
{
|
|
||||||
if (!torrentExportDirectory().isEmpty())
|
|
||||||
exportTorrentFile(torrent, torrentExportDirectory());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (((torrent->ratioLimit() >= 0) || (torrent->seedingTimeLimit() >= 0))
|
if (((torrent->ratioLimit() >= 0) || (torrent->seedingTimeLimit() >= 0))
|
||||||
&& !m_seedingLimitTimer->isActive())
|
&& !m_seedingLimitTimer->isActive())
|
||||||
{
|
{
|
||||||
m_seedingLimitTimer->start();
|
m_seedingLimitTimer->start();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isRestored())
|
|
||||||
{
|
|
||||||
LogMsg(tr("Restored torrent. Torrent: \"%1\"").arg(torrent->name()));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
LogMsg(tr("Added new torrent. Torrent: \"%1\"").arg(torrent->name()));
|
|
||||||
emit torrentAdded(torrent);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Torrent could have error just after adding to libtorrent
|
// Torrent could have error just after adding to libtorrent
|
||||||
if (torrent->hasError())
|
if (torrent->hasError())
|
||||||
LogMsg(tr("Torrent errored. Torrent: \"%1\". Error: \"%2\"").arg(torrent->name(), torrent->error()), Log::WARNING);
|
LogMsg(tr("Torrent errored. Torrent: \"%1\". Error: \"%2\"").arg(torrent->name(), torrent->error()), Log::WARNING);
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
|
#include <functional>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
@ -44,6 +45,7 @@
|
||||||
#include <QMap>
|
#include <QMap>
|
||||||
#include <QMutex>
|
#include <QMutex>
|
||||||
#include <QPointer>
|
#include <QPointer>
|
||||||
|
#include <QQueue>
|
||||||
#include <QSet>
|
#include <QSet>
|
||||||
#include <QThreadPool>
|
#include <QThreadPool>
|
||||||
|
|
||||||
|
@ -815,6 +817,9 @@ namespace BitTorrent
|
||||||
FileSearcher *m_fileSearcher = nullptr;
|
FileSearcher *m_fileSearcher = nullptr;
|
||||||
TorrentContentRemover *m_torrentContentRemover = nullptr;
|
TorrentContentRemover *m_torrentContentRemover = nullptr;
|
||||||
|
|
||||||
|
using AddTorrentAlertHandler = std::function<void (const lt::add_torrent_alert *alert)>;
|
||||||
|
QQueue<AddTorrentAlertHandler> m_addTorrentAlertHandlers;
|
||||||
|
|
||||||
QHash<TorrentID, lt::torrent_handle> m_downloadedMetadata;
|
QHash<TorrentID, lt::torrent_handle> m_downloadedMetadata;
|
||||||
|
|
||||||
QHash<TorrentID, TorrentImpl *> m_torrents;
|
QHash<TorrentID, TorrentImpl *> m_torrents;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue