do not retain documents by the documentsToCommitInEDT queue

This commit is contained in:
Alexey Kudravtsev
2016-06-03 13:59:44 +03:00
parent 3c2e588cee
commit 2bc99e29ac
@@ -246,8 +246,9 @@ public class DocumentCommitThread implements Runnable, Disposable, DocumentCommi
if (task.indicator.isCanceled()) {
s += "; indicator: " + task.indicator;
}
Document document = task.getDocument();
boolean stillUncommitted = !task.project.isDisposed() &&
((PsiDocumentManagerBase)PsiDocumentManager.getInstance(task.project)).isInUncommittedSet(task.document);
((PsiDocumentManagerBase)PsiDocumentManager.getInstance(task.project)).isInUncommittedSet(document);
if (stillUncommitted) {
s += "; still uncommitted";
}
@@ -345,11 +346,11 @@ public class DocumentCommitThread implements Runnable, Disposable, DocumentCommi
}
}
private static boolean cancelAndRemoveFromQueue(@NotNull CommitTask newTask, @NotNull HashSetQueue<CommitTask> queue, @NotNull Object reason) {
private boolean cancelAndRemoveFromQueue(@NotNull CommitTask newTask, @NotNull HashSetQueue<CommitTask> queue, @NotNull Object reason) {
CommitTask queuedTask = queue.find(newTask);
if (queuedTask != null) {
assert queuedTask != newTask;
queuedTask.cancel(reason, getInstance());
queuedTask.cancel(reason, this);
}
return queue.remove(newTask);
}
@@ -382,7 +383,7 @@ public class DocumentCommitThread implements Runnable, Disposable, DocumentCommi
return false;
}
document = task.document;
document = task.getDocument();
indicator = task.indicator;
project = task.project;
@@ -413,7 +414,7 @@ public class DocumentCommitThread implements Runnable, Disposable, DocumentCommi
public void run() {
result.set(commitUnderProgress(commitTask, false));
}
}, commitTask.indicator);
}, indicator);
finishRunnable = result.get().first;
success = finishRunnable != null;
failureReason = result.get().second;
@@ -435,7 +436,7 @@ public class DocumentCommitThread implements Runnable, Disposable, DocumentCommi
}
}
catch (ProcessCanceledException e) {
cancel(e + " (cancel reason: "+((UserDataHolder)task.indicator).getUserData(CommitTask.CANCEL_REASON)+")"); // leave queue unchanged
cancel(e + " (cancel reason: "+((UserDataHolder)task.indicator).getUserData(CANCEL_REASON)+")"); // leave queue unchanged
success = false;
failureReason = e;
}
@@ -446,7 +447,7 @@ public class DocumentCommitThread implements Runnable, Disposable, DocumentCommi
}
final PsiDocumentManager documentManager = PsiDocumentManager.getInstance(project);
if (!success && task != null && documentManager.isUncommited(task.document)) { // sync commit has not intervened
if (!success && task != null && documentManager.isUncommited(document)) { // sync commit has not intervened
final Document finalDocument = document;
final Project finalProject = project;
List<Pair<PsiFileImpl, FileASTNode>> oldFileNodes =
@@ -541,9 +542,9 @@ public class DocumentCommitThread implements Runnable, Disposable, DocumentCommi
if (synchronously) {
assert !task.indicator.isCanceled();
}
final Project project = task.project;
final Document document = task.document;
final Document document = task.getDocument();
final Project project = task.project;
final PsiDocumentManagerBase documentManager = (PsiDocumentManagerBase)PsiDocumentManager.getInstance(project);
final List<Processor<Document>> finishProcessors = new SmartList<Processor<Document>>();
Runnable runnable = new Runnable() {
@@ -602,11 +603,21 @@ public class DocumentCommitThread implements Runnable, Disposable, DocumentCommi
return new Pair<Runnable, Object>(null, "Indicator was canceled");
}
Runnable result = new Runnable() {
Runnable result = createEdtRunnable(task, synchronously, finishProcessors);
return Pair.create(result, null);
}
@NotNull
private Runnable createEdtRunnable(@NotNull final CommitTask task,
final boolean synchronously,
@NotNull final List<Processor<Document>> finishProcessors) {
return new Runnable() {
@Override
public void run() {
myApplication.assertIsDispatchThread();
Document document = task.getDocument();
Project project = task.project;
PsiDocumentManagerBase documentManager = (PsiDocumentManagerBase)PsiDocumentManager.getInstance(project);
boolean committed = project.isDisposed() || documentManager.isCommitted(document);
synchronized (lock) {
documentsToApplyInEDT.remove(task);
@@ -643,7 +654,6 @@ public class DocumentCommitThread implements Runnable, Disposable, DocumentCommi
}
}
};
return Pair.create(result, null);
}
@NotNull
@@ -683,9 +693,9 @@ public class DocumentCommitThread implements Runnable, Disposable, DocumentCommi
UIUtil.dispatchAllInvocationEvents();
}
private static class CommitTask {
static final Key<Object> CANCEL_REASON = Key.create("CANCEL_REASON");
@NotNull final Document document;
private static final Key<Object> CANCEL_REASON = Key.create("CANCEL_REASON");
private class CommitTask {
@NotNull private final Document document;
@NotNull final Project project;
private final int modificationSequence; // store initial document modification sequence here to check if it changed later before commit in EDT
@@ -698,12 +708,12 @@ public class DocumentCommitThread implements Runnable, Disposable, DocumentCommi
private final CharSequence myLastCommittedText;
@NotNull final List<Pair<PsiFileImpl, FileASTNode>> myOldFileNodes;
protected CommitTask(@NotNull final Project project,
@NotNull final Document document,
@NotNull final List<Pair<PsiFileImpl, FileASTNode>> oldFileNodes,
@NotNull ProgressIndicator indicator,
@NotNull Object reason,
@NotNull ModalityState currentModalityState) {
CommitTask(@NotNull final Project project,
@NotNull final Document document,
@NotNull final List<Pair<PsiFileImpl, FileASTNode>> oldFileNodes,
@NotNull ProgressIndicator indicator,
@NotNull Object reason,
@NotNull ModalityState currentModalityState) {
this.document = document;
this.project = project;
this.indicator = indicator;
@@ -717,11 +727,13 @@ public class DocumentCommitThread implements Runnable, Disposable, DocumentCommi
@NonNls
@Override
public String toString() {
return "Doc: " + document + " (\"" + StringUtil.first(document.getImmutableCharSequence(), 40, true).toString().replaceAll("\n", " ") + "\")"
+ (indicator.isCanceled() ? " (Canceled: " + ((UserDataHolder)indicator).getUserData(CANCEL_REASON) + ")":"")
+" Reason: " + reason
+ (isStillValid() ? "" : "; changed: old seq="+modificationSequence+", new seq="+ ((DocumentEx)document).getModificationSequence())
;
Document document = getDocument();
String docInfo = document + " (\"" + StringUtil.first(document.getImmutableCharSequence(), 40, true).toString().replaceAll("\n", " ") + "\")";
String indicatorInfo = indicator.isCanceled() ? " (Canceled: " + ((UserDataHolder)indicator).getUserData(CANCEL_REASON) + ")" : "";
String reasonInfo = " Reason: " + reason + (isStillValid() ? ""
: "; changed: old seq=" + modificationSequence + ", new seq=" +
((DocumentEx)document).getModificationSequence());
return "Doc: " + docInfo + indicatorInfo + reasonInfo;
}
@Override
@@ -731,17 +743,18 @@ public class DocumentCommitThread implements Runnable, Disposable, DocumentCommi
CommitTask task = (CommitTask)o;
return document.equals(task.document) && project.equals(task.project);
return Comparing.equal(getDocument(),task.getDocument()) && project.equals(task.project);
}
@Override
public int hashCode() {
int result = document.hashCode();
int result = getDocument().hashCode();
result = 31 * result + project.hashCode();
return result;
}
public boolean isStillValid() {
Document document = getDocument();
return ((DocumentEx)document).getModificationSequence() == modificationSequence;
}
@@ -751,8 +764,17 @@ public class DocumentCommitThread implements Runnable, Disposable, DocumentCommi
indicator.cancel();
((UserDataHolder)indicator).putUserData(CANCEL_REASON, reason);
synchronized (lock) {
documentsToCommit.remove(this);
documentsToApplyInEDT.remove(this);
}
}
}
Document getDocument() {
return document;
}
}
// public for Upsource
@@ -760,7 +782,7 @@ public class DocumentCommitThread implements Runnable, Disposable, DocumentCommi
public Processor<Document> doCommit(@NotNull final CommitTask task,
@NotNull final PsiFile file,
@NotNull final FileASTNode oldFileNode) {
Document document = task.document;
Document document = task.getDocument();
final CharSequence newDocumentText = document.getImmutableCharSequence();
final TextRange changedPsiRange = getChangedPsiRange(file, task.myLastCommittedText, newDocumentText);
if (changedPsiRange == null) {
@@ -944,4 +966,13 @@ public class DocumentCommitThread implements Runnable, Disposable, DocumentCommi
return lock != null ? lock : ((UserDataHolderEx)document).putUserDataIfAbsent(DOCUMENT_LOCK, new ReentrantLock());
}
private static final Key<Lock> DOCUMENT_LOCK = Key.create("DOCUMENT_LOCK");
@TestOnly
int documentsToCommit() {
return documentsToCommit.size();
}
@TestOnly
int documentsToApplyInEDT() {
return documentsToApplyInEDT.size();
}
}