mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
do not fire "AAA write action started, everything is lost" listener during continuation execution to fix IDEA-169288 Resource Bundle Editor: Cannot edit text
This commit is contained in:
+3
-4
@@ -82,7 +82,7 @@ public class ProgressIndicatorUtils {
|
||||
}
|
||||
|
||||
/**
|
||||
* Same as {@link #runInReadActionWithWriteActionPriority(Runnable)}, optionally allowing to pass a {@link ProgressIndicatorUtils}
|
||||
* Same as {@link #runInReadActionWithWriteActionPriority(Runnable)}, optionally allowing to pass a {@link ProgressIndicator}
|
||||
* instance, which can be used to cancel action externally.
|
||||
*/
|
||||
public static boolean runInReadActionWithWriteActionPriority(@NotNull final Runnable action,
|
||||
@@ -161,7 +161,6 @@ public class ProgressIndicatorUtils {
|
||||
public static CompletableFuture<?> 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
|
||||
// which get cancelled too soon when a next write action arrives in the same EDT batch
|
||||
@@ -171,8 +170,8 @@ public class ProgressIndicatorUtils {
|
||||
// to tolerate any immediate modality changes (e.g. https://youtrack.jetbrains.com/issue/IDEA-135180)
|
||||
|
||||
CompletableFuture<?> future = new CompletableFuture<>();
|
||||
//noinspection SSBasedInspection
|
||||
EdtInvocationManager.getInstance().invokeLater(() -> {
|
||||
final Application application = ApplicationManager.getApplication();
|
||||
if (application.isDisposed() || progressIndicator.isCanceled()) {
|
||||
future.complete(null);
|
||||
return;
|
||||
@@ -207,6 +206,7 @@ public class ProgressIndicatorUtils {
|
||||
application.invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
application.removeApplicationListener(listener); // remove listener early to prevent firing it during continuation execution
|
||||
try {
|
||||
if (!progressIndicator.isCanceled()) {
|
||||
continuation.getAction().run();
|
||||
@@ -232,7 +232,6 @@ public class ProgressIndicatorUtils {
|
||||
});
|
||||
}
|
||||
catch (RuntimeException | Error e) {
|
||||
application.removeApplicationListener(listener);
|
||||
future.completeExceptionally(e);
|
||||
throw e;
|
||||
}
|
||||
|
||||
+29
-2
@@ -21,6 +21,7 @@ import com.intellij.concurrency.SensitiveProgressWrapper;
|
||||
import com.intellij.ide.util.DelegatingProgressIndicator;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.ModalityState;
|
||||
import com.intellij.openapi.application.WriteAction;
|
||||
import com.intellij.openapi.application.ex.ApplicationManagerEx;
|
||||
import com.intellij.openapi.progress.*;
|
||||
import com.intellij.openapi.progress.util.ProgressIndicatorBase;
|
||||
@@ -43,14 +44,15 @@ import com.intellij.util.containers.Stack;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import gnu.trove.TLongArrayList;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
/**
|
||||
* @author yole
|
||||
@@ -148,7 +150,6 @@ public class ProgressIndicatorTest extends LightPlatformTestCase {
|
||||
final AtomicBoolean afterContinuation = new AtomicBoolean();
|
||||
final ProgressIndicatorBase indicator = new ProgressIndicatorBase();
|
||||
ProgressIndicatorUtils.scheduleWithWriteActionPriority(indicator, new ReadTask() {
|
||||
@Nullable
|
||||
@Override
|
||||
public Continuation performInReadAction(@NotNull ProgressIndicator indicator) throws ProcessCanceledException {
|
||||
return new Continuation(() -> afterContinuation.set(true));
|
||||
@@ -660,4 +661,30 @@ public class ProgressIndicatorTest extends LightPlatformTestCase {
|
||||
});
|
||||
assertFalse(progressManager.isInNonCancelableSection());
|
||||
}
|
||||
|
||||
public void testProgressIndicatorUtilsScheduleWithWriteActionPriorityMustRemoveListenerBeforeContinuationStartsExecutingInEDT() throws Throwable {
|
||||
final AtomicBoolean canceled = new AtomicBoolean();
|
||||
final ProgressIndicatorBase indicator = new ProgressIndicatorBase();
|
||||
AtomicReference<CompletableFuture<?>> future = new AtomicReference<>();
|
||||
future.set(ProgressIndicatorUtils.scheduleWithWriteActionPriority(indicator, new ReadTask() {
|
||||
@Override
|
||||
public Continuation performInReadAction(@NotNull ProgressIndicator indicator) throws ProcessCanceledException {
|
||||
return new Continuation(() -> {
|
||||
assertFalse(future.get().isDone());
|
||||
WriteAction.run(() -> {
|
||||
}); // when I start write action from the continuation, the read task must not cancel
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCanceled(@NotNull ProgressIndicator indicator) {
|
||||
canceled.set(true);
|
||||
fail();
|
||||
}
|
||||
}));
|
||||
while (!future.get().isDone()) {
|
||||
UIUtil.dispatchAllInvocationEvents();
|
||||
}
|
||||
assertFalse(canceled.get());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user