C++: release more futures.

The CPPEditorWidget retained two futures, as did the attached future
watchers retained them too. Together, each future and the watcher held
on to a complete snapshot that would only get released when another
future was set. This could result into retaining old snapshots in
editors that were invisible/unused for long.

Change-Id: I1133e857c620437b4a69b9dad468f6bd458304b8
Reviewed-by: Erik Verbruggen <erik.verbruggen@digia.com>
This commit is contained in:
Erik Verbruggen
2013-12-11 15:19:54 +01:00
committed by Eike Ziller
parent 4089012735
commit 58af02f074
4 changed files with 72 additions and 70 deletions

View File

@@ -549,19 +549,14 @@ void CPPEditorWidget::ctor()
this, SLOT(onDocumentUpdated())); this, SLOT(onDocumentUpdated()));
connect(editorSupport, SIGNAL(semanticInfoUpdated(CppTools::SemanticInfo)), connect(editorSupport, SIGNAL(semanticInfoUpdated(CppTools::SemanticInfo)),
this, SLOT(updateSemanticInfo(CppTools::SemanticInfo))); this, SLOT(updateSemanticInfo(CppTools::SemanticInfo)));
connect(editorSupport, SIGNAL(highlighterStarted(QFuture<TextEditor::HighlightingResult>*,uint)), connect(editorSupport, SIGNAL(highlighterStarted(QFuture<TextEditor::HighlightingResult>,uint)),
this, SLOT(highlighterStarted(QFuture<TextEditor::HighlightingResult>*,uint))); this, SLOT(highlighterStarted(QFuture<TextEditor::HighlightingResult>,uint)));
} }
m_highlightRevision = 0; m_highlightRevision = 0;
connect(&m_highlightWatcher, SIGNAL(resultsReadyAt(int,int)),
SLOT(highlightSymbolUsages(int,int)));
connect(&m_highlightWatcher, SIGNAL(finished()),
SLOT(finishHighlightSymbolUsages()));
m_referencesRevision = 0; m_referencesRevision = 0;
m_referencesCursorPosition = 0; m_referencesCursorPosition = 0;
connect(&m_referencesWatcher, SIGNAL(finished()), SLOT(markSymbolsNow()));
connect(this, SIGNAL(refactorMarkerClicked(TextEditor::RefactorMarker)), connect(this, SIGNAL(refactorMarkerClicked(TextEditor::RefactorMarker)),
this, SLOT(onRefactorMarkerClicked(TextEditor::RefactorMarker))); this, SLOT(onRefactorMarkerClicked(TextEditor::RefactorMarker)));
@@ -854,16 +849,13 @@ void CPPEditorWidget::renameUsages()
void CPPEditorWidget::markSymbolsNow() void CPPEditorWidget::markSymbolsNow()
{ {
if (m_references.isCanceled()) QTC_ASSERT(m_referencesWatcher, return);
return; if (!m_referencesWatcher->isCanceled()
else if (m_referencesCursorPosition != position()) && m_referencesCursorPosition == position()
return; && m_referencesRevision == editorRevision()) {
else if (m_referencesRevision != editorRevision())
return;
const SemanticInfo info = m_lastSemanticInfo; const SemanticInfo info = m_lastSemanticInfo;
TranslationUnit *unit = info.doc->translationUnit(); TranslationUnit *unit = info.doc->translationUnit();
const QList<int> result = m_references.result(); const QList<int> result = m_referencesWatcher->result();
QList<QTextEdit::ExtraSelection> selections; QList<QTextEdit::ExtraSelection> selections;
@@ -881,14 +873,16 @@ void CPPEditorWidget::markSymbolsNow()
cursor.setPosition(cursor.position() + len, QTextCursor::KeepAnchor); cursor.setPosition(cursor.position() + len, QTextCursor::KeepAnchor);
QTextEdit::ExtraSelection sel; QTextEdit::ExtraSelection sel;
sel.format = baseTextDocument()->fontSettings().toTextCharFormat(TextEditor::C_OCCURRENCES); sel.format = baseTextDocument()->fontSettings()
.toTextCharFormat(TextEditor::C_OCCURRENCES);
sel.cursor = cursor; sel.cursor = cursor;
selections.append(sel); selections.append(sel);
} }
setExtraSelections(CodeSemanticsSelection, selections); setExtraSelections(CodeSemanticsSelection, selections);
} }
m_referencesWatcher.reset();
}
static QList<int> lazyFindReferences(Scope *scope, QString code, Document::Ptr doc, static QList<int> lazyFindReferences(Scope *scope, QString code, Document::Ptr doc,
Snapshot snapshot) Snapshot snapshot)
@@ -951,12 +945,15 @@ void CPPEditorWidget::markSymbols(const QTextCursor &tc, const SemanticInfo &inf
CanonicalSymbol cs(this, info); CanonicalSymbol cs(this, info);
QString expression; QString expression;
if (Scope *scope = cs.getScopeAndExpression(this, info, tc, &expression)) { if (Scope *scope = cs.getScopeAndExpression(this, info, tc, &expression)) {
m_references.cancel(); if (m_referencesWatcher)
m_referencesWatcher->cancel();
m_referencesWatcher.reset(new QFutureWatcher<QList<int> >);
connect(m_referencesWatcher.data(), SIGNAL(finished()), SLOT(markSymbolsNow()));
m_referencesRevision = info.revision; m_referencesRevision = info.revision;
m_referencesCursorPosition = position(); m_referencesCursorPosition = position();
m_references = QtConcurrent::run(&lazyFindReferences, scope, expression, info.doc, m_referencesWatcher->setFuture(QtConcurrent::run(&lazyFindReferences, scope, expression,
info.snapshot); info.doc, info.snapshot));
m_referencesWatcher.setFuture(m_references);
} else { } else {
const QList<QTextEdit::ExtraSelection> selections = extraSelections(CodeSemanticsSelection); const QList<QTextEdit::ExtraSelection> selections = extraSelections(CodeSemanticsSelection);
@@ -1164,8 +1161,10 @@ void CPPEditorWidget::updateOutlineToolTip()
void CPPEditorWidget::updateUses() void CPPEditorWidget::updateUses()
{ {
if (editorRevision() != m_highlightRevision) if (m_highlightWatcher) {
m_highlighter.cancel(); m_highlightWatcher->cancel();
m_highlightWatcher.reset();
}
// Block premature semantic info calculation when editor is created. // Block premature semantic info calculation when editor is created.
if (m_modelManager && m_modelManager->cppEditorSupport(editor())->initialized()) if (m_modelManager && m_modelManager->cppEditorSupport(editor())->initialized())
@@ -1185,32 +1184,29 @@ void CPPEditorWidget::highlightSymbolUsages(int from, int to)
if (editorRevision() != m_highlightRevision) if (editorRevision() != m_highlightRevision)
return; // outdated return; // outdated
else if (m_highlighter.isCanceled()) else if (!m_highlightWatcher || m_highlightWatcher->isCanceled())
return; // aborted return; // aborted
TextEditor::SyntaxHighlighter *highlighter = baseTextDocument()->syntaxHighlighter(); TextEditor::SyntaxHighlighter *highlighter = baseTextDocument()->syntaxHighlighter();
QTC_ASSERT(highlighter, return); QTC_ASSERT(highlighter, return);
TextEditor::SemanticHighlighter::incrementalApplyExtraAdditionalFormats( TextEditor::SemanticHighlighter::incrementalApplyExtraAdditionalFormats(
highlighter, m_highlighter, from, to, m_semanticHighlightFormatMap); highlighter, m_highlightWatcher->future(), from, to, m_semanticHighlightFormatMap);
} }
void CPPEditorWidget::finishHighlightSymbolUsages() void CPPEditorWidget::finishHighlightSymbolUsages()
{ {
if (editorRevision() != m_highlightRevision) QTC_ASSERT(m_highlightWatcher, return);
return; // outdated if (!m_highlightWatcher->isCanceled()
&& editorRevision() == m_highlightRevision
if (m_highlighter.isCanceled()) && !m_lastSemanticInfo.doc.isNull()) {
return; // aborted
else if (m_lastSemanticInfo.doc.isNull())
return;
TextEditor::SyntaxHighlighter *highlighter = baseTextDocument()->syntaxHighlighter(); TextEditor::SyntaxHighlighter *highlighter = baseTextDocument()->syntaxHighlighter();
QTC_ASSERT(highlighter, return); QTC_CHECK(highlighter);
if (highlighter)
TextEditor::SemanticHighlighter::clearExtraAdditionalFormatsUntilEnd( TextEditor::SemanticHighlighter::clearExtraAdditionalFormatsUntilEnd(highlighter,
highlighter, m_highlighter); m_highlightWatcher->future());
}
m_highlightWatcher.reset();
} }
void CPPEditorWidget::switchDeclarationDefinition(bool inNextSplit) void CPPEditorWidget::switchDeclarationDefinition(bool inNextSplit)
@@ -1612,12 +1608,18 @@ void CPPEditorWidget::semanticRehighlight(bool force)
m_modelManager->cppEditorSupport(editor())->recalculateSemanticInfoDetached(force); m_modelManager->cppEditorSupport(editor())->recalculateSemanticInfoDetached(force);
} }
void CPPEditorWidget::highlighterStarted(QFuture<TextEditor::HighlightingResult> *highlighter, void CPPEditorWidget::highlighterStarted(QFuture<TextEditor::HighlightingResult> highlighter,
unsigned revision) unsigned revision)
{ {
m_highlighter = *highlighter;
m_highlightRevision = revision; m_highlightRevision = revision;
m_highlightWatcher.setFuture(m_highlighter);
m_highlightWatcher.reset(new QFutureWatcher<TextEditor::HighlightingResult>);
connect(m_highlightWatcher.data(), SIGNAL(resultsReadyAt(int,int)),
SLOT(highlightSymbolUsages(int,int)));
connect(m_highlightWatcher.data(), SIGNAL(finished()),
SLOT(finishHighlightSymbolUsages()));
m_highlightWatcher->setFuture(highlighter);
} }
void CPPEditorWidget::updateSemanticInfo(const SemanticInfo &semanticInfo) void CPPEditorWidget::updateSemanticInfo(const SemanticInfo &semanticInfo)

