runWhenSmart only after project is initialized to ensure all initial dumb tasks have...
authorpeter <peter@jetbrains.com>
Wed, 31 Aug 2016 17:57:42 +0000 (19:57 +0200)
committerpeter <peter@jetbrains.com>
Wed, 31 Aug 2016 17:58:05 +0000 (19:58 +0200)
platform/core-api/src/com/intellij/openapi/project/DumbService.java
platform/platform-impl/src/com/intellij/openapi/project/DumbServiceImpl.java

index c31aaf5113a9cc06f7c62a4259c251751128fabf..26f955de1df60aec26641ce9580a0774471553b5 100644 (file)
@@ -64,7 +64,8 @@ public abstract class DumbService {
   }
 
   /**
-   * Executes the runnable immediately if not in dumb mode, or on AWT Event Dispatch thread after the dumb mode ends.
+   * Executes the runnable immediately if the project is initialized and there's no dumb mode in progress,
+   * 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
index ec3c8dddbee626115f5d44d19dabff17fe3947e9..2c517632ce26517f964460bbbfaf3424336d4cb4 100644 (file)
@@ -26,6 +26,7 @@ import com.intellij.openapi.fileEditor.ex.FileEditorManagerEx;
 import com.intellij.openapi.progress.*;
 import com.intellij.openapi.progress.util.AbstractProgressIndicatorExBase;
 import com.intellij.openapi.progress.util.ProgressIndicatorBase;
+import com.intellij.openapi.startup.StartupManager;
 import com.intellij.openapi.ui.MessageType;
 import com.intellij.openapi.util.*;
 import com.intellij.openapi.wm.AppIconScheme;
@@ -53,13 +54,8 @@ import java.util.concurrent.atomic.AtomicReference;
 
 public class DumbServiceImpl extends DumbService implements Disposable, ModificationTracker {
   private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.project.DumbServiceImpl");
-  private static final NotNullLazyValue<DumbPermissionServiceImpl> ourPermissionService = new NotNullLazyValue<DumbPermissionServiceImpl>() {
-    @NotNull
-    @Override
-    protected DumbPermissionServiceImpl compute() {
-      return (DumbPermissionServiceImpl)ServiceManager.getService(DumbPermissionService.class);
-    }
-  };
+  private static final NotNullLazyValue<DumbPermissionServiceImpl> ourPermissionService = NotNullLazyValue.createValue(
+    () -> (DumbPermissionServiceImpl)ServiceManager.getService(DumbPermissionService.class));
   private static Throwable ourForcedTrace;
   private final AtomicReference<State> myState = new AtomicReference<>(State.SMART);
   private volatile Throwable myDumbStart;
@@ -152,14 +148,16 @@ public class DumbServiceImpl extends DumbService implements Disposable, Modifica
 
   @Override
   public void runWhenSmart(@NotNull Runnable runnable) {
-    synchronized (myRunWhenSmartQueue) {
-      if (isDumb()) {
-        myRunWhenSmartQueue.addLast(runnable);
-        return;
+    StartupManager.getInstance(myProject).runWhenProjectIsInitialized(() -> {
+      synchronized (myRunWhenSmartQueue) {
+        if (isDumb()) {
+          myRunWhenSmartQueue.addLast(runnable);
+          return;
+        }
       }
-    }
 
-    runnable.run();
+      runnable.run();
+    });
   }
 
   @Override
@@ -294,7 +292,10 @@ public class DumbServiceImpl extends DumbService implements Disposable, Modifica
 
   private void queueUpdateFinished(boolean modal) {
     if (myState.compareAndSet(State.RUNNING_DUMB_TASKS, State.WAITING_FOR_FINISH)) {
-      TransactionGuard.getInstance().submitTransaction(myProject, myDumbStartTransaction, () -> WriteAction.run(() -> updateFinished(modal)));
+      StartupManager.getInstance(myProject).runWhenProjectIsInitialized(
+        () -> TransactionGuard.getInstance().submitTransaction(myProject, myDumbStartTransaction, () ->
+          WriteAction.run(
+            () -> updateFinished(modal))));
     }
   }