forked from qt-creator/qt-creator
CppTools: Avoid unnecessary blocking of main thread
Among others, BaseEditorDocumentParser::projectPart() was a blocking operation in case the parser was running. This led to noticeable GUI freezes for the ClangCodeModel since the function was called from the main thread. Rework *EditorDocumentParser to clearly separate the configuration data (input) from the actual object state. Querying/setting configuration or (last) state does not block anymore. update() is supposed to get the necessary configuration and the last state at the beginning and to set the new state at end. Change-Id: Ib4b534fa6ff373c3059826726b3f10ece95acc21 Reviewed-by: Erik Verbruggen <erik.verbruggen@theqtcompany.com>
This commit is contained in:
@@ -44,15 +44,19 @@ namespace CppTools {
|
||||
It's meant to be used in the C++ editor to get precise results by using
|
||||
the "best" project part for a file.
|
||||
|
||||
Derived classes are expected to implement update() by using the protected
|
||||
mutex, determineProjectPart() and by respecting the options set by the client.
|
||||
Derived classes are expected to implement update() this way:
|
||||
|
||||
\list
|
||||
\li Get a copy of the configuration and the last state.
|
||||
\li Acquire the protected m_updateIsRunning for the duration of update().
|
||||
\li Work on the data and do whatever is necessary. At least, update
|
||||
the project part with the help of determineProjectPart().
|
||||
\li Ensure the new state is set before update() returns.
|
||||
\endlist
|
||||
*/
|
||||
|
||||
BaseEditorDocumentParser::BaseEditorDocumentParser(const QString &filePath)
|
||||
: m_mutex(QMutex::Recursive)
|
||||
, m_filePath(filePath)
|
||||
, m_usePrecompiledHeaders(false)
|
||||
, m_editorDefinesChangedSinceLastUpdate(false)
|
||||
: m_filePath(filePath)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -65,44 +69,33 @@ QString BaseEditorDocumentParser::filePath() const
|
||||
return m_filePath;
|
||||
}
|
||||
|
||||
BaseEditorDocumentParser::Configuration BaseEditorDocumentParser::configuration() const
|
||||
{
|
||||
QMutexLocker locker(&m_stateAndConfigurationMutex);
|
||||
return m_configuration;
|
||||
}
|
||||
|
||||
void BaseEditorDocumentParser::setConfiguration(const Configuration &configuration)
|
||||
{
|
||||
QMutexLocker locker(&m_stateAndConfigurationMutex);
|
||||
m_configuration = configuration;
|
||||
}
|
||||
|
||||
BaseEditorDocumentParser::State BaseEditorDocumentParser::state() const
|
||||
{
|
||||
QMutexLocker locker(&m_stateAndConfigurationMutex);
|
||||
return m_state;
|
||||
}
|
||||
|
||||
void BaseEditorDocumentParser::setState(const State &state)
|
||||
{
|
||||
QMutexLocker locker(&m_stateAndConfigurationMutex);
|
||||
m_state = state;
|
||||
}
|
||||
|
||||
ProjectPart::Ptr BaseEditorDocumentParser::projectPart() const
|
||||
{
|
||||
QMutexLocker locker(&m_mutex);
|
||||
return m_projectPart;
|
||||
}
|
||||
|
||||
void BaseEditorDocumentParser::setProjectPart(ProjectPart::Ptr projectPart)
|
||||
{
|
||||
QMutexLocker locker(&m_mutex);
|
||||
m_manuallySetProjectPart = projectPart;
|
||||
}
|
||||
|
||||
bool BaseEditorDocumentParser::usePrecompiledHeaders() const
|
||||
{
|
||||
QMutexLocker locker(&m_mutex);
|
||||
return m_usePrecompiledHeaders;
|
||||
}
|
||||
|
||||
void BaseEditorDocumentParser::setUsePrecompiledHeaders(bool usePrecompiledHeaders)
|
||||
{
|
||||
QMutexLocker locker(&m_mutex);
|
||||
m_usePrecompiledHeaders = usePrecompiledHeaders;
|
||||
}
|
||||
|
||||
QByteArray BaseEditorDocumentParser::editorDefines() const
|
||||
{
|
||||
QMutexLocker locker(&m_mutex);
|
||||
return m_editorDefines;
|
||||
}
|
||||
|
||||
void BaseEditorDocumentParser::setEditorDefines(const QByteArray &editorDefines)
|
||||
{
|
||||
QMutexLocker locker(&m_mutex);
|
||||
|
||||
if (editorDefines != m_editorDefines) {
|
||||
m_editorDefines = editorDefines;
|
||||
m_editorDefinesChangedSinceLastUpdate = true;
|
||||
}
|
||||
return state().projectPart;
|
||||
}
|
||||
|
||||
BaseEditorDocumentParser *BaseEditorDocumentParser::get(const QString &filePath)
|
||||
@@ -115,15 +108,17 @@ BaseEditorDocumentParser *BaseEditorDocumentParser::get(const QString &filePath)
|
||||
return 0;
|
||||
}
|
||||
|
||||
ProjectPart::Ptr BaseEditorDocumentParser::determineProjectPart() const
|
||||
ProjectPart::Ptr BaseEditorDocumentParser::determineProjectPart(const QString &filePath,
|
||||
const Configuration &config,
|
||||
const State &state)
|
||||
{
|
||||
if (m_manuallySetProjectPart)
|
||||
return m_manuallySetProjectPart;
|
||||
if (config.manuallySetProjectPart)
|
||||
return config.manuallySetProjectPart;
|
||||
|
||||
ProjectPart::Ptr projectPart = m_projectPart;
|
||||
ProjectPart::Ptr projectPart = state.projectPart;
|
||||
|
||||
CppModelManager *cmm = CppModelManager::instance();
|
||||
QList<ProjectPart::Ptr> projectParts = cmm->projectPart(m_filePath);
|
||||
QList<ProjectPart::Ptr> projectParts = cmm->projectPart(filePath);
|
||||
if (projectParts.isEmpty()) {
|
||||
if (projectPart)
|
||||
// File is not directly part of any project, but we got one before. We will re-use it,
|
||||
@@ -131,7 +126,7 @@ ProjectPart::Ptr BaseEditorDocumentParser::determineProjectPart() const
|
||||
return projectPart;
|
||||
|
||||
// Fall-back step 1: Get some parts through the dependency table:
|
||||
projectParts = cmm->projectPartFromDependencies(Utils::FileName::fromString(m_filePath));
|
||||
projectParts = cmm->projectPartFromDependencies(Utils::FileName::fromString(filePath));
|
||||
if (projectParts.isEmpty())
|
||||
// Fall-back step 2: Use fall-back part from the model manager:
|
||||
projectPart = cmm->fallbackProjectPart();
|
||||
@@ -146,14 +141,4 @@ ProjectPart::Ptr BaseEditorDocumentParser::determineProjectPart() const
|
||||
return projectPart;
|
||||
}
|
||||
|
||||
bool BaseEditorDocumentParser::editorDefinesChanged() const
|
||||
{
|
||||
return m_editorDefinesChangedSinceLastUpdate;
|
||||
}
|
||||
|
||||
void BaseEditorDocumentParser::resetEditorDefinesChanged()
|
||||
{
|
||||
m_editorDefinesChangedSinceLastUpdate = false;
|
||||
}
|
||||
|
||||
} // namespace CppTools
|
||||
|
||||
Reference in New Issue
Block a user