View File

@@ -144,10 +144,10 @@ public:
FollowSymbolUnderCursor *followSymbolUnderCursorDelegate(); // exposed for tests FollowSymbolUnderCursor *followSymbolUnderCursorDelegate(); // exposed for tests
Q_SIGNALS: signals:
void outlineModelIndexChanged(const QModelIndex &index); void outlineModelIndexChanged(const QModelIndex &index);
public Q_SLOTS: public slots:
void setSortedOutline(bool sort); void setSortedOutline(bool sort);
void switchDeclarationDefinition(bool inNextSplit); void switchDeclarationDefinition(bool inNextSplit);
void renameSymbolUnderCursor(); void renameSymbolUnderCursor();
@@ -156,7 +156,7 @@ public Q_SLOTS:
void showPreProcessorWidget(); void showPreProcessorWidget();
void renameUsagesNow(const QString &replacement = QString()); void renameUsagesNow(const QString &replacement = QString());
void semanticRehighlight(bool force = false); void semanticRehighlight(bool force = false);
void highlighterStarted(QFuture<TextEditor::HighlightingResult> *highlighter, void highlighterStarted(QFuture<TextEditor::HighlightingResult> highlighter,
unsigned revision); unsigned revision);
protected: protected:
@@ -169,10 +169,10 @@ protected:
const CPlusPlus::Macro *findCanonicalMacro(const QTextCursor &cursor, const CPlusPlus::Macro *findCanonicalMacro(const QTextCursor &cursor,
CPlusPlus::Document::Ptr doc) const; CPlusPlus::Document::Ptr doc) const;
protected Q_SLOTS: protected slots:
void slotCodeStyleSettingsChanged(const QVariant &); void slotCodeStyleSettingsChanged(const QVariant &);
private Q_SLOTS: private slots:
void jumpToOutlineElement(int index); void jumpToOutlineElement(int index);
void updateOutlineNow(); void updateOutlineNow();
void updateOutlineIndex(); void updateOutlineIndex();
@@ -254,12 +254,10 @@ private:
QList<TextEditor::QuickFixOperation::Ptr> m_quickFixes; QList<TextEditor::QuickFixOperation::Ptr> m_quickFixes;
bool m_objcEnabled; bool m_objcEnabled;
QFuture<TextEditor::HighlightingResult> m_highlighter; QScopedPointer<QFutureWatcher<TextEditor::HighlightingResult> > m_highlightWatcher;
QFutureWatcher<TextEditor::HighlightingResult> m_highlightWatcher;
unsigned m_highlightRevision; // the editor revision that requested the highlight unsigned m_highlightRevision; // the editor revision that requested the highlight
QFuture<QList<int> > m_references; QScopedPointer<QFutureWatcher<QList<int> > > m_referencesWatcher;
QFutureWatcher<QList<int> > m_referencesWatcher;
unsigned m_referencesRevision; unsigned m_referencesRevision;
int m_referencesCursorPosition; int m_referencesCursorPosition;

