diff --git a/lib/thumbnailprovider/thumbnailgenerator.h b/lib/thumbnailprovider/thumbnailgenerator.h --- a/lib/thumbnailprovider/thumbnailgenerator.h +++ b/lib/thumbnailprovider/thumbnailgenerator.h @@ -51,6 +51,10 @@ public: ThumbnailGenerator(); + // Because we override run(), like you're not really supposed to do, we + // can't trust isRunning() + bool isStopped(); + void load( const QString& originalUri, time_t originalTime, @@ -89,6 +93,7 @@ QWaitCondition mCond; ThumbnailGroup::Enum mThumbnailGroup; bool mCancel; + bool mStopped = false; }; } // namespace diff --git a/lib/thumbnailprovider/thumbnailgenerator.cpp b/lib/thumbnailprovider/thumbnailgenerator.cpp --- a/lib/thumbnailprovider/thumbnailgenerator.cpp +++ b/lib/thumbnailprovider/thumbnailgenerator.cpp @@ -36,6 +36,7 @@ #include #include #include +#include namespace Gwenview { @@ -178,7 +179,12 @@ //------------------------------------------------------------------------ ThumbnailGenerator::ThumbnailGenerator() : mCancel(false) -{} +{ + connect(qApp, &QCoreApplication::aboutToQuit, this, [=]() { + wait(); + }, Qt::DirectConnection); + start(); +} void ThumbnailGenerator::load( const QString& originalUri, time_t originalTime, KIO::filesize_t originalFileSize, const QString& originalMimeType, @@ -196,15 +202,20 @@ mPixPath = pixPath; mThumbnailPath = thumbnailPath; mThumbnailGroup = group; - if (!isRunning()) start(); mCond.wakeOne(); } QString ThumbnailGenerator::originalUri() const { return mOriginalUri; } +bool ThumbnailGenerator::isStopped() +{ + QMutexLocker lock(&mMutex); + return mStopped; +} + time_t ThumbnailGenerator::originalTime() const { return mOriginalTime; @@ -235,21 +246,18 @@ void ThumbnailGenerator::run() { - LOG(""); while (!testCancel()) { QString pixPath; int pixelSize; { QMutexLocker lock(&mMutex); // empty mPixPath means nothing to do - LOG("Waiting for mPixPath"); if (mPixPath.isNull()) { - LOG("mPixPath.isNull"); mCond.wait(&mMutex); } } if (testCancel()) { - return; + break; } { QMutexLocker lock(&mMutex); @@ -279,7 +287,7 @@ mPixPath.clear(); // done, ready for next } if (testCancel()) { - return; + break; } { QSize size(mOriginalWidth, mOriginalHeight); @@ -289,7 +297,12 @@ LOG("Done"); } } + LOG("Ending thread"); + + QMutexLocker lock(&mMutex); + mStopped = true; + deleteLater(); } void ThumbnailGenerator::cacheThumbnail() diff --git a/lib/thumbnailprovider/thumbnailprovider.cpp b/lib/thumbnailprovider/thumbnailprovider.cpp --- a/lib/thumbnailprovider/thumbnailprovider.cpp +++ b/lib/thumbnailprovider/thumbnailprovider.cpp @@ -175,11 +175,10 @@ ThumbnailProvider::~ThumbnailProvider() { LOG(this); - abortSubjob(); - mThumbnailGenerator->cancel(); disconnect(mThumbnailGenerator, nullptr, this, nullptr); disconnect(mThumbnailGenerator, nullptr, sThumbnailWriter, nullptr); - connect(mThumbnailGenerator, SIGNAL(finished()), mThumbnailGenerator, SLOT(deleteLater())); + abortSubjob(); + mThumbnailGenerator->cancel(); if (mPreviousThumbnailGenerator) { disconnect(mPreviousThumbnailGenerator, nullptr, sThumbnailWriter, nullptr); } @@ -193,7 +192,7 @@ // startCreatingThumbnail() will take care that these two threads won't work on the same item. mItems.clear(); abortSubjob(); - if (mThumbnailGenerator->isRunning() && !mPreviousThumbnailGenerator) { + if (!mThumbnailGenerator->isStopped() && !mPreviousThumbnailGenerator) { mPreviousThumbnailGenerator = mThumbnailGenerator; mPreviousThumbnailGenerator->cancel(); disconnect(mPreviousThumbnailGenerator, nullptr, this, nullptr); @@ -524,7 +523,7 @@ // connect mPreviousThumbnailGenerator's signal "finished" to determineNextIcon // which will load the thumbnail from sThumbnailWriter or from disk // (because we re-add mCurrentItem to mItems). - if (mPreviousThumbnailGenerator && mPreviousThumbnailGenerator->isRunning() && + if (mPreviousThumbnailGenerator && !mPreviousThumbnailGenerator->isStopped() && mOriginalUri == mPreviousThumbnailGenerator->originalUri() && mOriginalTime == mPreviousThumbnailGenerator->originalTime() && mOriginalFileSize == mPreviousThumbnailGenerator->originalFileSize() &&