From 570296c29e0969fdfdb42b2b204a4cc081ef0843 Mon Sep 17 00:00:00 2001 From: Christophe Dumez Date: Tue, 31 Jul 2007 08:52:04 +0000 Subject: [PATCH] - Multithreaded deletionThread (harmonized with deleteThread) --- src/bittorrent.cpp | 12 ++--- src/bittorrent.h | 2 +- src/deleteThread.h | 108 +++++++++++++++++++++++++++++++++++++++---- src/downloadThread.h | 12 ++--- 4 files changed, 108 insertions(+), 26 deletions(-) diff --git a/src/bittorrent.cpp b/src/bittorrent.cpp index 5100753f9..f6dd23067 100644 --- a/src/bittorrent.cpp +++ b/src/bittorrent.cpp @@ -66,6 +66,8 @@ bittorrent::bittorrent(){ downloader = new downloadThread(this); connect(downloader, SIGNAL(downloadFinished(QString, QString)), this, SLOT(processDownloadedFile(QString, QString))); connect(downloader, SIGNAL(downloadFailure(QString, QString)), this, SLOT(HandleDownloadFailure(QString, QString))); + // File deleter (thread) + deleter = new deleteThread(this); } // Main destructor @@ -76,6 +78,7 @@ bittorrent::~bittorrent(){ saveDHTEntry(); saveFastResumeAndRatioData(); // Delete our objects + delete deleter; delete timerAlerts; delete ETARefresher; delete downloader; @@ -184,17 +187,10 @@ void bittorrent::deleteTorrent(QString hash, bool permanent){ // Remove from Hard drive qDebug("Removing this on hard drive: %s", qPrintable(savePath+QDir::separator()+fileName)); // Deleting in a thread to avoid GUI freeze - deleteThread *deleter = new deleteThread(savePath+QDir::separator()+fileName); - connect(deleter, SIGNAL(deletionFinished(deleteThread*)), this, SLOT(cleanDeleter(deleteThread*))); + deleter->deletePath(savePath+QDir::separator()+fileName); } } -// slot to destroy a deleteThread once it finished deletion -void bittorrent::cleanDeleter(deleteThread* deleter){ - qDebug("Deleting deleteThread because it finished deletion"); - delete deleter; -} - // Pause a running torrent bool bittorrent::pauseTorrent(QString hash){ bool change = false; diff --git a/src/bittorrent.h b/src/bittorrent.h index af8941ef0..9fa62e0d2 100644 --- a/src/bittorrent.h +++ b/src/bittorrent.h @@ -55,6 +55,7 @@ class bittorrent : public QObject{ QTimer *ETARefresher; QList fullAllocationModeList; QHash > > trackersErrors; + deleteThread *deleter; protected: QString getSavePath(QString hash); @@ -125,7 +126,6 @@ class bittorrent : public QObject{ void setUploadLimit(QString hash, int val); protected slots: - void cleanDeleter(deleteThread* deleter); void scanDirectory(); void readAlerts(); void processDownloadedFile(QString, QString); diff --git a/src/deleteThread.h b/src/deleteThread.h index f340bc37d..11dbbbd84 100644 --- a/src/deleteThread.h +++ b/src/deleteThread.h @@ -23,31 +23,121 @@ #define DELETETHREAD_H #include +#include +#include +#include #include "misc.h" -class deleteThread : public QThread { +class subDeleteThread : public QThread { Q_OBJECT - private: QString path; + bool abort; - public : - deleteThread(QString _path): path(_path){ - start(); + public: + subDeleteThread(QObject *parent, QString path) : QThread(parent), path(path){ + abort = false; } - ~deleteThread(){ + ~subDeleteThread(){ + abort = true; wait(); } signals: - void deletionFinished(deleteThread*) const; + // For subthreads + void deletionSuccessST(subDeleteThread* st, QString path); + void deletionFailureST(subDeleteThread* st, QString path); + + protected: + void run(){ + if(misc::removePath(path)) + emit deletionSuccessST(this, path); + else + emit deletionFailureST(this, path); + qDebug("deletion completed for %s", (const char*)path.toUtf8()); + } +}; + +class deleteThread : public QThread { + Q_OBJECT private: + QStringList path_list; + QMutex mutex; + QWaitCondition condition; + bool abort; + QList subThreads; + + signals: + void deletionSuccess(QString path); + void deletionFailure(QString path); + + public: + deleteThread(QObject* parent) : QThread(parent){ + abort = false; + } + + ~deleteThread(){ + mutex.lock(); + abort = true; + condition.wakeOne(); + mutex.unlock(); + subDeleteThread *st; + foreach(st, subThreads){ + delete st; + } + wait(); + } + + void deletePath(QString path){ + QMutexLocker locker(&mutex); + path_list << path; + if(!isRunning()){ + start(); + }else{ + condition.wakeOne(); + } + } + + protected: void run(){ - misc::removePath(path); - emit deletionFinished(this); + forever{ + if(abort) + return; + mutex.lock(); + if(path_list.size() != 0){ + QString path = path_list.takeFirst(); + mutex.unlock(); + subDeleteThread *st = new subDeleteThread(0, path); + subThreads << st; + connect(st, SIGNAL(deletionSuccessST(subDownloadThread*, QString, QString)), this, SLOT(propagateDeletionSuccess(subDeleteThread*, QString))); + connect(st, SIGNAL(deletionFailureST(subDownloadThread*, QString, QString)), this, SLOT(propagateDeletionFailure(subDeleteThread*, QString))); + st->start(); + }else{ + condition.wait(&mutex); + mutex.unlock(); + } + } + } + protected slots: + void propagateDeletionSuccess(subDeleteThread* st, QString path){ + int index = subThreads.indexOf(st); + Q_ASSERT(index != -1); + subThreads.removeAt(index); + delete st; + emit deletionSuccess(path); + qDebug("%s was successfully deleted", (const char*)path.toUtf8()); + } + + void propagateDeletionFailure(subDeleteThread* st, QString path){ + int index = subThreads.indexOf(st); + Q_ASSERT(index != -1); + subThreads.removeAt(index); + delete st; + emit deletionFailure(path); + std::cerr << "Could not delete path: " << (const char*)path.toUtf8() << ". Check if qBittorrent has the required rights.\n"; } }; diff --git a/src/downloadThread.h b/src/downloadThread.h index cab40c997..bb910d241 100644 --- a/src/downloadThread.h +++ b/src/downloadThread.h @@ -194,20 +194,16 @@ class downloadThread : public QThread { protected slots: void propagateDownloadedFile(subDownloadThread* st, QString url, QString path){ int index = subThreads.indexOf(st); - if(index == -1) - std::cerr << "ERROR: Couldn't delete download subThread!\n"; - else - subThreads.takeAt(index); + Q_ASSERT(index != -1); + subThreads.removeAt(index); delete st; emit downloadFinished(url, path); } void propagateDownloadFailure(subDownloadThread* st, QString url, QString reason){ int index = subThreads.indexOf(st); - if(index == -1) - std::cerr << "ERROR: Couldn't delete download subThread!\n"; - else - subThreads.takeAt(index); + Q_ASSERT(index != -1); + subThreads.removeAt(index); delete st; emit downloadFailure(url, reason); }