diff --git a/src/base/CMakeLists.txt b/src/base/CMakeLists.txt index 36bb0f506..60d9995fa 100644 --- a/src/base/CMakeLists.txt +++ b/src/base/CMakeLists.txt @@ -35,7 +35,7 @@ add_library(qbt_base STATIC bittorrent/torrent.h bittorrent/torrentcontenthandler.h bittorrent/torrentcontentlayout.h - bittorrent/torrentcreatorthread.h + bittorrent/torrentcreator.h bittorrent/torrentdescriptor.h bittorrent/torrentimpl.h bittorrent/torrentinfo.h @@ -132,7 +132,7 @@ add_library(qbt_base STATIC bittorrent/speedmonitor.cpp bittorrent/torrent.cpp bittorrent/torrentcontenthandler.cpp - bittorrent/torrentcreatorthread.cpp + bittorrent/torrentcreator.cpp bittorrent/torrentdescriptor.cpp bittorrent/torrentimpl.cpp bittorrent/torrentinfo.cpp diff --git a/src/base/bittorrent/torrentcreatorthread.cpp b/src/base/bittorrent/torrentcreator.cpp similarity index 90% rename from src/base/bittorrent/torrentcreatorthread.cpp rename to src/base/bittorrent/torrentcreator.cpp index f7253f207..7762e63f8 100644 --- a/src/base/bittorrent/torrentcreatorthread.cpp +++ b/src/base/bittorrent/torrentcreator.cpp @@ -26,7 +26,7 @@ * exception statement from your version. */ -#include "torrentcreatorthread.h" +#include "torrentcreator.h" #include @@ -74,35 +74,34 @@ namespace using namespace BitTorrent; -TorrentCreatorThread::TorrentCreatorThread(QObject *parent) - : QThread(parent) +TorrentCreator::TorrentCreator(const TorrentCreatorParams ¶ms, QObject *parent) + : QObject(parent) + , m_params {params} { } -TorrentCreatorThread::~TorrentCreatorThread() -{ - requestInterruption(); - wait(); -} - -void TorrentCreatorThread::create(const TorrentCreatorParams ¶ms) -{ - m_params = params; - start(); -} - -void TorrentCreatorThread::sendProgressSignal(int currentPieceIdx, int totalPieces) +void TorrentCreator::sendProgressSignal(int currentPieceIdx, int totalPieces) { emit updateProgress(static_cast((currentPieceIdx * 100.) / totalPieces)); } -void TorrentCreatorThread::checkInterruptionRequested() const +void TorrentCreator::checkInterruptionRequested() const { if (isInterruptionRequested()) throw RuntimeError(tr("Operation aborted")); } -void TorrentCreatorThread::run() +void TorrentCreator::requestInterruption() +{ + m_interruptionRequested.storeRelaxed(1); +} + +bool TorrentCreator::isInterruptionRequested() const +{ + return m_interruptionRequested.loadRelaxed() != 0; +} + +void TorrentCreator::run() { emit updateProgress(0); @@ -225,9 +224,9 @@ void TorrentCreatorThread::run() } #ifdef QBT_USES_LIBTORRENT2 -int TorrentCreatorThread::calculateTotalPieces(const Path &inputPath, const int pieceSize, const TorrentFormat torrentFormat) +int TorrentCreator::calculateTotalPieces(const Path &inputPath, const int pieceSize, const TorrentFormat torrentFormat) #else -int TorrentCreatorThread::calculateTotalPieces(const Path &inputPath, const int pieceSize, const bool isAlignmentOptimized, const int paddedFileSizeLimit) +int TorrentCreator::calculateTotalPieces(const Path &inputPath, const int pieceSize, const bool isAlignmentOptimized, const int paddedFileSizeLimit) #endif { if (inputPath.isEmpty()) diff --git a/src/base/bittorrent/torrentcreatorthread.h b/src/base/bittorrent/torrentcreator.h similarity index 87% rename from src/base/bittorrent/torrentcreatorthread.h rename to src/base/bittorrent/torrentcreator.h index 31afeeb0c..b819306b4 100644 --- a/src/base/bittorrent/torrentcreatorthread.h +++ b/src/base/bittorrent/torrentcreator.h @@ -28,8 +28,10 @@ #pragma once +#include +#include +#include #include -#include #include "base/path.h" @@ -62,16 +64,20 @@ namespace BitTorrent QStringList urlSeeds; }; - class TorrentCreatorThread final : public QThread + class TorrentCreator final : public QObject, public QRunnable { Q_OBJECT - Q_DISABLE_COPY_MOVE(TorrentCreatorThread) + Q_DISABLE_COPY_MOVE(TorrentCreator) public: - explicit TorrentCreatorThread(QObject *parent = nullptr); - ~TorrentCreatorThread() override; + explicit TorrentCreator(const TorrentCreatorParams ¶ms, QObject *parent = nullptr); - void create(const TorrentCreatorParams ¶ms); + void run() override; + + bool isInterruptionRequested() const; + + public slots: + void requestInterruption(); #ifdef QBT_USES_LIBTORRENT2 static int calculateTotalPieces(const Path &inputPath, int pieceSize, TorrentFormat torrentFormat); @@ -86,10 +92,10 @@ namespace BitTorrent void updateProgress(int progress); private: - void run() override; void sendProgressSignal(int currentPieceIdx, int totalPieces); void checkInterruptionRequested() const; TorrentCreatorParams m_params; + QAtomicInt m_interruptionRequested; }; } diff --git a/src/gui/torrentcreatordialog.cpp b/src/gui/torrentcreatordialog.cpp index 687df05ec..749bf21d4 100644 --- a/src/gui/torrentcreatordialog.cpp +++ b/src/gui/torrentcreatordialog.cpp @@ -59,7 +59,7 @@ namespace TorrentCreatorDialog::TorrentCreatorDialog(QWidget *parent, const Path &defaultPath) : QDialog(parent) , m_ui(new Ui::TorrentCreatorDialog) - , m_creatorThread(new BitTorrent::TorrentCreatorThread(this)) + , m_threadPool(this) , m_storeDialogSize(SETTINGS_KEY(u"Size"_s)) , m_storePieceSize(SETTINGS_KEY(u"PieceSize"_s)) , m_storePrivateTorrent(SETTINGS_KEY(u"PrivateTorrent"_s)) @@ -90,13 +90,11 @@ TorrentCreatorDialog::TorrentCreatorDialog(QWidget *parent, const Path &defaultP connect(m_ui->buttonCalcTotalPieces, &QPushButton::clicked, this, &TorrentCreatorDialog::updatePiecesCount); connect(m_ui->checkStartSeeding, &QCheckBox::clicked, m_ui->checkIgnoreShareLimits, &QWidget::setEnabled); - connect(m_creatorThread, &BitTorrent::TorrentCreatorThread::creationSuccess, this, &TorrentCreatorDialog::handleCreationSuccess); - connect(m_creatorThread, &BitTorrent::TorrentCreatorThread::creationFailure, this, &TorrentCreatorDialog::handleCreationFailure); - connect(m_creatorThread, &BitTorrent::TorrentCreatorThread::updateProgress, this, &TorrentCreatorDialog::updateProgressBar); - loadSettings(); updateInputPath(defaultPath); + m_threadPool.setMaxThreadCount(1); + #ifdef QBT_USES_LIBTORRENT2 m_ui->checkOptimizeAlignment->hide(); #else @@ -233,8 +231,14 @@ void TorrentCreatorDialog::onCreateButtonClicked() , m_ui->URLSeedsList->toPlainText().split(u'\n', Qt::SkipEmptyParts) }; - // run the creator thread - m_creatorThread->create(params); + auto *torrentCreator = new BitTorrent::TorrentCreator(params); + connect(this, &QDialog::rejected, torrentCreator, &BitTorrent::TorrentCreator::requestInterruption); + connect(torrentCreator, &BitTorrent::TorrentCreator::creationSuccess, this, &TorrentCreatorDialog::handleCreationSuccess); + connect(torrentCreator, &BitTorrent::TorrentCreator::creationFailure, this, &TorrentCreatorDialog::handleCreationFailure); + connect(torrentCreator, &BitTorrent::TorrentCreator::updateProgress, this, &TorrentCreatorDialog::updateProgressBar); + + // run the torrentCreator in a thread + m_threadPool.start(torrentCreator); } void TorrentCreatorDialog::handleCreationFailure(const QString &msg) @@ -286,11 +290,11 @@ void TorrentCreatorDialog::updatePiecesCount() { const Path path = m_ui->textInputPath->selectedPath(); #ifdef QBT_USES_LIBTORRENT2 - const int count = BitTorrent::TorrentCreatorThread::calculateTotalPieces( + const int count = BitTorrent::TorrentCreator::calculateTotalPieces( path, getPieceSize(), getTorrentFormat()); #else const bool isAlignmentOptimized = m_ui->checkOptimizeAlignment->isChecked(); - const int count = BitTorrent::TorrentCreatorThread::calculateTotalPieces(path + const int count = BitTorrent::TorrentCreator::calculateTotalPieces(path , getPieceSize(), isAlignmentOptimized, getPaddedFileSizeLimit()); #endif m_ui->labelTotalPieces->setText(QString::number(count)); diff --git a/src/gui/torrentcreatordialog.h b/src/gui/torrentcreatordialog.h index 4f032c2cf..addda955d 100644 --- a/src/gui/torrentcreatordialog.h +++ b/src/gui/torrentcreatordialog.h @@ -30,8 +30,9 @@ #pragma once #include +#include -#include "base/bittorrent/torrentcreatorthread.h" +#include "base/bittorrent/torrentcreator.h" #include "base/path.h" #include "base/settingvalue.h" @@ -75,7 +76,7 @@ private: #endif Ui::TorrentCreatorDialog *m_ui = nullptr; - BitTorrent::TorrentCreatorThread *m_creatorThread = nullptr; + QThreadPool m_threadPool; // settings SettingValue m_storeDialogSize;