From ebfceaf10e952490d8f01fe33a15c4c84f53bfbc Mon Sep 17 00:00:00 2001 From: "Vladimir Golovnev (Glassez)" Date: Sat, 5 Nov 2022 16:31:48 +0300 Subject: [PATCH] Save torrents queue w/o blocking calls --- 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 6495a8fcf83f..72b745f400a3 100644 --- a/src/base/bittorrent/sessionimpl.cpp +++ b/src/base/bittorrent/sessionimpl.cpp @@ -580,6 +580,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(); @@ -2335,7 +2344,7 @@ void SessionImpl::increaseTorrentsQueuePos(const QVector &ids) torrentQueue.pop(); } - saveTorrentsQueue(); + m_torrentsQueueChanged = true; } void SessionImpl::decreaseTorrentsQueuePos(const QVector &ids) @@ -2363,7 +2372,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) @@ -2388,7 +2397,7 @@ void SessionImpl::topTorrentsQueuePos(const QVector &ids) torrentQueue.pop(); } - saveTorrentsQueue(); + m_torrentsQueueChanged = true; } void SessionImpl::bottomTorrentsQueuePos(const QVector &ids) @@ -2418,7 +2427,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) @@ -2891,12 +2900,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); @@ -2916,7 +2919,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}; @@ -2936,7 +2939,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; } @@ -2949,14 +2953,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); @@ -2965,11 +2967,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) @@ -4084,7 +4089,7 @@ void SessionImpl::setQueueingSystemEnabled(const bool enabled) configureDeferred(); if (enabled) - saveTorrentsQueue(); + m_torrentsQueueChanged = true; else removeTorrentsQueue(); } @@ -4976,6 +4981,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; @@ -5083,7 +5094,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) @@ -5647,6 +5662,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 d7a747f613ea..578aa26c4251 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;