improve runInReadActionWithWriteActionPriority, add assertion (IDEA-CR-15454)
authorpeter <peter@jetbrains.com>
Mon, 7 Nov 2016 12:45:14 +0000 (13:45 +0100)
committerpeter <peter@jetbrains.com>
Mon, 7 Nov 2016 14:05:26 +0000 (15:05 +0100)
platform/core-api/src/com/intellij/openapi/progress/ProgressManager.java
platform/platform-impl/src/com/intellij/openapi/progress/impl/ProgressManagerImpl.java
platform/platform-impl/src/com/intellij/openapi/progress/util/ProgressIndicatorUtils.java

index 46a4dfa5db8134bee6d827f99ffe97b1b0237f46..f9dfac0d9376c28c6db589f2c11c10ba9f4b194f 100644 (file)
@@ -234,6 +234,8 @@ public abstract class ProgressManager extends ProgressIndicatorProvider {
    * <li>action started to execute, but was aborted using {@link ProcessCanceledException} when some other thread initiated
    * write action</li>
    * </ul>
+   * If unable to run read action because of interfering write action, this method waits for that write action to complete.
+   * So under no circumstances must you call this method from read action or under critical locks.
    * @since 171.*
    */
   public abstract boolean runInReadActionWithWriteActionPriority(@NotNull final Runnable action);
index 719114e8b73e54bdfcda138c702606e8466dd8a3..39f6f99809c879be56b13a9d25b5cdb277640b6b 100644 (file)
@@ -159,6 +159,9 @@ public class ProgressManagerImpl extends CoreProgressManager implements Disposab
 
   @Override
   public boolean runInReadActionWithWriteActionPriority(@NotNull Runnable action) {
+    if (ApplicationManager.getApplication().isReadAccessAllowed()) {
+      throw new AssertionError("runInReadActionWithWriteActionPriority shouldn't be invoked from read action");
+    }
     boolean success = ProgressIndicatorUtils.runInReadActionWithWriteActionPriority(action);
     if (!success) {
       ProgressIndicatorUtils.yieldToPendingWriteActions();
index 837623d0277e620ead0f59ade777cd466db58111..dadd49495563feb31bb509905feba7c519caf6b4 100644 (file)
@@ -230,7 +230,7 @@ public class ProgressIndicatorUtils {
 
   /**
    * Ensure the current EDT activity finishes in case it requires many write actions, with each being delayed a bit
-   * by background thread read action (until its first checkCanceled call).
+   * by background thread read action (until its first checkCanceled call). Shouldn't be called from under read action.
    */
   public static void yieldToPendingWriteActions() {
     ApplicationManager.getApplication().invokeAndWait(EmptyRunnable.INSTANCE, ModalityState.any());