diff --git a/platform/platform-impl/src/com/intellij/openapi/progress/impl/ProgressManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/progress/impl/ProgressManagerImpl.java index 878e60099b50..51f14f8e2bd9 100644 --- a/platform/platform-impl/src/com/intellij/openapi/progress/impl/ProgressManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/progress/impl/ProgressManagerImpl.java @@ -56,7 +56,7 @@ import java.util.concurrent.atomic.AtomicReference; public class ProgressManagerImpl extends ProgressManager implements Disposable { private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.progress.impl.ProgressManagerImpl"); - public static final int CHECK_CANCELED_DELAY_MILLIS = 10; + static final int CHECK_CANCELED_DELAY_MILLIS = 10; private final AtomicInteger myCurrentUnsafeProgressCount = new AtomicInteger(0); private final AtomicInteger myCurrentModalProgressCount = new AtomicInteger(0); @@ -321,19 +321,17 @@ public class ProgressManagerImpl extends ProgressManager implements Disposable { Set threads = threadsUnderIndicator.get(indicator); if (threads != null) { for (Thread thread : threads) { - ProgressIndicator currentIndicator = getCurrentIndicator(thread); - boolean underCancelledIndicator = currentIndicator == indicator; - - if (!underCancelledIndicator && currentIndicator instanceof WrappedProgressIndicator) { - while(currentIndicator instanceof WrappedProgressIndicator) { - ProgressIndicator originalProgressIndicator = ((WrappedProgressIndicator)currentIndicator).getOriginalProgressIndicator(); - if (originalProgressIndicator == indicator) { - underCancelledIndicator = true; - break; - } - currentIndicator = originalProgressIndicator; + boolean underCancelledIndicator = false; + for (ProgressIndicator currentIndicator = getCurrentIndicator(thread); + currentIndicator != null; + currentIndicator = currentIndicator instanceof WrappedProgressIndicator ? + ((WrappedProgressIndicator)currentIndicator).getOriginalProgressIndicator() : null) { + if (currentIndicator == indicator) { + underCancelledIndicator = true; + break; } } + if (underCancelledIndicator) { threadsUnderCanceledIndicator.add(thread); } diff --git a/platform/platform-tests/testSrc/com/intellij/openapi/progress/impl/ProgressIndicatorTest.java b/platform/platform-tests/testSrc/com/intellij/openapi/progress/impl/ProgressIndicatorTest.java index f1884e98875b..5545d44c9d8a 100644 --- a/platform/platform-tests/testSrc/com/intellij/openapi/progress/impl/ProgressIndicatorTest.java +++ b/platform/platform-tests/testSrc/com/intellij/openapi/progress/impl/ProgressIndicatorTest.java @@ -22,6 +22,7 @@ import com.intellij.openapi.application.ex.ApplicationManagerEx; import com.intellij.openapi.progress.*; import com.intellij.openapi.progress.util.ProgressIndicatorBase; import com.intellij.openapi.progress.util.ProgressIndicatorUtils; +import com.intellij.openapi.progress.util.ProgressWrapper; import com.intellij.openapi.progress.util.ReadTask; import com.intellij.openapi.util.EmptyRunnable; import com.intellij.openapi.wm.ex.ProgressIndicatorEx; @@ -373,6 +374,34 @@ public class ProgressIndicatorTest extends LightPlatformTestCase { }).assertTiming(); } + public void testWrapperIndicatorGotCanceledTooWhenInnerIndicatorHas() { + final ProgressIndicator progress = new ProgressIndicatorBase(){ + @Override + protected boolean isCancelable() { + return true; + } + }; + try { + ProgressManager.getInstance().executeProcessUnderProgress(new Runnable() { + @Override + public void run() { + assertFalse(ProgressManagerImpl.threadsUnderCanceledIndicator.contains(Thread.currentThread())); + assertTrue(!progress.isCanceled()); + progress.cancel(); + assertTrue(ProgressManagerImpl.threadsUnderCanceledIndicator.contains(Thread.currentThread())); + assertTrue(progress.isCanceled()); + while (true) { // wait for PCE + ProgressManager.checkCanceled(); + } + } + }, ProgressWrapper.wrap(progress)); + fail("PCE must have been thrown"); + } + catch (ProcessCanceledException ignored) { + + } + } + private static class ProgressIndicatorStub implements ProgressIndicatorEx { private volatile boolean myCanceled;