Avoid race condition when update tracker entries

PR #21995.
This commit is contained in:
Vladimir Golovnev 2024-12-15 14:07:36 +03:00 committed by GitHub
parent 14684c8c83
commit eb2eea8d34
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 11 additions and 3 deletions

View file

@ -66,6 +66,7 @@
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonValue>
#include <QMutexLocker>
#include <QNetworkAddressEntry>
#include <QNetworkInterface>
#include <QRegularExpression>
@ -6234,6 +6235,8 @@ void SessionImpl::handleTrackerAlert(const lt::tracker_alert *alert)
if (!torrent)
return;
[[maybe_unused]] const QMutexLocker updatedTrackerStatusesLocker {&m_updatedTrackerStatusesMutex};
const auto prevSize = m_updatedTrackerStatuses.size();
QMap<int, int> &updateInfo = m_updatedTrackerStatuses[torrent->nativeHandle()][std::string(alert->tracker_url())][alert->local_endpoint];
if (prevSize < m_updatedTrackerStatuses.size())
@ -6330,14 +6333,17 @@ void SessionImpl::updateTrackerEntryStatuses(lt::torrent_handle torrentHandle)
try
{
std::vector<lt::announce_entry> nativeTrackers = torrentHandle.trackers();
invoke([this, torrentHandle, nativeTrackers = std::move(nativeTrackers)]
QMutexLocker updatedTrackerStatusesLocker {&m_updatedTrackerStatusesMutex};
QHash<std::string, QHash<lt::tcp::endpoint, QMap<int, int>>> updatedTrackers = m_updatedTrackerStatuses.take(torrentHandle);
updatedTrackerStatusesLocker.unlock();
invoke([this, torrentHandle, nativeTrackers = std::move(nativeTrackers), updatedTrackers = std::move(updatedTrackers)]
{
TorrentImpl *torrent = m_torrents.value(torrentHandle.info_hash());
if (!torrent || torrent->isStopped())
return;
QHash<std::string, QHash<lt::tcp::endpoint, QMap<int, int>>> updatedTrackers = m_updatedTrackerStatuses.take(torrentHandle);
QHash<QString, TrackerEntryStatus> trackers;
trackers.reserve(updatedTrackers.size());
for (const lt::announce_entry &announceEntry : nativeTrackers)

View file

@ -42,6 +42,7 @@
#include <QHash>
#include <QList>
#include <QMap>
#include <QMutex>
#include <QPointer>
#include <QSet>
#include <QThreadPool>
@ -799,6 +800,7 @@ namespace BitTorrent
// This field holds amounts of peers reported by trackers in their responses to announces
// (torrent.tracker_name.tracker_local_endpoint.protocol_version.num_peers)
QHash<lt::torrent_handle, QHash<std::string, QHash<lt::tcp::endpoint, QMap<int, int>>>> m_updatedTrackerStatuses;
QMutex m_updatedTrackerStatusesMutex;
// I/O errored torrents
QSet<TorrentID> m_recentErroredTorrents;