diff --git a/platform/core-api/src/com/intellij/openapi/project/DumbService.java b/platform/core-api/src/com/intellij/openapi/project/DumbService.java index 8062d86390b8..fcd2ec68fa29 100644 --- a/platform/core-api/src/com/intellij/openapi/project/DumbService.java +++ b/platform/core-api/src/com/intellij/openapi/project/DumbService.java @@ -64,7 +64,9 @@ public abstract class DumbService { } /** - * Executes the runnable immediately if not in dumb mode, or on AWT Event Dispatch thread when the dumb mode ends. + * Executes the runnable immediately if not in dumb mode, or on AWT Event Dispatch thread after the dumb mode ends. + * Note that it's not guaranteed that the dumb mode won't start again during this runnable execution, it should manage that situation explicitly + * (e.g. by starting a read action; it's still necessary to check isDumb inside the read action). * @param runnable runnable to run */ public abstract void runWhenSmart(@NotNull Runnable runnable); diff --git a/platform/platform-impl/src/com/intellij/openapi/project/DumbServiceImpl.java b/platform/platform-impl/src/com/intellij/openapi/project/DumbServiceImpl.java index 788864eaabb4..a1d1cc15b81e 100644 --- a/platform/platform-impl/src/com/intellij/openapi/project/DumbServiceImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/project/DumbServiceImpl.java @@ -151,14 +151,14 @@ public class DumbServiceImpl extends DumbService implements Disposable, Modifica @Override public void runWhenSmart(@NotNull Runnable runnable) { - if (!isDumb()) { - runnable.run(); - } - else { - synchronized (myRunWhenSmartQueue) { + synchronized (myRunWhenSmartQueue) { + if (isDumb()) { myRunWhenSmartQueue.addLast(runnable); + return; } } + + runnable.run(); } private void scheduleCacheUpdate(@NotNull final DumbModeTask task, boolean forceDumbMode) { @@ -220,7 +220,9 @@ public class DumbServiceImpl extends DumbService implements Disposable, Modifica application.runWriteAction(new Runnable() { @Override public void run() { - myDumb = true; + synchronized (myRunWhenSmartQueue) { + myDumb = true; + } myDumbStart = trace; myModificationCount++; try { @@ -286,7 +288,9 @@ public class DumbServiceImpl extends DumbService implements Disposable, Modifica } private void updateFinished(boolean modal) { - myDumb = false; + synchronized (myRunWhenSmartQueue) { + myDumb = false; + } myDumbStart = null; myModificationCount++; if (myProject.isDisposed()) return;