mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
commitAndRunReadAction from a progress should not hang forever (IDEA-173613)
Signed-off-by: peter <peter@jetbrains.com>
This commit is contained in:
@@ -506,8 +506,8 @@ public abstract class PsiDocumentManagerBase extends PsiDocumentManager implemen
|
||||
});
|
||||
if (executed) break;
|
||||
|
||||
final Semaphore semaphore = new Semaphore();
|
||||
semaphore.down();
|
||||
TransactionId contextTransaction = TransactionGuard.getInstance().getContextTransaction();
|
||||
Semaphore semaphore = new Semaphore(1);
|
||||
application.invokeLater(() -> {
|
||||
if (myProject.isDisposed()) {
|
||||
// committedness doesn't matter anymore; give clients a chance to do checkCanceled
|
||||
@@ -515,7 +515,7 @@ public abstract class PsiDocumentManagerBase extends PsiDocumentManager implemen
|
||||
return;
|
||||
}
|
||||
|
||||
performWhenAllCommitted(() -> semaphore.up());
|
||||
performWhenAllCommitted(() -> semaphore.up(), contextTransaction);
|
||||
}, ModalityState.any());
|
||||
semaphore.waitFor();
|
||||
}
|
||||
@@ -528,6 +528,10 @@ public abstract class PsiDocumentManagerBase extends PsiDocumentManager implemen
|
||||
*/
|
||||
@Override
|
||||
public boolean performWhenAllCommitted(@NotNull final Runnable action) {
|
||||
return performWhenAllCommitted(action, TransactionGuard.getInstance().getContextTransaction());
|
||||
}
|
||||
|
||||
private boolean performWhenAllCommitted(@NotNull Runnable action, @Nullable TransactionId context) {
|
||||
ApplicationManager.getApplication().assertIsDispatchThread();
|
||||
checkWeAreOutsideAfterCommitHandler();
|
||||
|
||||
@@ -543,13 +547,12 @@ public abstract class PsiDocumentManagerBase extends PsiDocumentManager implemen
|
||||
}
|
||||
actions.add(action);
|
||||
|
||||
TransactionId current = TransactionGuard.getInstance().getContextTransaction();
|
||||
if (current != ModalityState.NON_MODAL) {
|
||||
if (context != null) {
|
||||
// re-add all uncommitted documents into the queue with this new modality
|
||||
// because this client obviously expects them to commit even inside modal dialog
|
||||
for (Document document : myUncommittedDocuments) {
|
||||
myDocumentCommitProcessor.commitAsynchronously(myProject, document,
|
||||
"re-added with modality "+current+" because performWhenAllCommitted("+current+") was called", current);
|
||||
"re-added with context "+context+" because performWhenAllCommitted("+context+") was called", context);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
||||
@@ -37,6 +37,10 @@ import com.intellij.openapi.fileEditor.FileEditorManager;
|
||||
import com.intellij.openapi.fileEditor.OpenFileDescriptor;
|
||||
import com.intellij.openapi.fileTypes.PlainTextLanguage;
|
||||
import com.intellij.openapi.fileTypes.StdFileTypes;
|
||||
import com.intellij.openapi.progress.ProgressIndicator;
|
||||
import com.intellij.openapi.progress.ProgressManager;
|
||||
import com.intellij.openapi.progress.Task;
|
||||
import com.intellij.openapi.progress.util.ProgressWindow;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.project.ex.ProjectManagerEx;
|
||||
import com.intellij.openapi.ui.DialogWrapper;
|
||||
@@ -793,6 +797,33 @@ public class PsiDocumentManagerImplTest extends PlatformTestCase {
|
||||
assertEquals(PlainTextLanguage.INSTANCE, file2.getLanguage());
|
||||
}
|
||||
|
||||
public void testAsyncCommitHappensInProgressStartedFromTransaction() throws IOException {
|
||||
PsiFile file = getPsiManager().findFile(getVirtualFile(createTempFile("X.txt", "")));
|
||||
Document document = file.getViewProvider().getDocument();
|
||||
|
||||
Semaphore semaphore = new Semaphore(1);
|
||||
TransactionGuard.submitTransaction(getTestRootDisposable(), () -> {
|
||||
WriteCommandAction.runWriteCommandAction(myProject, () -> {
|
||||
document.insertString(0, "x");
|
||||
|
||||
ProgressManager.getInstance().runProcessWithProgressAsynchronously(new Task.Backgroundable(myProject, "Title", false) {
|
||||
@Override
|
||||
public void run(@NotNull ProgressIndicator indicator) {
|
||||
getPsiDocumentManager().commitAndRunReadAction(() -> semaphore.up());
|
||||
}
|
||||
}, new ProgressWindow(false, myProject));
|
||||
});
|
||||
});
|
||||
int iteration = 0;
|
||||
while (!semaphore.waitFor(10)) {
|
||||
UIUtil.dispatchAllInvocationEvents();
|
||||
if (++iteration > 3000) {
|
||||
printThreadDump();
|
||||
fail("Couldn't wait for commit");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void assertLargeFileContentLimited(@NotNull String content, @NotNull VirtualFile vFile, @NotNull Document document) {
|
||||
Charset charset = EncodingManager.getInstance().getEncoding(vFile, false);
|
||||
float bytesPerChar = charset == null ? 2 : charset.newEncoder().averageBytesPerChar();
|
||||
|
||||
Reference in New Issue
Block a user