From 7c4fe4e7b07cb5a4c43e20619f727c2da21f753f Mon Sep 17 00:00:00 2001 From: peter Date: Wed, 27 Apr 2016 10:52:14 +0200 Subject: [PATCH] don't lose transactions 2 (IDEA-155266 IDEA hanging in 'indexing' state) --- .../application/TransactionGuardImpl.java | 20 +++++++++++++------ .../application/TransactionTest.groovy | 9 ++++++--- 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/platform/core-impl/src/com/intellij/openapi/application/TransactionGuardImpl.java b/platform/core-impl/src/com/intellij/openapi/application/TransactionGuardImpl.java index 17c520c6e906..6950a95a49c8 100644 --- a/platform/core-impl/src/com/intellij/openapi/application/TransactionGuardImpl.java +++ b/platform/core-impl/src/com/intellij/openapi/application/TransactionGuardImpl.java @@ -56,26 +56,25 @@ public class TransactionGuardImpl extends TransactionGuard { @NotNull private AccessToken startTransactionUnchecked() { - final TransactionIdImpl prevTransaction = myCurrentTransaction; final Object prevUnsafeModality = myUnsafeModality; final boolean wasWritingAllowed = myWritingAllowed; myWritingAllowed = true; - myCurrentTransaction = new TransactionIdImpl(); + myCurrentTransaction = new TransactionIdImpl(myCurrentTransaction); myUnsafeModality = null; return new AccessToken() { @Override public void finish() { - Queue queue = getQueue(prevTransaction); + Queue queue = getQueue(myCurrentTransaction.myParent); queue.addAll(myCurrentTransaction.myQueue); - myCurrentTransaction.myQueue = queue; if (!queue.isEmpty()) { pollQueueLater(); } myWritingAllowed = wasWritingAllowed; - myCurrentTransaction = prevTransaction; + myCurrentTransaction.myFinished = true; + myCurrentTransaction = myCurrentTransaction.myParent; myUnsafeModality = prevUnsafeModality; } }; @@ -83,6 +82,9 @@ public class TransactionGuardImpl extends TransactionGuard { @NotNull private Queue getQueue(@Nullable TransactionIdImpl transaction) { + while (transaction != null && transaction.myFinished) { + transaction = transaction.myParent; + } return transaction == null ? myQueue : transaction.myQueue; } @@ -316,7 +318,13 @@ public class TransactionGuardImpl extends TransactionGuard { private static class TransactionIdImpl implements TransactionId { private static final AtomicLong ourTransactionCounter = new AtomicLong(); final long myStartCounter = ourTransactionCounter.getAndIncrement(); - Queue myQueue = new LinkedBlockingQueue(); + final Queue myQueue = new LinkedBlockingQueue(); + boolean myFinished; + final TransactionIdImpl myParent; + + public TransactionIdImpl(@Nullable TransactionIdImpl parent) { + myParent = parent; + } @Override public String toString() { diff --git a/platform/platform-tests/testSrc/com/intellij/application/TransactionTest.groovy b/platform/platform-tests/testSrc/com/intellij/application/TransactionTest.groovy index aa702edf29a6..43f3d774152e 100644 --- a/platform/platform-tests/testSrc/com/intellij/application/TransactionTest.groovy +++ b/platform/platform-tests/testSrc/com/intellij/application/TransactionTest.groovy @@ -193,13 +193,16 @@ class TransactionTest extends LightPlatformTestCase { TransactionId id = null TransactionGuard.submitTransaction testRootDisposable, { log << '2' - id = guard.contextTransaction + TransactionGuard.submitTransaction testRootDisposable, { + log << '3' + id = guard.contextTransaction + } } SwingUtilities.invokeLater { - guard.submitTransaction testRootDisposable, id, { log << '3' } + guard.submitTransaction testRootDisposable, id, { log << '4' } } UIUtil.dispatchAllInvocationEvents() - assert log == ['1', '2', '3'] + assert log == ['1', '2', '3', '4'] } }