From 2e4431f0b84d46d488604453a506f4d8f7a0f1a1 Mon Sep 17 00:00:00 2001 From: Vladimir Golovnev Date: Tue, 8 Nov 2022 07:00:40 +0300 Subject: [PATCH] Save torrents queue w/o blocking calls PR #17988. --- src/base/bittorrent/sessionimpl.cpp | 54 +++++++++++++++++++---------- src/base/bittorrent/sessionimpl.h | 6 ++-- 2 files changed, 40 insertions(+), 20 deletions(-) diff --git a/src/base/bittorrent/sessionimpl.cpp b/src/base/bittorrent/sessionimpl.cpp index f640d26ad..0bc64d05b 100644 --- a/src/base/bittorrent/sessionimpl.cpp +++ b/src/base/bittorrent/sessionimpl.cpp @@ -582,6 +582,15 @@ SessionImpl::SessionImpl(QObject *parent) SessionImpl::~SessionImpl() { + m_nativeSession->pause(); + + if (m_torrentsQueueChanged) + { + m_nativeSession->post_torrent_updates({}); + m_torrentsQueueChanged = false; + m_needSaveTorrentsQueue = true; + } + // Do some bittorrent related saving // After this, (ideally) no more important alerts will be generated/handled saveResumeData(); @@ -2348,7 +2357,7 @@ void SessionImpl::increaseTorrentsQueuePos(const QVector &ids) torrentQueue.pop(); } - saveTorrentsQueue(); + m_torrentsQueueChanged = true; } void SessionImpl::decreaseTorrentsQueuePos(const QVector &ids) @@ -2376,7 +2385,7 @@ void SessionImpl::decreaseTorrentsQueuePos(const QVector &ids) for (auto i = m_downloadedMetadata.cbegin(); i != m_downloadedMetadata.cend(); ++i) torrentQueuePositionBottom(m_nativeSession->find_torrent(*i)); - saveTorrentsQueue(); + m_torrentsQueueChanged = true; } void SessionImpl::topTorrentsQueuePos(const QVector &ids) @@ -2401,7 +2410,7 @@ void SessionImpl::topTorrentsQueuePos(const QVector &ids) torrentQueue.pop(); } - saveTorrentsQueue(); + m_torrentsQueueChanged = true; } void SessionImpl::bottomTorrentsQueuePos(const QVector &ids) @@ -2431,7 +2440,7 @@ void SessionImpl::bottomTorrentsQueuePos(const QVector &ids) for (auto i = m_downloadedMetadata.cbegin(); i != m_downloadedMetadata.cend(); ++i) torrentQueuePositionBottom(m_nativeSession->find_torrent(*i)); - saveTorrentsQueue(); + m_torrentsQueueChanged = true; } void SessionImpl::handleTorrentNeedSaveResumeData(const TorrentImpl *torrent) @@ -2904,12 +2913,6 @@ void SessionImpl::generateResumeData() // Called on exit void SessionImpl::saveResumeData() { - // Pause session - m_nativeSession->pause(); - - if (isQueueingSystemEnabled()) - saveTorrentsQueue(); - for (const TorrentImpl *torrent : asConst(m_torrents)) { torrent->nativeHandle().save_resume_data(lt::torrent_handle::only_if_modified); @@ -2929,7 +2932,7 @@ void SessionImpl::saveResumeData() QElapsedTimer timer; timer.start(); - while ((m_numResumeData > 0) || !m_moveStorageQueue.isEmpty()) + while ((m_numResumeData > 0) || !m_moveStorageQueue.isEmpty() || m_needSaveTorrentsQueue) { const lt::seconds waitTime {5}; const lt::seconds expireTime {30}; @@ -2949,7 +2952,8 @@ void SessionImpl::saveResumeData() { if (const int alertType = a->type(); (alertType == lt::save_resume_data_alert::alert_type) || (alertType == lt::save_resume_data_failed_alert::alert_type) - || (alertType == lt::storage_moved_alert::alert_type) || (alertType == lt::storage_moved_failed_alert::alert_type)) + || (alertType == lt::storage_moved_alert::alert_type) || (alertType == lt::storage_moved_failed_alert::alert_type) + || (alertType == lt::state_update_alert::alert_type)) { hasWantedAlert = true; } @@ -2962,14 +2966,12 @@ void SessionImpl::saveResumeData() } } -void SessionImpl::saveTorrentsQueue() const +void SessionImpl::saveTorrentsQueue() { QVector queue; for (const TorrentImpl *torrent : asConst(m_torrents)) { - // We require actual (non-cached) queue position here! - const int queuePos = LT::toUnderlyingType(torrent->nativeHandle().queue_position()); - if (queuePos >= 0) + if (const int queuePos = torrent->queuePosition(); queuePos >= 0) { if (queuePos >= queue.size()) queue.resize(queuePos + 1); @@ -2978,11 +2980,14 @@ void SessionImpl::saveTorrentsQueue() const } m_resumeDataStorage->storeQueue(queue); + m_needSaveTorrentsQueue = false; } -void SessionImpl::removeTorrentsQueue() const +void SessionImpl::removeTorrentsQueue() { m_resumeDataStorage->storeQueue({}); + m_torrentsQueueChanged = false; + m_needSaveTorrentsQueue = false; } void SessionImpl::setSavePath(const Path &path) @@ -4097,7 +4102,7 @@ void SessionImpl::setQueueingSystemEnabled(const bool enabled) configureDeferred(); if (enabled) - saveTorrentsQueue(); + m_torrentsQueueChanged = true; else removeTorrentsQueue(); } @@ -4989,6 +4994,12 @@ void SessionImpl::enqueueRefresh() { m_nativeSession->post_torrent_updates(); m_nativeSession->post_session_stats(); + + if (m_torrentsQueueChanged) + { + m_torrentsQueueChanged = false; + m_needSaveTorrentsQueue = true; + } }); m_refreshEnqueued = true; @@ -5096,7 +5107,11 @@ void SessionImpl::handleAddTorrentAlerts(const std::vector &alerts) } if (!loadedTorrents.isEmpty()) + { + if (isRestored()) + m_torrentsQueueChanged = true; emit torrentsLoaded(loadedTorrents); + } } void SessionImpl::handleAlert(const lt::alert *a) @@ -5660,6 +5675,9 @@ void SessionImpl::handleStateUpdateAlert(const lt::state_update_alert *p) if (!updatedTorrents.isEmpty()) emit torrentsUpdated(updatedTorrents); + if (m_needSaveTorrentsQueue) + saveTorrentsQueue(); + if (m_refreshEnqueued) m_refreshEnqueued = false; else diff --git a/src/base/bittorrent/sessionimpl.h b/src/base/bittorrent/sessionimpl.h index d7a747f61..578aa26c4 100644 --- a/src/base/bittorrent/sessionimpl.h +++ b/src/base/bittorrent/sessionimpl.h @@ -533,8 +533,8 @@ namespace BitTorrent TorrentImpl *createTorrent(const lt::torrent_handle &nativeHandle, const LoadTorrentParams ¶ms); void saveResumeData(); - void saveTorrentsQueue() const; - void removeTorrentsQueue() const; + void saveTorrentsQueue(); + void removeTorrentsQueue(); std::vector getPendingAlerts(lt::time_duration time = lt::time_duration::zero()) const; @@ -681,6 +681,8 @@ namespace BitTorrent qint64 m_previouslyUploaded = 0; qint64 m_previouslyDownloaded = 0; + bool m_torrentsQueueChanged = false; + bool m_needSaveTorrentsQueue = false; bool m_refreshEnqueued = false; QTimer *m_seedingLimitTimer = nullptr; QTimer *m_resumeDataTimer = nullptr;