Skip to content

Commit

Permalink
Avoid race condition when update tracker entries
Browse files Browse the repository at this point in the history
PR #21995.
  • Loading branch information
glassez authored Dec 15, 2024
1 parent 53adb7b commit 68f7295
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 3 deletions.
12 changes: 9 additions & 3 deletions src/base/bittorrent/sessionimpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonValue>
#include <QMutexLocker>
#include <QNetworkAddressEntry>
#include <QNetworkInterface>
#include <QRegularExpression>
Expand Down Expand Up @@ -6201,6 +6202,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())
Expand Down Expand Up @@ -6297,14 +6300,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)
Expand Down
2 changes: 2 additions & 0 deletions src/base/bittorrent/sessionimpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
#include <QElapsedTimer>
#include <QHash>
#include <QMap>
#include <QMutex>
#include <QPointer>
#include <QSet>
#include <QVector>
Expand Down Expand Up @@ -793,6 +794,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;
Expand Down

0 comments on commit 68f7295

Please sign in to comment.