add ProgressManager#runInReadActionWithWriteActionPriority API
authorpeter <peter@jetbrains.com>
Mon, 7 Nov 2016 07:25:14 +0000 (08:25 +0100)
committerpeter <peter@jetbrains.com>
Mon, 7 Nov 2016 07:25:14 +0000 (08:25 +0100)
platform/core-api/src/com/intellij/openapi/progress/ProgressManager.java
platform/core-impl/src/com/intellij/openapi/progress/impl/CoreProgressManager.java
platform/platform-impl/src/com/intellij/openapi/progress/impl/ProgressManagerImpl.java

index 50f1e03a7b725322cdcf00e99ed017359fc59e52..46a4dfa5db8134bee6d827f99ffe97b1b0237f46 100644 (file)
@@ -221,4 +221,21 @@ public abstract class ProgressManager extends ProgressIndicatorProvider {
       }
     }
   }
+
+  /**
+   * This method attempts to run provided action synchronously in a read action, so that, if possible, it wouldn't impact any pending,
+   * executing or future write actions (for this to work effectively the action should invoke {@link ProgressManager#checkCanceled()} or
+   * {@link ProgressIndicator#checkCanceled()} often enough).
+   * It returns <code>true</code> if action was executed successfully. It returns <code>false</code> if the action was not
+   * executed successfully, i.e. if:
+   * <ul>
+   * <li>write action was in progress when the method was called</li>
+   * <li>write action was pending when the method was called</li>
+   * <li>action started to execute, but was aborted using {@link ProcessCanceledException} when some other thread initiated
+   * write action</li>
+   * </ul>
+   * @since 171.*
+   */
+  public abstract boolean runInReadActionWithWriteActionPriority(@NotNull final Runnable action);
+
 }
\ No newline at end of file
index b990594c94304471d30537b0bde9db9a4a065d3f..aeb23cb6cc84d26d4b19e575015dc64ab02ab0fa 100644 (file)
@@ -534,6 +534,12 @@ public class CoreProgressManager extends ProgressManager implements Disposable {
     }
   }
 
+  @Override
+  public boolean runInReadActionWithWriteActionPriority(@NotNull Runnable action) {
+    ApplicationManager.getApplication().runReadAction(action);
+    return true;
+  }
+
   private void registerIndicatorAndRun(@NotNull ProgressIndicator indicator,
                                        @NotNull Thread currentThread,
                                        ProgressIndicator oldIndicator,
index 1f623cc79b4e2531f346bd0c8fb2978e996da0cc..719114e8b73e54bdfcda138c702606e8466dd8a3 100644 (file)
@@ -19,6 +19,7 @@ import com.intellij.openapi.Disposable;
 import com.intellij.openapi.application.ApplicationManager;
 import com.intellij.openapi.application.ModalityState;
 import com.intellij.openapi.progress.*;
+import com.intellij.openapi.progress.util.ProgressIndicatorUtils;
 import com.intellij.openapi.progress.util.ProgressWindow;
 import com.intellij.openapi.progress.util.SmoothProgressAdapter;
 import com.intellij.openapi.util.Disposer;
@@ -155,4 +156,13 @@ public class ProgressManagerImpl extends CoreProgressManager implements Disposab
 
     return ApplicationManager.getApplication().executeOnPooledThread(action);
   }
+
+  @Override
+  public boolean runInReadActionWithWriteActionPriority(@NotNull Runnable action) {
+    boolean success = ProgressIndicatorUtils.runInReadActionWithWriteActionPriority(action);
+    if (!success) {
+      ProgressIndicatorUtils.yieldToPendingWriteActions();
+    }
+    return success;
+  }
 }