View File

@@ -390,7 +390,7 @@ void CppEditorSupport::startHighlighting()
m_highlighter = m_highlightingSupport->highlightingFuture(doc, snapshot); m_highlighter = m_highlightingSupport->highlightingFuture(doc, snapshot);
m_lastHighlightRevision = revision; m_lastHighlightRevision = revision;
emit highlighterStarted(&m_highlighter, m_lastHighlightRevision); emit highlighterStarted(m_highlighter, m_lastHighlightRevision);
} else { } else {
const unsigned revision = currentSource(false).revision; const unsigned revision = currentSource(false).revision;
if (m_lastHighlightRevision == revision) if (m_lastHighlightRevision == revision)
@@ -400,7 +400,7 @@ void CppEditorSupport::startHighlighting()
static const Document::Ptr dummyDoc; static const Document::Ptr dummyDoc;
static const Snapshot dummySnapshot; static const Snapshot dummySnapshot;
m_highlighter = m_highlightingSupport->highlightingFuture(dummyDoc, dummySnapshot); m_highlighter = m_highlightingSupport->highlightingFuture(dummyDoc, dummySnapshot);
emit highlighterStarted(&m_highlighter, m_lastHighlightRevision); emit highlighterStarted(m_highlighter, m_lastHighlightRevision);
} }
} }
@@ -500,6 +500,8 @@ void CppEditorSupport::onCurrentEditorChanged()
void CppEditorSupport::releaseResources() void CppEditorSupport::releaseResources()
{ {
m_highlighter.cancel();
m_highlighter = QFuture<TextEditor::HighlightingResult>();
snapshotUpdater()->releaseSnapshot(); snapshotUpdater()->releaseSnapshot();
QMutexLocker semanticLocker(&m_lastSemanticInfoLock); QMutexLocker semanticLocker(&m_lastSemanticInfoLock);
m_lastSemanticInfo = SemanticInfo(); m_lastSemanticInfo = SemanticInfo();

View File

@@ -132,7 +132,7 @@ signals:
void documentUpdated(); void documentUpdated();
void diagnosticsChanged(); void diagnosticsChanged();
void semanticInfoUpdated(CppTools::SemanticInfo); void semanticInfoUpdated(CppTools::SemanticInfo);
void highlighterStarted(QFuture<TextEditor::HighlightingResult> *, unsigned revision); void highlighterStarted(QFuture<TextEditor::HighlightingResult>, unsigned revision);
private slots: private slots:
void onMimeTypeChanged(); void onMimeTypeChanged();