From 5257dc88d6c2fdc5e543acc384994f60ccd9a2b6 Mon Sep 17 00:00:00 2001 From: Igor Kushnir Date: Wed, 3 Feb 2021 21:32:44 +0200 Subject: [PATCH 1/2] Library: destroy the temporary thread when deleting finishes finished() signal of both FoldersRemover and ComicsRemover was not connected to their QThread's quit() slot. So the thread kept running after the deletion completed. The QThread's parent is LibraryWindow. Thus LibraryWindow's ~QObject() invokes the QThread's destructor. As a result, when the user exited YACReader Library after deleting at least one folder or comic, it printed the following FATAL message and crashed at exit: "QThread: Destroyed while thread is still running". Extract signal-slot connections between a remover and a QThread into moveAndConnectRemoverToThread() to reduce code duplication. Remove always true (thread != NULL) checks. --- YACReaderLibrary/library_window.cpp | 41 ++++++++++++++--------------- 1 file changed, 20 insertions(+), 21 deletions(-) diff --git a/YACReaderLibrary/library_window.cpp b/YACReaderLibrary/library_window.cpp index b3edb761..4cdc4b83 100644 --- a/YACReaderLibrary/library_window.cpp +++ b/YACReaderLibrary/library_window.cpp @@ -91,6 +91,20 @@ #include #endif +namespace { +template +void moveAndConnectRemoverToThread(Remover *remover, QThread *thread) +{ + Q_ASSERT(remover); + Q_ASSERT(thread); + remover->moveToThread(thread); + QObject::connect(thread, &QThread::started, remover, &Remover::process); + QObject::connect(remover, &Remover::finished, remover, &QObject::deleteLater); + QObject::connect(remover, &Remover::finished, thread, &QThread::quit); + QObject::connect(thread, &QThread::finished, thread, &QObject::deleteLater); +} +} + using namespace YACReader; LibraryWindow::LibraryWindow() @@ -1535,22 +1549,14 @@ void LibraryWindow::deleteSelectedFolder() paths << folderPath; auto remover = new FoldersRemover(indexList, paths); + const auto thread = new QThread(this); + moveAndConnectRemoverToThread(remover, thread); - QThread *thread = NULL; - - thread = new QThread(this); - - remover->moveToThread(thread); - - connect(thread, SIGNAL(started()), remover, SLOT(process())); connect(remover, SIGNAL(remove(QModelIndex)), foldersModel, SLOT(deleteFolder(QModelIndex))); connect(remover, SIGNAL(removeError()), this, SLOT(errorDeletingFolder())); connect(remover, SIGNAL(finished()), navigationController, SLOT(reselectCurrentFolder())); - connect(remover, SIGNAL(finished()), remover, SLOT(deleteLater())); - connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater())); - if (thread != NULL) - thread->start(); + thread->start(); } } } @@ -2530,15 +2536,11 @@ void LibraryWindow::deleteComicsFromDisk() } auto remover = new ComicsRemover(indexList, paths, comics.at(0).parentId); - QThread *thread = NULL; - - thread = new QThread(this); - - remover->moveToThread(thread); + const auto thread = new QThread(this); + moveAndConnectRemoverToThread(remover, thread); comicsModel->startTransaction(); - connect(thread, SIGNAL(started()), remover, SLOT(process())); connect(remover, SIGNAL(remove(int)), comicsModel, SLOT(remove(int))); connect(remover, SIGNAL(removeError()), this, SLOT(setRemoveError())); connect(remover, SIGNAL(finished()), comicsModel, SLOT(finishTransaction())); @@ -2547,11 +2549,8 @@ void LibraryWindow::deleteComicsFromDisk() connect(remover, SIGNAL(finished()), this, SLOT(checkEmptyFolder())); connect(remover, SIGNAL(finished()), this, SLOT(checkRemoveError())); - connect(remover, SIGNAL(finished()), remover, SLOT(deleteLater())); - connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater())); - if (thread != NULL) - thread->start(); + thread->start(); } } From aa9dd95d5df1071016ed64753d9d19c5ac916f6f Mon Sep 17 00:00:00 2001 From: Igor Kushnir Date: Thu, 4 Feb 2021 20:31:26 +0200 Subject: [PATCH 2/2] LibraryWindow: remove a duplicate signal-slot connection QSqlDatabase::commit() in ComicModel::finishTransaction() returned false (failed) when this slot was invoked the second time in a row. --- YACReaderLibrary/library_window.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/YACReaderLibrary/library_window.cpp b/YACReaderLibrary/library_window.cpp index 4cdc4b83..f74d2b27 100644 --- a/YACReaderLibrary/library_window.cpp +++ b/YACReaderLibrary/library_window.cpp @@ -2544,7 +2544,6 @@ void LibraryWindow::deleteComicsFromDisk() connect(remover, SIGNAL(remove(int)), comicsModel, SLOT(remove(int))); connect(remover, SIGNAL(removeError()), this, SLOT(setRemoveError())); connect(remover, SIGNAL(finished()), comicsModel, SLOT(finishTransaction())); - connect(remover, SIGNAL(finished()), comicsModel, SLOT(finishTransaction())); connect(remover, SIGNAL(removedItemsFromFolder(qulonglong)), foldersModel, SLOT(updateFolderChildrenInfo(qulonglong))); connect(remover, SIGNAL(finished()), this, SLOT(checkEmptyFolder()));