diff options
Diffstat (limited to 'platform/platform-impl/src/com/intellij/openapi/progress')
2 files changed, 64 insertions, 39 deletions
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 27bb8eb5f245..6a37bb2fb69e 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 @@ -17,7 +17,6 @@ package com.intellij.openapi.progress.impl; import com.intellij.concurrency.JobScheduler; import com.intellij.openapi.Disposable; -import com.intellij.openapi.application.Application; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.ModalityState; import com.intellij.openapi.application.ex.ApplicationEx; @@ -46,7 +45,7 @@ import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; -public class ProgressManagerImpl extends ProgressManager implements Disposable{ +public class ProgressManagerImpl extends ProgressManager implements Disposable { private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.progress.impl.ProgressManagerImpl"); private final AtomicInteger myCurrentUnsafeProgressCount = new AtomicInteger(0); private final AtomicInteger myCurrentModalProgressCount = new AtomicInteger(0); @@ -55,7 +54,7 @@ public class ProgressManagerImpl extends ProgressManager implements Disposable{ private static final boolean DISABLED = "disabled".equals(System.getProperty("idea.ProcessCanceledException")); private final ScheduledFuture<?> myCheckCancelledFuture; - public ProgressManagerImpl(Application application) { + public ProgressManagerImpl() { if (DISABLED) { myCheckCancelledFuture = null; } @@ -64,7 +63,6 @@ public class ProgressManagerImpl extends ProgressManager implements Disposable{ @Override public void run() { ourNeedToCheckCancel = true; - ProgressIndicatorProvider.ourNeedToCheckCancel = true; } }, 0, 10, TimeUnit.MILLISECONDS); } @@ -86,7 +84,6 @@ public class ProgressManagerImpl extends ProgressManager implements Disposable{ if (ourLockedCheckCounter > 10) { ourLockedCheckCounter = 0; ourNeedToCheckCancel = true; - ProgressIndicatorProvider.ourNeedToCheckCancel = true; } } else { @@ -99,7 +96,6 @@ public class ProgressManagerImpl extends ProgressManager implements Disposable{ public static void canceled() { ourNeedToCheckCancel = true; - ProgressIndicatorProvider.ourNeedToCheckCancel = true; } private static class NonCancelableIndicator extends EmptyProgressIndicator implements NonCancelableSection { @@ -371,6 +367,14 @@ public class ProgressManagerImpl extends ProgressManager implements Disposable{ public static Future<?> runProcessWithProgressAsynchronously(@NotNull final Task.Backgroundable task, @NotNull final ProgressIndicator progressIndicator, @Nullable final Runnable continuation) { + return runProcessWithProgressAsynchronously(task, progressIndicator, continuation, ModalityState.NON_MODAL); + } + + @NotNull + public static Future<?> runProcessWithProgressAsynchronously(@NotNull final Task.Backgroundable task, + @NotNull final ProgressIndicator progressIndicator, + @Nullable final Runnable continuation, + @NotNull final ModalityState modalityState) { if (progressIndicator instanceof Disposable) { Disposer.register(ApplicationManager.getApplication(), (Disposable)progressIndicator); } @@ -397,7 +401,7 @@ public class ProgressManagerImpl extends ProgressManager implements Disposable{ public void run() { task.onCancel(); } - }, ModalityState.NON_MODAL); + }, modalityState); } else { final Task.NotificationInfo notificationInfo = task.notifyFinished(); @@ -412,7 +416,7 @@ public class ProgressManagerImpl extends ProgressManager implements Disposable{ public void run() { task.onSuccess(); } - }, ModalityState.NON_MODAL); + }, modalityState); } } }; @@ -493,10 +497,6 @@ public class ProgressManagerImpl extends ProgressManager implements Disposable{ @Override public void dispose() { - stopCheckCanceled(); - } - - private void stopCheckCanceled() { if (myCheckCancelledFuture != null) myCheckCancelledFuture.cancel(false); } diff --git a/platform/platform-impl/src/com/intellij/openapi/progress/util/ProgressIndicatorUtils.java b/platform/platform-impl/src/com/intellij/openapi/progress/util/ProgressIndicatorUtils.java index b98f19b25d17..0c18cb7706d9 100644 --- a/platform/platform-impl/src/com/intellij/openapi/progress/util/ProgressIndicatorUtils.java +++ b/platform/platform-impl/src/com/intellij/openapi/progress/util/ProgressIndicatorUtils.java @@ -61,7 +61,7 @@ public class ProgressIndicatorUtils { runWithWriteActionPriority(new ProgressIndicatorBase(), task); } - public static void runWithWriteActionPriority(final ProgressIndicator progressIndicator, final ReadTask task) { + private static void surroundWithListener(@NotNull final ProgressIndicator progressIndicator, @NotNull Runnable runnable) { final ApplicationAdapter listener = new ApplicationAdapter() { @Override public void beforeWriteActionStart(Object action) { @@ -69,45 +69,70 @@ public class ProgressIndicatorUtils { } }; final Application application = ApplicationManager.getApplication(); + application.addApplicationListener(listener); try { - application.addApplicationListener(listener); - ProgressManager.getInstance().runProcess(new Runnable(){ - @Override - public void run() { - // This read action can possible last for a long time, we want it to stop immediately on the first write access. - // For this purpose we launch it under empty progress and invoke progressIndicator#cancel on write access to avoid possible write lock delays. - try { - application.runReadAction(new Runnable() { - @Override - public void run() { - task.computeInReadAction(progressIndicator); - } - }); - } - catch (ProcessCanceledException ignore) { - } - finally { - if (progressIndicator.isCanceled()) { - task.onCanceled(progressIndicator); - } - } - } - }, progressIndicator); + runnable.run(); } finally { application.removeApplicationListener(listener); } } + + public static void runWithWriteActionPriority(@NotNull final ProgressIndicator progressIndicator, @NotNull final ReadTask task) { + surroundWithListener(progressIndicator, new Runnable() { + @Override + public void run() { + runUnderProgress(progressIndicator, task); + } + }); + } + + private static void runUnderProgress(@NotNull final ProgressIndicator progressIndicator, @NotNull final ReadTask task) { + ProgressManager.getInstance().runProcess(new Runnable() { + @Override + public void run() { + // This read action can possible last for a long time, we want it to stop immediately on the first write access. + // For this purpose we launch it under empty progress and invoke progressIndicator#cancel on write access to avoid possible write lock delays. + try { + ApplicationManager.getApplication().runReadAction(new Runnable() { + @Override + public void run() { + task.computeInReadAction(progressIndicator); + } + }); + } + catch (ProcessCanceledException ignore) { + } + finally { + if (progressIndicator.isCanceled()) { + task.onCanceled(progressIndicator); + } + } + } + }, progressIndicator); + } + public static void scheduleWithWriteActionPriority(@NotNull final ReadTask task) { scheduleWithWriteActionPriority(new ProgressIndicatorBase(), task); } - public static void scheduleWithWriteActionPriority(final ProgressIndicator indicator, final ReadTask task) { - ApplicationManager.getApplication().executeOnPooledThread(new Runnable() { + public static void scheduleWithWriteActionPriority(@NotNull final ProgressIndicator indicator, @NotNull final ReadTask task) { + // we have to attach listeners in EDT to avoid "fire write action started while attach listeners from another thread" race condition + ApplicationManager.getApplication().invokeLater(new Runnable() { @Override public void run() { - runWithWriteActionPriority(indicator, task); + surroundWithListener(indicator, new Runnable() { + @Override + public void run() { + ApplicationManager.getApplication().executeOnPooledThread(new Runnable() { + @Override + public void run() { + runUnderProgress(indicator, task); + } + }); + } + }); } }); } |