mirror of
https://github.com/d47081/qBittorrent.git
synced 2025-01-11 07:18:08 +00:00
Merge pull request #16876 from glassez/blocking
Avoid some blocking calls to libtorrent Under some conditions (when libtorrent is doing heavy work), blocking calls can wait quite a long time, thereby suspending the main application thread. In some cases, we can avoid this, since we have enough data to make the job without call to libtorrent. Although in some cases it may require a little more work to be done in the main thread, but overall responsiveness still benefits greatly in the end, especially when the libtorrent working thread is heavily loaded.
This commit is contained in:
commit
613e9866aa
@ -2310,6 +2310,17 @@ bool Session::addTorrent_impl(const std::variant<MagnetUri, TorrentInfo> &source
|
|||||||
for (int i = 0; i < addTorrentParams.filePriorities.size(); ++i)
|
for (int i = 0; i < addTorrentParams.filePriorities.size(); ++i)
|
||||||
p.file_priorities[LT::toUnderlyingType(nativeIndexes[i])] = LT::toNative(addTorrentParams.filePriorities[i]);
|
p.file_priorities[LT::toUnderlyingType(nativeIndexes[i])] = LT::toNative(addTorrentParams.filePriorities[i]);
|
||||||
|
|
||||||
|
if (isAddTrackersEnabled() && !torrentInfo.isPrivate())
|
||||||
|
{
|
||||||
|
p.trackers.reserve(static_cast<std::size_t>(m_additionalTrackerList.size()));
|
||||||
|
p.tracker_tiers.reserve(static_cast<std::size_t>(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();
|
p.ti = torrentInfo.nativeInfo();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -4899,7 +4910,7 @@ void Session::createTorrent(const lt::torrent_handle &nativeHandle)
|
|||||||
|
|
||||||
const LoadTorrentParams params = m_loadingTorrents.take(torrentID);
|
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);
|
m_torrents.insert(torrent->id(), torrent);
|
||||||
|
|
||||||
const bool hasMetadata = torrent->hasMetadata();
|
const bool hasMetadata = torrent->hasMetadata();
|
||||||
@ -4918,14 +4929,13 @@ void Session::createTorrent(const lt::torrent_handle &nativeHandle)
|
|||||||
exportTorrentFile(torrentInfo, torrentExportDirectory(), torrent->name());
|
exportTorrentFile(torrentInfo, torrentExportDirectory(), torrent->name());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isAddTrackersEnabled() && !torrent->isPrivate())
|
|
||||||
torrent->addTrackers(m_additionalTrackerList);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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();
|
||||||
|
}
|
||||||
|
|
||||||
// Send torrent addition signal
|
// Send torrent addition signal
|
||||||
emit torrentLoaded(torrent);
|
emit torrentLoaded(torrent);
|
||||||
|
@ -284,17 +284,18 @@ TorrentImpl::TorrentImpl(Session *session, lt::session *nativeSession
|
|||||||
m_filePaths.reserve(filesCount);
|
m_filePaths.reserve(filesCount);
|
||||||
m_indexMap.reserve(filesCount);
|
m_indexMap.reserve(filesCount);
|
||||||
m_filePriorities.reserve(filesCount);
|
m_filePriorities.reserve(filesCount);
|
||||||
const std::shared_ptr<const lt::torrent_info> currentInfo = m_nativeHandle.torrent_file();
|
|
||||||
const lt::file_storage &fileStorage = currentInfo->files();
|
|
||||||
const std::vector<lt::download_priority_t> filePriorities =
|
const std::vector<lt::download_priority_t> 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));
|
, LT::toNative(m_ltAddTorrentParams.file_priorities.empty() ? DownloadPriority::Normal : DownloadPriority::Ignored));
|
||||||
|
|
||||||
for (int i = 0; i < filesCount; ++i)
|
for (int i = 0; i < filesCount; ++i)
|
||||||
{
|
{
|
||||||
const lt::file_index_t nativeIndex = m_torrentInfo.nativeIndexes().at(i);
|
const lt::file_index_t nativeIndex = m_torrentInfo.nativeIndexes().at(i);
|
||||||
m_indexMap[nativeIndex] = 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);
|
m_filePaths.append(filePath);
|
||||||
|
|
||||||
const auto priority = LT::fromNative(filePriorities[LT::toUnderlyingType(nativeIndex)]);
|
const auto priority = LT::fromNative(filePriorities[LT::toUnderlyingType(nativeIndex)]);
|
||||||
@ -1465,28 +1466,32 @@ void TorrentImpl::applyFirstLastPiecePriority(const bool enabled)
|
|||||||
|
|
||||||
// Download first and last pieces first for every file in the torrent
|
// Download first and last pieces first for every file in the torrent
|
||||||
|
|
||||||
std::vector<lt::download_priority_t> piecePriorities = nativeHandle().get_piece_priorities();
|
auto piecePriorities = std::vector<lt::download_priority_t>(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
|
// 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.
|
// 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)
|
if (filePrio <= DownloadPriority::Ignored)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Determine the priority to set
|
// Determine the priority to set
|
||||||
const DownloadPriority newPrio = enabled ? DownloadPriority::Maximum : filePrio;
|
const lt::download_priority_t piecePrio = LT::toNative(enabled ? DownloadPriority::Maximum : filePrio);
|
||||||
const auto piecePrio = static_cast<lt::download_priority_t>(static_cast<int>(newPrio));
|
const TorrentInfo::PieceRange pieceRange = m_torrentInfo.filePieces(fileIndex);
|
||||||
const TorrentInfo::PieceRange extremities = m_torrentInfo.filePieces(index);
|
|
||||||
|
|
||||||
// worst case: AVI index = 1% of total file size (at the end of the file)
|
// 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());
|
const int numPieces = std::ceil(fileSize(fileIndex) * 0.01 / pieceLength());
|
||||||
for (int i = 0; i < nNumPieces; ++i)
|
for (int i = 0; i < numPieces; ++i)
|
||||||
{
|
{
|
||||||
piecePriorities[extremities.first() + i] = piecePrio;
|
piecePriorities[pieceRange.first() + i] = piecePrio;
|
||||||
piecePriorities[extremities.last() - i] = piecePrio;
|
piecePriorities[pieceRange.last() - i] = piecePrio;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const int firstPiece = pieceRange.first() + numPieces;
|
||||||
|
const int lastPiece = pieceRange.last() - numPieces;
|
||||||
|
for (int pieceIndex = firstPiece; pieceIndex <= lastPiece; ++pieceIndex)
|
||||||
|
piecePriorities[pieceIndex] = LT::toNative(filePrio);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_nativeHandle.prioritize_pieces(piecePriorities);
|
m_nativeHandle.prioritize_pieces(piecePriorities);
|
||||||
|
Loading…
Reference in New Issue
Block a user