From bd45dc5d0fe56113b5458a87eb1b05affccdd8bc Mon Sep 17 00:00:00 2001 From: "Vladimir Golovnev (Glassez)" Date: Mon, 11 Apr 2022 22:20:11 +0300 Subject: [PATCH 1/2] Avoid some blocking calls to libtorrent --- src/base/bittorrent/torrentimpl.cpp | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/src/base/bittorrent/torrentimpl.cpp b/src/base/bittorrent/torrentimpl.cpp index 06454a680..1ef51ba11 100644 --- a/src/base/bittorrent/torrentimpl.cpp +++ b/src/base/bittorrent/torrentimpl.cpp @@ -284,17 +284,18 @@ TorrentImpl::TorrentImpl(Session *session, lt::session *nativeSession m_filePaths.reserve(filesCount); m_indexMap.reserve(filesCount); m_filePriorities.reserve(filesCount); - const std::shared_ptr currentInfo = m_nativeHandle.torrent_file(); - const lt::file_storage &fileStorage = currentInfo->files(); const std::vector filePriorities = - resized(m_ltAddTorrentParams.file_priorities, fileStorage.num_files() + resized(m_ltAddTorrentParams.file_priorities, m_ltAddTorrentParams.ti->num_files() , LT::toNative(m_ltAddTorrentParams.file_priorities.empty() ? DownloadPriority::Normal : DownloadPriority::Ignored)); + for (int i = 0; i < filesCount; ++i) { const lt::file_index_t nativeIndex = m_torrentInfo.nativeIndexes().at(i); m_indexMap[nativeIndex] = i; - const auto filePath = Path(fileStorage.file_path(nativeIndex)).removedExtension(QB_EXT); + const auto fileIter = m_ltAddTorrentParams.renamed_files.find(nativeIndex); + const Path filePath = ((fileIter != m_ltAddTorrentParams.renamed_files.end()) + ? Path(fileIter->second).removedExtension(QB_EXT) : m_torrentInfo.filePath(i)); m_filePaths.append(filePath); const auto priority = LT::fromNative(filePriorities[LT::toUnderlyingType(nativeIndex)]); @@ -1465,7 +1466,7 @@ void TorrentImpl::applyFirstLastPiecePriority(const bool enabled) // Download first and last pieces first for every file in the torrent - std::vector piecePriorities = nativeHandle().get_piece_priorities(); + auto piecePriorities = std::vector(m_torrentInfo.piecesCount(), LT::toNative(DownloadPriority::Ignored)); // Updating file priorities is an async operation in libtorrent, when we just updated it and immediately query it // we might get the old/wrong values, so we rely on `updatedFilePrio` in this case. @@ -1476,17 +1477,21 @@ void TorrentImpl::applyFirstLastPiecePriority(const bool enabled) continue; // Determine the priority to set - const DownloadPriority newPrio = enabled ? DownloadPriority::Maximum : filePrio; - const auto piecePrio = static_cast(static_cast(newPrio)); - const TorrentInfo::PieceRange extremities = m_torrentInfo.filePieces(index); + const lt::download_priority_t piecePrio = LT::toNative(enabled ? DownloadPriority::Maximum : filePrio); + const TorrentInfo::PieceRange pieceRange = m_torrentInfo.filePieces(index); // worst case: AVI index = 1% of total file size (at the end of the file) - const int nNumPieces = std::ceil(fileSize(index) * 0.01 / pieceLength()); - for (int i = 0; i < nNumPieces; ++i) + const int numPieces = std::ceil(fileSize(index) * 0.01 / pieceLength()); + for (int i = 0; i < numPieces; ++i) { - piecePriorities[extremities.first() + i] = piecePrio; - piecePriorities[extremities.last() - i] = piecePrio; + piecePriorities[pieceRange.first() + i] = piecePrio; + piecePriorities[pieceRange.last() - i] = piecePrio; } + + const int firstPiece = pieceRange.first() + numPieces; + const int lastPiece = pieceRange.last() - numPieces; + for (int index = firstPiece; index <= lastPiece; ++index) + piecePriorities[index] = LT::toNative(filePrio); } m_nativeHandle.prioritize_pieces(piecePriorities); From 35fcf39fc889bd12c0838e7c0093b654ff3c6638 Mon Sep 17 00:00:00 2001 From: "Vladimir Golovnev (Glassez)" Date: Thu, 14 Apr 2022 17:21:16 +0300 Subject: [PATCH 2/2] Add additional trackers without extra blocking call --- src/base/bittorrent/session.cpp | 18 ++++++++++++++---- src/base/bittorrent/torrentimpl.cpp | 12 ++++++------ 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/src/base/bittorrent/session.cpp b/src/base/bittorrent/session.cpp index e0c21cda7..22dd85a9a 100644 --- a/src/base/bittorrent/session.cpp +++ b/src/base/bittorrent/session.cpp @@ -2310,6 +2310,17 @@ bool Session::addTorrent_impl(const std::variant &source for (int i = 0; i < addTorrentParams.filePriorities.size(); ++i) p.file_priorities[LT::toUnderlyingType(nativeIndexes[i])] = LT::toNative(addTorrentParams.filePriorities[i]); + if (isAddTrackersEnabled() && !torrentInfo.isPrivate()) + { + p.trackers.reserve(static_cast(m_additionalTrackerList.size())); + p.tracker_tiers.reserve(static_cast(m_additionalTrackerList.size())); + for (const TrackerEntry &trackerEntry : asConst(m_additionalTrackerList)) + { + p.trackers.push_back(trackerEntry.url.toStdString()); + p.tracker_tiers.push_back(trackerEntry.tier); + } + } + p.ti = torrentInfo.nativeInfo(); } else @@ -4899,7 +4910,7 @@ void Session::createTorrent(const lt::torrent_handle &nativeHandle) const LoadTorrentParams params = m_loadingTorrents.take(torrentID); - auto *const torrent = new TorrentImpl {this, m_nativeSession, nativeHandle, params}; + auto *const torrent = new TorrentImpl(this, m_nativeSession, nativeHandle, params); m_torrents.insert(torrent->id(), torrent); const bool hasMetadata = torrent->hasMetadata(); @@ -4918,14 +4929,13 @@ void Session::createTorrent(const lt::torrent_handle &nativeHandle) exportTorrentFile(torrentInfo, torrentExportDirectory(), torrent->name()); } } - - if (isAddTrackersEnabled() && !torrent->isPrivate()) - torrent->addTrackers(m_additionalTrackerList); } if (((torrent->ratioLimit() >= 0) || (torrent->seedingTimeLimit() >= 0)) && !m_seedingLimitTimer->isActive()) + { m_seedingLimitTimer->start(); + } // Send torrent addition signal emit torrentLoaded(torrent); diff --git a/src/base/bittorrent/torrentimpl.cpp b/src/base/bittorrent/torrentimpl.cpp index 1ef51ba11..76c4bdfdd 100644 --- a/src/base/bittorrent/torrentimpl.cpp +++ b/src/base/bittorrent/torrentimpl.cpp @@ -1470,18 +1470,18 @@ void TorrentImpl::applyFirstLastPiecePriority(const bool enabled) // Updating file priorities is an async operation in libtorrent, when we just updated it and immediately query it // we might get the old/wrong values, so we rely on `updatedFilePrio` in this case. - for (int index = 0; index < m_filePriorities.size(); ++index) + for (int fileIndex = 0; fileIndex < m_filePriorities.size(); ++fileIndex) { - const DownloadPriority filePrio = m_filePriorities[index]; + const DownloadPriority filePrio = m_filePriorities[fileIndex]; if (filePrio <= DownloadPriority::Ignored) continue; // Determine the priority to set const lt::download_priority_t piecePrio = LT::toNative(enabled ? DownloadPriority::Maximum : filePrio); - const TorrentInfo::PieceRange pieceRange = m_torrentInfo.filePieces(index); + const TorrentInfo::PieceRange pieceRange = m_torrentInfo.filePieces(fileIndex); // worst case: AVI index = 1% of total file size (at the end of the file) - const int numPieces = std::ceil(fileSize(index) * 0.01 / pieceLength()); + const int numPieces = std::ceil(fileSize(fileIndex) * 0.01 / pieceLength()); for (int i = 0; i < numPieces; ++i) { piecePriorities[pieceRange.first() + i] = piecePrio; @@ -1490,8 +1490,8 @@ void TorrentImpl::applyFirstLastPiecePriority(const bool enabled) const int firstPiece = pieceRange.first() + numPieces; const int lastPiece = pieceRange.last() - numPieces; - for (int index = firstPiece; index <= lastPiece; ++index) - piecePriorities[index] = LT::toNative(filePrio); + for (int pieceIndex = firstPiece; pieceIndex <= lastPiece; ++pieceIndex) + piecePriorities[pieceIndex] = LT::toNative(filePrio); } m_nativeHandle.prioritize_pieces(piecePriorities);