a more safe and performant way of fixing IDEA-CR-35432 IDEA-191113 Don't show "Background tasks running" if we know the tasks can be safely resumed

This commit is contained in:
peter
2018-07-31 10:03:52 -07:00
parent 0fa1e60f8b
commit c052a0e302
2 changed files with 15 additions and 7 deletions
@@ -105,6 +105,12 @@ public class CoreProgressManager extends ProgressManager implements Disposable {
}
}
List<ProgressIndicator> getCurrentIndicators() {
synchronized (threadsUnderIndicator) {
return new ArrayList<>(threadsUnderIndicator.keySet());
}
}
public static boolean runCheckCanceledHooks(@Nullable ProgressIndicator indicator) {
CheckCanceledHook hook = ourCheckCanceledHook;
return hook != null && hook.runHook(indicator);
@@ -12,6 +12,7 @@ import com.intellij.openapi.progress.Task;
import com.intellij.openapi.progress.util.PingProgress;
import com.intellij.openapi.progress.util.ProgressIndicatorUtils;
import com.intellij.openapi.progress.util.ProgressWindow;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.wm.WindowManager;
import com.intellij.ui.SystemNotifications;
import com.intellij.util.concurrency.AppExecutorUtil;
@@ -30,8 +31,8 @@ import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.locks.LockSupport;
public class ProgressManagerImpl extends CoreProgressManager implements Disposable {
private static final Key<Boolean> SAFE_PROGRESS_INDICATOR = Key.create("SAFE_PROGRESS_INDICATOR");
private final Set<CheckCanceledHook> myHooks = ContainerUtil.newConcurrentSet();
private final Set<ProgressWindow> myUnsafeProgresses = ContainerUtil.newConcurrentSet();
public ProgressManagerImpl() {
HeavyProcessLatch.INSTANCE.addUIActivityListener(new HeavyProcessLatch.HeavyProcessListener() {
@@ -61,21 +62,23 @@ public class ProgressManagerImpl extends CoreProgressManager implements Disposab
@Override
public boolean hasUnsafeProgressIndicator() {
return super.hasUnsafeProgressIndicator() || !myUnsafeProgresses.isEmpty();
return super.hasUnsafeProgressIndicator() || ContainerUtil.exists(getCurrentIndicators(), ProgressManagerImpl::isUnsafeIndicator);
}
private static boolean isUnsafeIndicator(ProgressIndicator indicator) {
return indicator instanceof ProgressWindow && ((ProgressWindow)indicator).getUserData(SAFE_PROGRESS_INDICATOR) == null;
}
/**
* The passes progress won't count in {@link #hasUnsafeProgressIndicator()} and won't stop from application exiting.
*/
public void markProgressSafe(@NotNull ProgressWindow progress) {
myUnsafeProgresses.remove(progress);
progress.putUserData(SAFE_PROGRESS_INDICATOR, true);
}
@Override
public void executeProcessUnderProgress(@NotNull Runnable process, ProgressIndicator progress) throws ProcessCanceledException {
if (progress instanceof ProgressWindow) myUnsafeProgresses.add((ProgressWindow)progress);
CheckCanceledHook hook = progress instanceof PingProgress && ApplicationManager.getApplication().isDispatchThread()
CheckCanceledHook hook = progress instanceof PingProgress && ApplicationManager.getApplication().isDispatchThread()
? p -> { ((PingProgress)progress).interact(); return true; }
: null;
if (hook != null) addCheckCanceledHook(hook);
@@ -84,7 +87,6 @@ public class ProgressManagerImpl extends CoreProgressManager implements Disposab
super.executeProcessUnderProgress(process, progress);
}
finally {
if (progress instanceof ProgressWindow) myUnsafeProgresses.remove((ProgressWindow)progress);
if (hook != null) removeCheckCanceledHook(hook);
}
}