From cd868e8a7bd098dcaee0262308079036312fe53c Mon Sep 17 00:00:00 2001 From: Marco Bubke Date: Thu, 24 Jan 2019 15:01:30 +0100 Subject: [PATCH] Clang: Fix crash on exit There were threads running but the instances they called were already deleted. Now we delete the scheduler first which is the thread holder and which is waiting that all threads are finished. Task-number: QTCREATORBUG-21882 Change-Id: I2e9f4d8381d79fab9a93346cef6598ab8e8f7850 Reviewed-by: Ivan Donchevskii --- .../clangpchmanagerbackendmain.cpp | 20 +++++++++---------- .../source/taskscheduler.h | 5 +++++ .../clangrefactoringbackendmain.cpp | 2 +- .../source/symbolindexing.h | 4 ++-- tests/unit/unittest/symbolindexer-test.cpp | 12 +++++------ 5 files changed, 24 insertions(+), 19 deletions(-) diff --git a/src/tools/clangpchmanagerbackend/clangpchmanagerbackendmain.cpp b/src/tools/clangpchmanagerbackend/clangpchmanagerbackendmain.cpp index 3656ebd9dc5..5c38a3d8413 100644 --- a/src/tools/clangpchmanagerbackend/clangpchmanagerbackendmain.cpp +++ b/src/tools/clangpchmanagerbackend/clangpchmanagerbackendmain.cpp @@ -183,16 +183,6 @@ struct Data // because we have a cycle dependency PrecompiledHeaderStorage<> preCompiledHeaderStorage{database}; ClangBackEnd::ProgressCounter progressCounter{ [&](int progress, int total) { clangPchManagerServer.setProgress(progress, total); }}; - TaskScheduler systemTaskScheduler{pchCreatorManager, - pchTaskQueue, - progressCounter, - std::thread::hardware_concurrency(), - ClangBackEnd::CallDoInMainThreadAfterFinished::No}; - TaskScheduler projectTaskScheduler{pchCreatorManager, - pchTaskQueue, - progressCounter, - std::thread::hardware_concurrency(), - ClangBackEnd::CallDoInMainThreadAfterFinished::Yes}; ClangBackEnd::PchTaskQueue pchTaskQueue{systemTaskScheduler, projectTaskScheduler, progressCounter, @@ -212,6 +202,16 @@ struct Data // because we have a cycle dependency database}; ClangBackEnd::PchTaskGenerator pchTaskGenerator{buildDependencyProvider, pchTaskMerger}; PchManagerServer clangPchManagerServer{includeWatcher, pchTaskGenerator, projectParts, generatedFiles}; + TaskScheduler systemTaskScheduler{pchCreatorManager, + pchTaskQueue, + progressCounter, + std::thread::hardware_concurrency(), + ClangBackEnd::CallDoInMainThreadAfterFinished::No}; + TaskScheduler projectTaskScheduler{pchCreatorManager, + pchTaskQueue, + progressCounter, + std::thread::hardware_concurrency(), + ClangBackEnd::CallDoInMainThreadAfterFinished::Yes}; }; int main(int argc, char *argv[]) diff --git a/src/tools/clangpchmanagerbackend/source/taskscheduler.h b/src/tools/clangpchmanagerbackend/source/taskscheduler.h index 621baef0909..37fdc744a84 100644 --- a/src/tools/clangpchmanagerbackend/source/taskscheduler.h +++ b/src/tools/clangpchmanagerbackend/source/taskscheduler.h @@ -80,6 +80,11 @@ public: , m_callDoInMainThreadAfterFinished(callDoInMainThreadAfterFinished) {} + ~TaskScheduler() + { + syncTasks(); + } + void addTasks(std::vector &&tasks) { for (auto &task : tasks) { diff --git a/src/tools/clangrefactoringbackend/clangrefactoringbackendmain.cpp b/src/tools/clangrefactoringbackend/clangrefactoringbackendmain.cpp index 07e594b7217..0d483bbeaf1 100644 --- a/src/tools/clangrefactoringbackend/clangrefactoringbackendmain.cpp +++ b/src/tools/clangrefactoringbackend/clangrefactoringbackendmain.cpp @@ -93,8 +93,8 @@ struct Data // because we have a cycle dependency RefactoringDatabaseInitializer databaseInitializer{database}; FilePathCaching filePathCache{database}; GeneratedFiles generatedFiles; - SymbolIndexing symbolIndexing{database, filePathCache, generatedFiles, [&] (int progress, int total) { clangCodeModelServer.setProgress(progress, total); }}; RefactoringServer clangCodeModelServer{symbolIndexing, filePathCache, generatedFiles}; + SymbolIndexing symbolIndexing{database, filePathCache, generatedFiles, [&] (int progress, int total) { clangCodeModelServer.setProgress(progress, total); }}; }; int main(int argc, char *argv[]) diff --git a/src/tools/clangrefactoringbackend/source/symbolindexing.h b/src/tools/clangrefactoringbackend/source/symbolindexing.h index 6f52f863d85..62be193682c 100644 --- a/src/tools/clangrefactoringbackend/source/symbolindexing.h +++ b/src/tools/clangrefactoringbackend/source/symbolindexing.h @@ -124,8 +124,6 @@ private: FileStatusCache m_fileStatusCache{m_filePathCache}; SymbolsCollectorManager m_collectorManger; ProgressCounter m_progressCounter; - SymbolIndexerTaskScheduler m_indexerScheduler; - SymbolIndexerTaskQueue m_indexerQueue{m_indexerScheduler, m_progressCounter}; SymbolIndexer m_indexer{m_indexerQueue, m_symbolStorage, m_buildDependencyStorage, @@ -133,6 +131,8 @@ private: m_filePathCache, m_fileStatusCache, m_symbolStorage.m_database}; + SymbolIndexerTaskQueue m_indexerQueue{m_indexerScheduler, m_progressCounter}; + SymbolIndexerTaskScheduler m_indexerScheduler; }; } // namespace ClangBackEnd diff --git a/tests/unit/unittest/symbolindexer-test.cpp b/tests/unit/unittest/symbolindexer-test.cpp index 23f469cd340..4f112d45298 100644 --- a/tests/unit/unittest/symbolindexer-test.cpp +++ b/tests/unit/unittest/symbolindexer-test.cpp @@ -241,12 +241,6 @@ protected: Manager collectorManger{generatedFiles}; NiceMock> mockSetProgressCallback; ClangBackEnd::ProgressCounter progressCounter{mockSetProgressCallback.AsStdFunction()}; - Scheduler indexerScheduler{collectorManger, - indexerQueue, - progressCounter, - 1, - ClangBackEnd::CallDoInMainThreadAfterFinished::Yes}; - SymbolIndexerTaskQueue indexerQueue{indexerScheduler, progressCounter}; ClangBackEnd::SymbolIndexer indexer{indexerQueue, mockSymbolStorage, mockBuildDependenciesStorage, @@ -254,6 +248,12 @@ protected: filePathCache, fileStatusCache, mockSqliteTransactionBackend}; + SymbolIndexerTaskQueue indexerQueue{indexerScheduler, progressCounter}; + Scheduler indexerScheduler{collectorManger, + indexerQueue, + progressCounter, + 1, + ClangBackEnd::CallDoInMainThreadAfterFinished::Yes}; MockSymbolsCollector &mockCollector{static_cast(collectorManger.unusedProcessor())}; };