mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
make getExtensions interruptible by checkCanceled
to get more responsiveness while loading classes for all of those extensions
This commit is contained in:
@@ -8,6 +8,7 @@ import com.intellij.openapi.progress.ProcessCanceledException;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.openapi.util.Condition;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
import com.intellij.openapi.util.EmptyRunnable;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.containers.OpenTHashSet;
|
||||
@@ -247,6 +248,7 @@ public final class ExtensionPointImpl<T> implements ExtensionPoint<T> {
|
||||
myLoadedAdapters = Collections.emptyList();
|
||||
boolean errorHappened = false;
|
||||
for (int i = 0; i < adapters.size(); i++) {
|
||||
CHECK_CANCELED.run();
|
||||
ExtensionComponentAdapter adapter = adapters.get(i);
|
||||
try {
|
||||
@SuppressWarnings("unchecked") T extension = (T)adapter.getExtension();
|
||||
@@ -548,4 +550,35 @@ public final class ExtensionPointImpl<T> implements ExtensionPoint<T> {
|
||||
return myLoadingOrder;
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("FieldAccessedSynchronizedAndUnsynchronized")
|
||||
private static Runnable CHECK_CANCELED = EmptyRunnable.getInstance();
|
||||
|
||||
public static void setCheckCanceledAction(Runnable checkCanceled) {
|
||||
CHECK_CANCELED = new Runnable() {
|
||||
final Set<Throwable> reported = ContainerUtil.newConcurrentSet();
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
checkCanceled.run();
|
||||
}
|
||||
catch (ProcessCanceledException e) {
|
||||
if (!isInsideClassInitializer(e.getStackTrace())) { // otherwise ExceptionInInitializerError happens and the class is screwed forever
|
||||
throw e;
|
||||
}
|
||||
else {
|
||||
Throwable throwable = new Throwable();
|
||||
if (reported.add(throwable)) {
|
||||
LOG.warn("Don't instantiate extensions from class initializer", throwable);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private static boolean isInsideClassInitializer(StackTraceElement[] trace) {
|
||||
return Arrays.stream(trace).anyMatch(s -> "<clinit>".equals(s.getMethodName()));
|
||||
}
|
||||
}
|
||||
|
||||
+3
-4
@@ -5,10 +5,8 @@ package com.intellij.openapi.progress.impl;
|
||||
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.progress.EmptyProgressIndicator;
|
||||
import com.intellij.openapi.progress.ProcessCanceledException;
|
||||
import com.intellij.openapi.progress.ProgressIndicator;
|
||||
import com.intellij.openapi.progress.Task;
|
||||
import com.intellij.openapi.extensions.impl.ExtensionPointImpl;
|
||||
import com.intellij.openapi.progress.*;
|
||||
import com.intellij.openapi.progress.util.PingProgress;
|
||||
import com.intellij.openapi.progress.util.ProgressIndicatorUtils;
|
||||
import com.intellij.openapi.progress.util.ProgressWindow;
|
||||
@@ -58,6 +56,7 @@ public class ProgressManagerImpl extends CoreProgressManager implements Disposab
|
||||
}
|
||||
|
||||
}, this);
|
||||
ExtensionPointImpl.setCheckCanceledAction(ProgressManager::checkCanceled);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Reference in New Issue
Block a user