diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/RefreshQueueImpl.java b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/RefreshQueueImpl.java index cbf7b09cf62c..c75e191baf8a 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/RefreshQueueImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/RefreshQueueImpl.java @@ -1,14 +1,12 @@ // Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. package com.intellij.openapi.vfs.newvfs; -import com.intellij.concurrency.SensitiveProgressWrapper; import com.intellij.openapi.Disposable; import com.intellij.openapi.application.*; import com.intellij.openapi.application.ex.ApplicationEx; import com.intellij.openapi.diagnostic.FrequentEventDetector; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.progress.ProgressIndicator; -import com.intellij.openapi.progress.util.ProgressIndicatorUtils; import com.intellij.openapi.util.registry.Registry; import com.intellij.openapi.vfs.AsyncFileListener; import com.intellij.openapi.vfs.VfsBundle; @@ -27,7 +25,6 @@ import java.util.Collections; import java.util.List; import java.util.concurrent.Executor; import java.util.concurrent.RejectedExecutionException; -import java.util.concurrent.atomic.AtomicLong; /** * @author max @@ -43,16 +40,6 @@ public class RefreshQueueImpl extends RefreshQueue implements Disposable { private int myBusyThreads; private final TLongObjectHashMap mySessions = new TLongObjectHashMap<>(); private final FrequentEventDetector myEventCounter = new FrequentEventDetector(100, 100, FrequentEventDetector.Level.WARN); - private final AtomicLong myWriteActionCounter = new AtomicLong(); - - public RefreshQueueImpl() { - ApplicationManager.getApplication().addApplicationListener(new ApplicationListener() { - @Override - public void writeActionStarted(@NotNull Object action) { - myWriteActionCounter.incrementAndGet(); - } - }, this); - } public void execute(@NotNull RefreshSessionImpl session) { if (session.isAsynchronous()) { @@ -98,15 +85,19 @@ public class RefreshQueueImpl extends RefreshQueue implements Disposable { private void scheduleAsynchronousPreprocessing(@NotNull RefreshSessionImpl session, @NotNull ModalityState modality) { try { - myEventProcessingQueue.execute(() -> { - startRefreshActivity(); - try (AccessToken ignored = HeavyProcessLatch.INSTANCE.processStarted("Processing VFS events. " + session)) { - processAndFireEvents(session, modality); - } - finally { - finishRefreshActivity(); - } - }); + ReadAction + .nonBlocking(() -> { + startRefreshActivity(); + try (AccessToken ignored = HeavyProcessLatch.INSTANCE.processStarted("Processing VFS events. " + session)) { + return runAsyncListeners(session); + } + finally { + finishRefreshActivity(); + } + }) + .cancelWith(myRefreshIndicator) + .finishOnUiThread(modality, Runnable::run) + .submit(myEventProcessingQueue); } catch (RejectedExecutionException e) { LOG.debug(e); @@ -125,35 +116,14 @@ public class RefreshQueueImpl extends RefreshQueue implements Disposable { } } - private void processAndFireEvents(@NotNull RefreshSessionImpl session, @NotNull ModalityState modality) { - while (true) { - ProgressIndicator progress = new SensitiveProgressWrapper(myRefreshIndicator); - boolean success = ProgressIndicatorUtils.runWithWriteActionPriority(() -> tryProcessingEvents(session, modality), progress); - if (success) { - break; - } - - ProgressIndicatorUtils.yieldToPendingWriteActions(); - } - } - - private void tryProcessingEvents(@NotNull RefreshSessionImpl session, @NotNull ModalityState modality) { + private static Runnable runAsyncListeners(@NotNull RefreshSessionImpl session) { List events = ContainerUtil.filter(session.getEvents(), e -> { VirtualFile file = e instanceof VFileCreateEvent ? ((VFileCreateEvent)e).getParent() : e.getFile(); return file == null || file.isValid(); }); List appliers = AsyncEventSupport.runAsyncListeners(events); - - long stamp = myWriteActionCounter.get(); - ApplicationManager.getApplication().invokeLater(() -> { - if (stamp == myWriteActionCounter.get()) { - session.fireEvents(events, appliers); - } - else { - scheduleAsynchronousPreprocessing(session, modality); - } - }, modality); + return () -> session.fireEvents(events, appliers); } private void doScan(@NotNull RefreshSessionImpl session) {