mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
VSC: better suspend logic for continuation, to avoid potential duplicate tasks after suspend-awake (separate progress runner)
This commit is contained in:
@@ -28,6 +28,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
/**
|
||||
* @author irengrig
|
||||
@@ -39,7 +40,7 @@ abstract class GeneralRunner implements ContinuationContext {
|
||||
protected final boolean myCancellable;
|
||||
protected final List<TaskDescriptor> myQueue;
|
||||
protected final Object myQueueLock;
|
||||
protected volatile boolean myTriggerSuspend;
|
||||
private boolean myTriggerSuspend;
|
||||
protected ProgressIndicator myIndicator;
|
||||
protected final Map<Object, Object> myDisasters;
|
||||
private final List<Consumer<TaskDescriptor>> myTasksPatchers;
|
||||
@@ -53,6 +54,7 @@ abstract class GeneralRunner implements ContinuationContext {
|
||||
myDisasters = new HashMap<Object, Object>();
|
||||
myHandlersMap = new HashMap<Class<? extends Exception>, Consumer<Exception>>();
|
||||
myTasksPatchers = new ArrayList<Consumer<TaskDescriptor>>();
|
||||
myTriggerSuspend = false;
|
||||
}
|
||||
|
||||
public <T extends Exception> void addExceptionHandler(final Class<T> clazz, final Consumer<T> consumer) {
|
||||
@@ -113,7 +115,21 @@ abstract class GeneralRunner implements ContinuationContext {
|
||||
}
|
||||
|
||||
public void suspend() {
|
||||
myTriggerSuspend = true;
|
||||
synchronized (myQueueLock) {
|
||||
myTriggerSuspend = true;
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean getSuspendFlag() {
|
||||
synchronized (myQueueLock) {
|
||||
return myTriggerSuspend;
|
||||
}
|
||||
}
|
||||
|
||||
protected void clearSuspend() {
|
||||
synchronized (myQueueLock) {
|
||||
myTriggerSuspend = false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -241,13 +257,10 @@ abstract class GeneralRunner implements ContinuationContext {
|
||||
ping();
|
||||
}
|
||||
|
||||
// null - no more tasks or suspend
|
||||
// null - no more tasks
|
||||
@Nullable
|
||||
protected TaskDescriptor getNextMatching() {
|
||||
while (true) {
|
||||
if (myTriggerSuspend) {
|
||||
return null;
|
||||
}
|
||||
synchronized (myQueueLock) {
|
||||
if (myQueue.isEmpty()) return null;
|
||||
TaskDescriptor current = myQueue.remove(0);
|
||||
|
||||
@@ -52,7 +52,7 @@ public class SameProgressRunner extends GeneralRunner {
|
||||
|
||||
@Override
|
||||
public void ping() {
|
||||
myTriggerSuspend = false;
|
||||
clearSuspend();
|
||||
if (Thread.currentThread().equals(myInitThread)) {
|
||||
pingInSourceThread();
|
||||
} else {
|
||||
@@ -66,17 +66,16 @@ public class SameProgressRunner extends GeneralRunner {
|
||||
// stop if project is being disposed
|
||||
if (! myProject.isOpen()) return;
|
||||
|
||||
if (getSuspendFlag()) {
|
||||
mySemaphore.down();
|
||||
while (getSuspendFlag()) {
|
||||
mySemaphore.waitFor(500);
|
||||
}
|
||||
}
|
||||
|
||||
final TaskDescriptor current = getNextMatching();
|
||||
if (current == null) {
|
||||
if (myTriggerSuspend) {
|
||||
mySemaphore.down();
|
||||
while (myTriggerSuspend) {
|
||||
mySemaphore.waitFor(500);
|
||||
}
|
||||
continue;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (Where.AWT.equals(current.getWhere())) {
|
||||
|
||||
@@ -40,6 +40,7 @@ public class SeparatePiecesRunner extends GeneralRunner {
|
||||
|
||||
@CalledInAwt
|
||||
public void ping() {
|
||||
clearSuspend();
|
||||
if (! ApplicationManager.getApplication().isDispatchThread()) {
|
||||
Runnable command = new Runnable() {
|
||||
public void run() {
|
||||
@@ -52,15 +53,14 @@ public class SeparatePiecesRunner extends GeneralRunner {
|
||||
}
|
||||
}
|
||||
|
||||
@CalledInAwt
|
||||
private void pingImpl() {
|
||||
while (true) {
|
||||
// stop if project is being disposed
|
||||
if (! myProject.isDefault() && ! myProject.isOpen()) return;
|
||||
if (getSuspendFlag()) return;
|
||||
final TaskDescriptor current = getNextMatching();
|
||||
if (current == null) {
|
||||
synchronized (myQueueLock) {
|
||||
myTriggerSuspend = false;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user