mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
project leak: explicitly wait for project scan in background to complete
This commit is contained in:
+45
-29
@@ -32,7 +32,10 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.ide.PooledThreadExecutor;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.function.BiConsumer;
|
||||
|
||||
/**
|
||||
* Methods in this class are used to equip long background processes which take read actions with a special listener
|
||||
@@ -60,16 +63,23 @@ public class ProgressIndicatorUtils {
|
||||
return progress;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static Future<?> submitWithWriteActionPriority(@NotNull ReadTask task) {
|
||||
return scheduleWithWriteActionPriority(new ProgressIndicatorBase(), task);
|
||||
}
|
||||
|
||||
public static void scheduleWithWriteActionPriority(@NotNull ReadTask task) {
|
||||
scheduleWithWriteActionPriority(new ProgressIndicatorBase(), task);
|
||||
submitWithWriteActionPriority(task);
|
||||
}
|
||||
|
||||
public static void scheduleWithWriteActionPriority(@NotNull ProgressIndicator progressIndicator, @NotNull ReadTask readTask) {
|
||||
scheduleWithWriteActionPriority(progressIndicator, PooledThreadExecutor.INSTANCE, readTask);
|
||||
@NotNull
|
||||
public static Future<?> scheduleWithWriteActionPriority(@NotNull ProgressIndicator progressIndicator, @NotNull ReadTask readTask) {
|
||||
return scheduleWithWriteActionPriority(progressIndicator, PooledThreadExecutor.INSTANCE, readTask);
|
||||
}
|
||||
|
||||
public static void scheduleWithWriteActionPriority(@NotNull Executor executor, @NotNull ReadTask task) {
|
||||
scheduleWithWriteActionPriority(new ProgressIndicatorBase(), executor, task);
|
||||
@NotNull
|
||||
public static Future<?> scheduleWithWriteActionPriority(@NotNull Executor executor, @NotNull ReadTask task) {
|
||||
return scheduleWithWriteActionPriority(new ProgressIndicatorBase(), executor, task);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -148,9 +158,10 @@ public class ProgressIndicatorUtils {
|
||||
return wasCancelled.get() != Boolean.TRUE;
|
||||
}
|
||||
|
||||
public static void scheduleWithWriteActionPriority(@NotNull final ProgressIndicator progressIndicator,
|
||||
@NotNull final Executor executor,
|
||||
@NotNull final ReadTask readTask) {
|
||||
@NotNull
|
||||
public static Future<?> scheduleWithWriteActionPriority(@NotNull final ProgressIndicator progressIndicator,
|
||||
@NotNull final Executor executor,
|
||||
@NotNull final ReadTask readTask) {
|
||||
final Application application = ApplicationManager.getApplication();
|
||||
// invoke later even if on EDT
|
||||
// to avoid tasks eagerly restarting immediately, allocating many pooled threads
|
||||
@@ -160,9 +171,13 @@ public class ProgressIndicatorUtils {
|
||||
// use SwingUtilities instead of application.invokeLater
|
||||
// to tolerate any immediate modality changes (e.g. https://youtrack.jetbrains.com/issue/IDEA-135180)
|
||||
|
||||
CompletableFuture<?> future = new CompletableFuture<>();
|
||||
//noinspection SSBasedInspection
|
||||
EdtInvocationManager.getInstance().invokeLater(() -> {
|
||||
if (application.isDisposed()) return;
|
||||
if (application.isDisposed()) {
|
||||
future.complete(null);
|
||||
return;
|
||||
}
|
||||
final ApplicationAdapter listener = new ApplicationAdapter() {
|
||||
@Override
|
||||
public void beforeWriteActionStart(@NotNull Object action) {
|
||||
@@ -173,35 +188,34 @@ public class ProgressIndicatorUtils {
|
||||
}
|
||||
};
|
||||
application.addApplicationListener(listener);
|
||||
future.whenComplete((BiConsumer<Object, Throwable>)(o, throwable) -> application.removeApplicationListener(listener));
|
||||
try {
|
||||
executor.execute(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
boolean continued = false;
|
||||
try {
|
||||
final ReadTask.Continuation continuation = runUnderProgress(progressIndicator, readTask);
|
||||
continued = continuation != null;
|
||||
if (continuation != null) {
|
||||
application.invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
application.removeApplicationListener(listener);
|
||||
final ReadTask.Continuation continuation = runUnderProgress(progressIndicator, readTask);
|
||||
if (continuation == null) {
|
||||
future.complete(null);
|
||||
}
|
||||
else {
|
||||
application.invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
if (!progressIndicator.isCanceled()) {
|
||||
continuation.getAction().run();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "continuation of " + readTask;
|
||||
finally {
|
||||
future.complete(null);
|
||||
}
|
||||
}, continuation.getModalityState());
|
||||
}
|
||||
}
|
||||
finally {
|
||||
if (!continued) {
|
||||
application.removeApplicationListener(listener);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "continuation of " + readTask;
|
||||
}
|
||||
}, continuation.getModalityState());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -213,9 +227,11 @@ public class ProgressIndicatorUtils {
|
||||
}
|
||||
catch (RuntimeException | Error e) {
|
||||
application.removeApplicationListener(listener);
|
||||
future.completeExceptionally(e);
|
||||
throw e;
|
||||
}
|
||||
});
|
||||
return future;
|
||||
}
|
||||
|
||||
private static ReadTask.Continuation runUnderProgress(@NotNull final ProgressIndicator progressIndicator, @NotNull final ReadTask task) {
|
||||
|
||||
Reference in New Issue
Block a user