From 06c7a4e159ababbe8f6de82d53bad28027ea7703 Mon Sep 17 00:00:00 2001 From: Eberhard Graether Date: Thu, 20 Oct 2016 23:02:54 +0200 Subject: [PATCH] logic: Fixed bugs in TaskParse scheduling * Added TaskParse as base for TaskParseCxx and TaskParseJava * Fixed increment and decrement of indexer_count on blackboard not atomic * Fixed TaskInjectStorage finished before TaskParse started * Fixed project not cleared when refreshing on now empty project * Fixed TaskInjectStorage overheating when nothing to do --- src/lib/CMakeLists.txt | 7 +-- src/lib/Project.cpp | 12 ++--- src/lib/data/TaskInjectStorage.cpp | 26 +++++++++- src/lib/data/TaskInjectStorage.h | 2 + src/lib/data/parser/TaskParse.cpp | 50 +++++++++++++++++++ src/lib/data/parser/TaskParse.h | 42 ++++++++++++++++ src/lib/utility/scheduling/Blackboard.cpp | 5 ++ src/lib/utility/scheduling/Blackboard.h | 4 ++ src/lib_cxx/data/parser/cxx/TaskParseCxx.cpp | 35 ++----------- src/lib_cxx/data/parser/cxx/TaskParseCxx.h | 28 ++--------- .../data/parser/java/TaskParseJava.cpp | 38 +------------- src/lib_java/data/parser/java/TaskParseJava.h | 26 +--------- 12 files changed, 147 insertions(+), 128 deletions(-) create mode 100644 src/lib/data/parser/TaskParse.cpp create mode 100644 src/lib/data/parser/TaskParse.h diff --git a/src/lib/CMakeLists.txt b/src/lib/CMakeLists.txt index f5a41c2d..18162064 100644 --- a/src/lib/CMakeLists.txt +++ b/src/lib/CMakeLists.txt @@ -135,9 +135,6 @@ add_files( data/name/NameHierarchy.cpp data/name/NameHierarchy.h - data/parser/TaskParseWrapper.cpp - data/parser/TaskParseWrapper.h - data/parser/AccessKind.cpp data/parser/AccessKind.h data/parser/ParseLocation.cpp @@ -152,6 +149,10 @@ add_files( data/parser/ReferenceKind.h data/parser/SymbolKind.cpp data/parser/SymbolKind.h + data/parser/TaskParse.cpp + data/parser/TaskParse.h + data/parser/TaskParseWrapper.cpp + data/parser/TaskParseWrapper.h data/search/SearchIndex.cpp data/search/SearchIndex.h diff --git a/src/lib/Project.cpp b/src/lib/Project.cpp index 122330d9..001fd1f7 100644 --- a/src/lib/Project.cpp +++ b/src/lib/Project.cpp @@ -245,9 +245,9 @@ bool Project::buildIndex(bool forceRefresh) return false; } - m_fileManager.fetchFilePaths( - forceRefresh ? std::vector() : m_storage->getInfoOnAllFiles() - ); + std::vector fileInfos = m_storage->getInfoOnAllFiles(); + + m_fileManager.fetchFilePaths(forceRefresh ? std::vector() : fileInfos); std::set addedFilePaths = m_fileManager.getAddedFilePaths(); std::set updatedFilePaths = m_fileManager.getUpdatedFilePaths(); @@ -279,7 +279,7 @@ bool Project::buildIndex(bool forceRefresh) utility::append(filesToParse, addedFilePaths); utility::append(filesToParse, updatedFilePaths); - if (!filesToClean.size() && !filesToParse.size()) + if (!filesToClean.size() && !filesToParse.size() && (!forceRefresh || !fileInfos.size())) { MessageStatus("Nothing to refresh, all files are up-to-date.").dispatch(); return false; @@ -315,7 +315,7 @@ bool Project::buildIndex(bool forceRefresh) ); } - const int indexerThreadCount = ApplicationSettings::getInstance()->getIndexerThreadCount(); + const size_t indexerThreadCount = ApplicationSettings::getInstance()->getIndexerThreadCount(); std::shared_ptr fileRegister = std::make_shared(&m_fileManager, indexerThreadCount > 1); @@ -334,7 +334,7 @@ bool Project::buildIndex(bool forceRefresh) std::shared_ptr storageProvider = std::make_shared(); - for (int i = 0; i < indexerThreadCount; i++) + for (size_t i = 0; i < indexerThreadCount && i < filesToParse.size(); i++) { std::shared_ptr taskRepeat = std::make_shared(Task::STATE_SUCCESS); taskParallelIndexing->addTask(taskRepeat); diff --git a/src/lib/data/TaskInjectStorage.cpp b/src/lib/data/TaskInjectStorage.cpp index f508d3de..f538bb0a 100644 --- a/src/lib/data/TaskInjectStorage.cpp +++ b/src/lib/data/TaskInjectStorage.cpp @@ -1,5 +1,8 @@ #include "data/TaskInjectStorage.h" +#include +#include + #include "data/Storage.h" #include "data/StorageProvider.h" #include "utility/scheduling/Blackboard.h" @@ -10,11 +13,26 @@ TaskInjectStorage::TaskInjectStorage( ) : m_storageProvider(storageProvider) , m_target(target) + , m_hasInjected(false) { } void TaskInjectStorage::doEnter(std::shared_ptr blackboard) { + while (!m_hasInjected) + { + int indexerCount = 0; + if (blackboard->get("indexer_count", indexerCount)) + { + if (indexerCount > 0 || m_storageProvider->getStorageCount() > 0) + { + break; + } + } + + const int SLEEP_TIME_MS = 25; + std::this_thread::sleep_for(std::chrono::milliseconds(SLEEP_TIME_MS)); + } } Task::TaskState TaskInjectStorage::doUpdate(std::shared_ptr blackboard) @@ -25,14 +43,20 @@ Task::TaskState TaskInjectStorage::doUpdate(std::shared_ptr blackboa if (source) { m_target->inject(source.get()); + m_hasInjected = true; return STATE_SUCCESS; } } + else + { + const int SLEEP_TIME_MS = 25; + std::this_thread::sleep_for(std::chrono::milliseconds(SLEEP_TIME_MS)); + } int indexerCount = 0; if (blackboard->get("indexer_count", indexerCount)) { - if (indexerCount > 0) + if (indexerCount > 0 || m_storageProvider->getStorageCount() > 0) { return STATE_SUCCESS; } diff --git a/src/lib/data/TaskInjectStorage.h b/src/lib/data/TaskInjectStorage.h index 0f4bf413..a7898bc6 100644 --- a/src/lib/data/TaskInjectStorage.h +++ b/src/lib/data/TaskInjectStorage.h @@ -25,6 +25,8 @@ private: std::shared_ptr m_storageProvider; std::shared_ptr m_target; + + bool m_hasInjected; }; #endif // TASK_INJECT_STORAGE_H diff --git a/src/lib/data/parser/TaskParse.cpp b/src/lib/data/parser/TaskParse.cpp new file mode 100644 index 00000000..7dbd841b --- /dev/null +++ b/src/lib/data/parser/TaskParse.cpp @@ -0,0 +1,50 @@ +#include "data/parser/TaskParse.h" + +#include "utility/scheduling/Blackboard.h" + +TaskParse::TaskParse( + std::shared_ptr storageProvider, + std::shared_ptr fileRegister, + const Parser::Arguments& arguments, + DialogView* dialogView +) + : m_storageProvider(storageProvider) + , m_fileRegister(fileRegister) + , m_arguments(arguments) + , m_dialogView(dialogView) + , m_interrupted(false) +{ +} + +void TaskParse::doEnter(std::shared_ptr blackboard) +{ + std::lock_guard lock(blackboard->getMutex()); + + int indexerCount = 0; + if (blackboard->get("indexer_count", indexerCount)) + { + indexerCount++; + blackboard->set("indexer_count", indexerCount); + } +} + +void TaskParse::doExit(std::shared_ptr blackboard) +{ + std::lock_guard lock(blackboard->getMutex()); + + int indexerCount = 0; + if (blackboard->get("indexer_count", indexerCount)) + { + indexerCount--; + blackboard->set("indexer_count", indexerCount); + } +} + +void TaskParse::doReset(std::shared_ptr blackboard) +{ +} + +void TaskParse::handleMessage(MessageInterruptTasks* message) +{ + m_interrupted = true; +} diff --git a/src/lib/data/parser/TaskParse.h b/src/lib/data/parser/TaskParse.h new file mode 100644 index 00000000..02d9ea6d --- /dev/null +++ b/src/lib/data/parser/TaskParse.h @@ -0,0 +1,42 @@ +#ifndef TASK_PARSE_H +#define TASK_PARSE_H + +#include "data/parser/Parser.h" +#include "utility/scheduling/Task.h" +#include "utility/messaging/type/MessageInterruptTasks.h" +#include "utility/messaging/MessageListener.h" + +class CxxParser; +class DialogView; +class FileRegister; +class StorageProvider; + +class TaskParse + : public Task + , public MessageListener +{ +public: + TaskParse( + std::shared_ptr storageProvider, + std::shared_ptr fileRegister, + const Parser::Arguments& arguments, + DialogView* dialogView + ); + +protected: + virtual void doEnter(std::shared_ptr blackboard); + virtual void doExit(std::shared_ptr blackboard); + virtual void doReset(std::shared_ptr blackboard); + + virtual void handleMessage(MessageInterruptTasks* message); + + std::shared_ptr m_storageProvider; + std::shared_ptr m_fileRegister; + + const Parser::Arguments m_arguments; + DialogView* m_dialogView; + + bool m_interrupted; +}; + +#endif // TASK_PARSE_H diff --git a/src/lib/utility/scheduling/Blackboard.cpp b/src/lib/utility/scheduling/Blackboard.cpp index 319965de..41105527 100644 --- a/src/lib/utility/scheduling/Blackboard.cpp +++ b/src/lib/utility/scheduling/Blackboard.cpp @@ -13,6 +13,11 @@ Blackboard::~Blackboard() { } +std::mutex& Blackboard::getMutex() +{ + return m_mutex; +} + bool Blackboard::exists(const std::string& key) { std::lock_guard lock(m_itemMutex); diff --git a/src/lib/utility/scheduling/Blackboard.h b/src/lib/utility/scheduling/Blackboard.h index 029f4aec..900c049c 100644 --- a/src/lib/utility/scheduling/Blackboard.h +++ b/src/lib/utility/scheduling/Blackboard.h @@ -37,6 +37,8 @@ public: Blackboard(std::shared_ptr parent); ~Blackboard(); + std::mutex& getMutex(); + template void set(const std::string& key, const T& value); @@ -51,6 +53,8 @@ private: std::shared_ptr m_parent; + std::mutex m_mutex; + ItemMap m_items; std::mutex m_itemMutex; }; diff --git a/src/lib_cxx/data/parser/cxx/TaskParseCxx.cpp b/src/lib_cxx/data/parser/cxx/TaskParseCxx.cpp index 5dd10d45..6ef6e133 100644 --- a/src/lib_cxx/data/parser/cxx/TaskParseCxx.cpp +++ b/src/lib_cxx/data/parser/cxx/TaskParseCxx.cpp @@ -1,15 +1,13 @@ #include "data/parser/cxx/TaskParseCxx.h" -#include - #include "clang/Tooling/JSONCompilationDatabase.h" #include "component/view/DialogView.h" #include "data/parser/cxx/CxxParser.h" +#include "data/parser/ParserClientImpl.h" #include "data/StorageProvider.h" #include "utility/file/FileRegister.h" #include "utility/scheduling/Blackboard.h" -#include "utility/utility.h" std::vector TaskParseCxx::getSourceFilesFromCDB(const FilePath& compilationDatabasePath) { @@ -35,11 +33,8 @@ TaskParseCxx::TaskParseCxx( const Parser::Arguments& arguments, DialogView* dialogView ) - : m_storageProvider(storageProvider) - , m_arguments(arguments) - , m_dialogView(dialogView) + : TaskParse(storageProvider, fileRegister, arguments, dialogView) , m_isCDB(false) - , m_interrupted(false) { if (arguments.compilationDatabasePath.exists()) { @@ -51,12 +46,7 @@ TaskParseCxx::TaskParseCxx( void TaskParseCxx::doEnter(std::shared_ptr blackboard) { - int indexerCount = 0; - if (blackboard->get("indexer_count", indexerCount)) - { - indexerCount++; - blackboard->set("indexer_count", indexerCount); - } + TaskParse::doEnter(blackboard); if (m_isCDB) { @@ -117,22 +107,3 @@ Task::TaskState TaskParseCxx::doUpdate(std::shared_ptr blackboard) return (m_interrupted ? STATE_FAILURE : STATE_SUCCESS); } - -void TaskParseCxx::doExit(std::shared_ptr blackboard) -{ - int indexerCount = 0; - if (blackboard->get("indexer_count", indexerCount)) - { - indexerCount--; - blackboard->set("indexer_count", indexerCount); - } -} - -void TaskParseCxx::doReset(std::shared_ptr blackboard) -{ -} - -void TaskParseCxx::handleMessage(MessageInterruptTasks* message) -{ - m_interrupted = true; -} diff --git a/src/lib_cxx/data/parser/cxx/TaskParseCxx.h b/src/lib_cxx/data/parser/cxx/TaskParseCxx.h index 69a750c0..3cb4214c 100644 --- a/src/lib_cxx/data/parser/cxx/TaskParseCxx.h +++ b/src/lib_cxx/data/parser/cxx/TaskParseCxx.h @@ -1,20 +1,10 @@ #ifndef TASK_PARSE_CXX_H #define TASK_PARSE_CXX_H -#include -#include - -#include "data/parser/Parser.h" -#include "data/parser/ParserClientImpl.h" -#include "utility/scheduling/Task.h" -#include "utility/TimePoint.h" -#include "utility/messaging/type/MessageInterruptTasks.h" -#include "utility/messaging/MessageListener.h" +#include "data/parser/TaskParse.h" class CxxParser; -class DialogView; -class FileRegister; -class StorageProvider; +class ParserClientImpl; namespace clang { @@ -25,8 +15,7 @@ namespace clang } class TaskParseCxx - : public Task - , public MessageListener + : public TaskParse { public: static std::vector getSourceFilesFromCDB(const FilePath& compilationDatabasePath); @@ -41,23 +30,12 @@ public: private: virtual void doEnter(std::shared_ptr blackboard); virtual TaskState doUpdate(std::shared_ptr blackboard); - virtual void doExit(std::shared_ptr blackboard); - virtual void doReset(std::shared_ptr blackboard); - - virtual void handleMessage(MessageInterruptTasks* message); - - std::shared_ptr m_storageProvider; - - const Parser::Arguments m_arguments; - DialogView* m_dialogView; std::shared_ptr m_parser; std::shared_ptr m_parserClient; bool m_isCDB; std::shared_ptr m_cdb; - - bool m_interrupted; }; #endif // TASK_PARSE_CXX_H diff --git a/src/lib_java/data/parser/java/TaskParseJava.cpp b/src/lib_java/data/parser/java/TaskParseJava.cpp index 9e5db6c8..f7b9a066 100644 --- a/src/lib_java/data/parser/java/TaskParseJava.cpp +++ b/src/lib_java/data/parser/java/TaskParseJava.cpp @@ -5,10 +5,7 @@ #include "data/parser/ParserClientImpl.h" #include "data/StorageProvider.h" #include "utility/file/FileRegister.h" -#include "utility/messaging/type/MessageFinishedParsing.h" -#include "utility/scheduling/Blackboard.h" #include "utility/text/TextAccess.h" -#include "utility/utility.h" TaskParseJava::TaskParseJava( std::shared_ptr storageProvider, @@ -16,24 +13,10 @@ TaskParseJava::TaskParseJava( const Parser::Arguments& arguments, DialogView* dialogView ) - : m_storageProvider(storageProvider) - , m_fileRegister(fileRegister) - , m_arguments(arguments) - , m_dialogView(dialogView) - , m_interrupted(false) + : TaskParse(storageProvider, fileRegister, arguments, dialogView) { } -void TaskParseJava::doEnter(std::shared_ptr blackboard) -{ - int indexerCount = 0; - if (blackboard->get("indexer_count", indexerCount)) - { - indexerCount++; - blackboard->set("indexer_count", indexerCount); - } -} - Task::TaskState TaskParseJava::doUpdate(std::shared_ptr blackboard) { std::shared_ptr parserClient = std::make_shared(); @@ -69,22 +52,3 @@ Task::TaskState TaskParseJava::doUpdate(std::shared_ptr blackboard) return (m_interrupted ? STATE_FAILURE : STATE_SUCCESS); } - -void TaskParseJava::doExit(std::shared_ptr blackboard) -{ - int indexerCount = 0; - if (blackboard->get("indexer_count", indexerCount)) - { - indexerCount--; - blackboard->set("indexer_count", indexerCount); - } -} - -void TaskParseJava::doReset(std::shared_ptr blackboard) -{ -} - -void TaskParseJava::handleMessage(MessageInterruptTasks* message) -{ - m_interrupted = true; -} diff --git a/src/lib_java/data/parser/java/TaskParseJava.h b/src/lib_java/data/parser/java/TaskParseJava.h index 76e06b88..0a04e704 100644 --- a/src/lib_java/data/parser/java/TaskParseJava.h +++ b/src/lib_java/data/parser/java/TaskParseJava.h @@ -1,20 +1,10 @@ #ifndef TASK_PARSE_JAVA_H #define TASK_PARSE_JAVA_H -#include - -#include "data/parser/Parser.h" -#include "utility/scheduling/Task.h" -#include "utility/messaging/type/MessageInterruptTasks.h" -#include "utility/messaging/MessageListener.h" - -class DialogView; -class FileRegister; -class StorageProvider; +#include "data/parser/TaskParse.h" class TaskParseJava - : public Task - , public MessageListener + : public TaskParse { public: TaskParseJava( @@ -25,19 +15,7 @@ public: ); private: - virtual void doEnter(std::shared_ptr blackboard); virtual TaskState doUpdate(std::shared_ptr blackboard); - virtual void doExit(std::shared_ptr blackboard); - virtual void doReset(std::shared_ptr blackboard); - - virtual void handleMessage(MessageInterruptTasks* message); - - std::shared_ptr m_storageProvider; - std::shared_ptr m_fileRegister; - Parser::Arguments m_arguments; - DialogView* m_dialogView; - - bool m_interrupted; }; #endif // TASK_PARSE_JAVA_H