diff --git a/java/compiler/impl/src/com/intellij/compiler/server/DefaultMessageHandler.java b/java/compiler/impl/src/com/intellij/compiler/server/DefaultMessageHandler.java index 96271ada3751..bfde64d4396e 100644 --- a/java/compiler/impl/src/com/intellij/compiler/server/DefaultMessageHandler.java +++ b/java/compiler/impl/src/com/intellij/compiler/server/DefaultMessageHandler.java @@ -20,6 +20,7 @@ import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.progress.ProcessCanceledException; import com.intellij.openapi.progress.ProgressIndicator; +import com.intellij.openapi.progress.util.ProgressIndicatorBase; import com.intellij.openapi.progress.util.ProgressIndicatorUtils; import com.intellij.openapi.progress.util.ReadTask; import com.intellij.openapi.project.DumbService; @@ -40,7 +41,6 @@ import org.jetbrains.jps.api.CmdlineRemoteProto; import org.jetbrains.org.objectweb.asm.Opcodes; import java.util.*; -import java.util.concurrent.atomic.AtomicBoolean; /** * @author Eugene Zhuravlev @@ -82,12 +82,7 @@ public abstract class DefaultMessageHandler implements BuilderMessageHandler { break; case CONSTANT_SEARCH_TASK: final CmdlineRemoteProto.Message.BuilderMessage.ConstantSearchTask task = msg.getConstantSearchTask(); - myTaskExecutor.submit(new Runnable() { - @Override - public void run() { - handleConstantSearchTask(channel, sessionId, task); - } - }); + handleConstantSearchTask(channel, sessionId, task); break; } } @@ -97,30 +92,29 @@ public abstract class DefaultMessageHandler implements BuilderMessageHandler { protected abstract void handleBuildEvent(UUID sessionId, CmdlineRemoteProto.Message.BuilderMessage.BuildEvent event); private void handleConstantSearchTask(final Channel channel, final UUID sessionId, final CmdlineRemoteProto.Message.BuilderMessage.ConstantSearchTask task) { - while (true) { - final AtomicBoolean canceled = new AtomicBoolean(false); - DumbService.getInstance(myProject).waitForSmartMode(); - ProgressIndicatorUtils.runWithWriteActionPriority(new ReadTask() { - @Override - public void computeInReadAction(@NotNull ProgressIndicator indicator) { - if (DumbService.isDumb(myProject)) { - canceled.set(true); - return; - } - + ProgressIndicatorUtils.scheduleWithWriteActionPriority(new ProgressIndicatorBase(), myTaskExecutor, new ReadTask() { + @Override + public void computeInReadAction(@NotNull ProgressIndicator indicator) { + if (DumbService.isDumb(myProject)) { + onCanceled(indicator); + } + else { doHandleConstantSearchTask(channel, sessionId, task); } - - @Override - public void onCanceled(@NotNull ProgressIndicator indicator) { - canceled.set(true); - } - }); - if (!canceled.get()) { - break; } - } + + @Override + public void onCanceled(@NotNull ProgressIndicator indicator) { + DumbService.getInstance(myProject).runWhenSmart(new Runnable() { + @Override + public void run() { + handleConstantSearchTask(channel, sessionId, task); + } + }); + } + }); } + private void doHandleConstantSearchTask(Channel channel, UUID sessionId, CmdlineRemoteProto.Message.BuilderMessage.ConstantSearchTask task) { final String ownerClassName = task.getOwnerClassName(); final String fieldName = task.getFieldName(); 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 0c18cb7706d9..368200492cae 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 @@ -22,7 +22,11 @@ import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.progress.ProcessCanceledException; import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.progress.ProgressManager; +import com.intellij.ui.AppUIUtil; import org.jetbrains.annotations.NotNull; +import org.jetbrains.ide.PooledThreadExecutor; + +import java.util.concurrent.Executor; /** * @author gregsh @@ -44,96 +48,76 @@ public class ProgressIndicatorUtils { return progress; } - public static void runWithWriteActionPriority(@NotNull final Runnable action) { - runWithWriteActionPriority(new ReadTask() { - @Override - public void computeInReadAction(@NotNull ProgressIndicator indicator) { - action.run(); - } - - @Override - public void onCanceled(@NotNull ProgressIndicator indicator) { - } - }); + public static void scheduleWithWriteActionPriority(@NotNull ReadTask task) { + scheduleWithWriteActionPriority(new ProgressIndicatorBase(), task); } - public static void runWithWriteActionPriority(@NotNull final ReadTask task) { - runWithWriteActionPriority(new ProgressIndicatorBase(), task); + public static void scheduleWithWriteActionPriority(@NotNull ProgressIndicator progressIndicator, @NotNull ReadTask readTask) { + scheduleWithWriteActionPriority(progressIndicator, PooledThreadExecutor.INSTANCE, readTask); } - private static void surroundWithListener(@NotNull final ProgressIndicator progressIndicator, @NotNull Runnable runnable) { - final ApplicationAdapter listener = new ApplicationAdapter() { - @Override - public void beforeWriteActionStart(Object action) { - progressIndicator.cancel(); - } - }; - final Application application = ApplicationManager.getApplication(); - application.addApplicationListener(listener); - try { - runnable.run(); - } - finally { - application.removeApplicationListener(listener); - } - } - - - public static void runWithWriteActionPriority(@NotNull final ProgressIndicator progressIndicator, @NotNull final ReadTask task) { - surroundWithListener(progressIndicator, new Runnable() { + public static void scheduleWithWriteActionPriority(@NotNull final ProgressIndicator progressIndicator, + @NotNull final Executor executor, + @NotNull final ReadTask readTask) { + AppUIUtil.invokeOnEdt(new Runnable() { @Override public void run() { - runUnderProgress(progressIndicator, task); + final Application application = ApplicationManager.getApplication(); + application.assertIsDispatchThread(); + final ApplicationAdapter listener = new ApplicationAdapter() { + @Override + public void beforeWriteActionStart(Object action) { + progressIndicator.cancel(); + } + }; + application.addApplicationListener(listener); + try { + executor.execute(new Runnable() { + @Override + public void run() { + try { + runUnderProgress(progressIndicator, readTask); + } + finally { + application.removeApplicationListener(listener); + } + } + }); + } + catch (RuntimeException e) { + application.removeApplicationListener(listener); + throw e; + } + catch (Error e) { + application.removeApplicationListener(listener); + throw e; + } } }); } 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(@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() { - surroundWithListener(indicator, new Runnable() { - @Override - public void run() { - ApplicationManager.getApplication().executeOnPooledThread(new Runnable() { - @Override - public void run() { - runUnderProgress(indicator, task); - } - }); + // 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); } } diff --git a/platform/platform-impl/src/com/intellij/ui/EditorNotificationsImpl.java b/platform/platform-impl/src/com/intellij/ui/EditorNotificationsImpl.java index 2197f7703769..4b788c80ae54 100644 --- a/platform/platform-impl/src/com/intellij/ui/EditorNotificationsImpl.java +++ b/platform/platform-impl/src/com/intellij/ui/EditorNotificationsImpl.java @@ -102,13 +102,7 @@ public class EditorNotificationsImpl extends EditorNotifications { task.computeInReadAction(indicator); } else { - final ProgressIndicator indicator1 = indicator; - myExecutor.execute(new Runnable() { - @Override - public void run() { - ProgressIndicatorUtils.runWithWriteActionPriority(indicator1, task); - } - }); + ProgressIndicatorUtils.scheduleWithWriteActionPriority(indicator, myExecutor, task); } } });