mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
allow nested synchronous transactions in the same modality
This commit is contained in:
@@ -36,24 +36,40 @@ public class TransactionGuardImpl extends TransactionGuard {
|
||||
private final Queue<Runnable> myQueue = new LinkedBlockingQueue<Runnable>();
|
||||
private final Set<TransactionKind> myMergeableKinds = ContainerUtil.newHashSet();
|
||||
private String myTransactionStartTrace;
|
||||
private ModalityState myTransactionModality;
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public AccessToken startSynchronousTransaction(@NotNull TransactionKind kind) throws IllegalStateException {
|
||||
ApplicationManager.getApplication().assertIsDispatchThread();
|
||||
if (myTransactionStartTrace != null) {
|
||||
if (!myMergeableKinds.contains(kind) && !ApplicationManager.getApplication().isUnitTestMode()) {
|
||||
// please assign exceptions that occur here to Peter
|
||||
LOG.error("Nested transactions are not allowed, see FAQ in TransactionGuard class javadoc. Transaction start trace is in attachment. Kind is " + kind,
|
||||
new Attachment("trace.txt", myTransactionStartTrace));
|
||||
ModalityState modality = ModalityState.current();
|
||||
if (isInsideTransaction()) {
|
||||
if (myTransactionModality == modality) {
|
||||
return AccessToken.EMPTY_ACCESS_TOKEN;
|
||||
}
|
||||
|
||||
if (myMergeableKinds.contains(kind)) {
|
||||
final ModalityState prev = myTransactionModality;
|
||||
myTransactionModality = modality;
|
||||
return new AccessToken() {
|
||||
@Override
|
||||
public void finish() {
|
||||
myTransactionModality = prev;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// please assign exceptions that occur here to Peter
|
||||
LOG.error("Nested transactions are not allowed, see FAQ in TransactionGuard class javadoc. Transaction start trace is in attachment. Kind is " + kind,
|
||||
new Attachment("trace.txt", myTransactionStartTrace));
|
||||
return AccessToken.EMPTY_ACCESS_TOKEN;
|
||||
}
|
||||
myTransactionModality = modality;
|
||||
myTransactionStartTrace = DebugUtil.currentStackTrace();
|
||||
return new AccessToken() {
|
||||
@Override
|
||||
public void finish() {
|
||||
myTransactionStartTrace = null;
|
||||
myTransactionModality = null;
|
||||
if (!myQueue.isEmpty()) {
|
||||
pollQueueLater();
|
||||
}
|
||||
@@ -148,7 +164,7 @@ public class TransactionGuardImpl extends TransactionGuard {
|
||||
public void submitTransactionAndWait(@NotNull TransactionKind kind, @NotNull final Runnable transaction) throws ProcessCanceledException {
|
||||
Application app = ApplicationManager.getApplication();
|
||||
if (app.isDispatchThread()) {
|
||||
if (!canRunTransactionNow(kind)) {
|
||||
if (!canRunTransactionNow(kind) && myTransactionModality != ModalityState.current()) {
|
||||
throw new AssertionError("Cannot run submitTransactionAndWait from another transaction, kind " + kind + " is not allowed");
|
||||
}
|
||||
runSyncTransaction(kind, transaction);
|
||||
|
||||
@@ -94,9 +94,7 @@ public class EndHandler extends EditorActionHandler {
|
||||
// here just as a boolean value holder due to requirement to declare variable used from inner class as final.
|
||||
final AtomicBoolean stopProcessing = new AtomicBoolean(true);
|
||||
|
||||
TransactionGuard guard = TransactionGuard.getInstance();
|
||||
// sometimes this handler is invoked from other actions, then we're already inside a transaction
|
||||
try (AccessToken ignore = guard.isInsideTransaction() ? null : guard.startSynchronousTransaction(TransactionKind.TEXT_EDITING)) {
|
||||
try (AccessToken ignore = TransactionGuard.getInstance().startSynchronousTransaction(TransactionKind.TEXT_EDITING)) {
|
||||
PsiDocumentManager.getInstance(project).commitAllDocuments();
|
||||
ApplicationManager.getApplication().runWriteAction(() -> {
|
||||
CodeStyleManager styleManager = CodeStyleManager.getInstance(project);
|
||||
|
||||
Reference in New Issue
Block a user