diff: simplify rediff logic

* move timer out of queue - it's rarely needed, and has non-obvious behavior
* dispose() is called on EDT now, so we don't need synchronization
This commit is contained in:
Aleksey Pivovarov
2015-05-18 14:16:40 +03:00
parent fa3714af83
commit ca5cc81f35
4 changed files with 18 additions and 63 deletions
@@ -138,7 +138,7 @@ public abstract class CacheDiffRequestChainProcessor extends DiffRequestProcesso
@CalledInAwt
protected void onDispose() {
super.onDispose();
Disposer.dispose(myQueue);
myQueue.abort();
myRequestCache.clear();
}
@@ -31,6 +31,7 @@ import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.util.ProgressWindow;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Disposer;
import com.intellij.util.Alarm;
import com.intellij.util.Function;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.*;
@@ -46,6 +47,7 @@ public abstract class DiffViewerBase implements DiffViewer, DataProvider {
@NotNull protected final ContentDiffRequest myRequest;
@NotNull private final DiffTaskQueue myTaskExecutor = new DiffTaskQueue();
@NotNull private final Alarm myTaskAlarm = new Alarm();
private volatile boolean myDisposed;
public DiffViewerBase(@NotNull DiffContext context, @NotNull ContentDiffRequest request) {
@@ -78,6 +80,7 @@ public abstract class DiffViewerBase implements DiffViewer, DataProvider {
if (myDisposed) return;
myDisposed = true;
abortRediff();
onDispose();
}
};
@@ -90,7 +93,8 @@ public abstract class DiffViewerBase implements DiffViewer, DataProvider {
public final void scheduleRediff() {
if (isDisposed()) return;
myTaskExecutor.abortAndSchedule(new Runnable() {
abortRediff();
myTaskAlarm.addRequest(new Runnable() {
@Override
public void run() {
rediff();
@@ -101,6 +105,7 @@ public abstract class DiffViewerBase implements DiffViewer, DataProvider {
@CalledInAwt
public final void abortRediff() {
myTaskExecutor.abort();
myTaskAlarm.cancelAllRequests();
}
@CalledInAwt
@@ -197,7 +202,7 @@ public abstract class DiffViewerBase implements DiffViewer, DataProvider {
@CalledInAwt
protected void onDispose() {
Disposer.dispose(myTaskExecutor);
Disposer.dispose(myTaskAlarm);
}
@Nullable
@@ -15,64 +15,19 @@
*/
package com.intellij.diff.util;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.util.Disposer;
import com.intellij.util.Alarm;
import com.intellij.util.Function;
import org.jetbrains.annotations.*;
import org.jetbrains.annotations.CalledInAwt;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.concurrent.atomic.AtomicReference;
public class DiffTaskQueue implements Disposable {
@NotNull private final Object LOCK = new Object();
@NotNull private final Alarm myAlarm = new Alarm();
private boolean myDisposed;
@NotNull private final AtomicReference<ProgressIndicator> myProgressIndicator = new AtomicReference<ProgressIndicator>();
@CalledInAny
public void dispose() {
// if EDT is awaiting for background progress in executeAndTryWait - it holds LOCK.
// so we want to try cancel indicator before getting the lock.
cancelProgress();
synchronized (LOCK) {
if (myDisposed) return;
myDisposed = true;
cancelProgress();
Disposer.dispose(myAlarm);
}
}
public class DiffTaskQueue {
@Nullable private ProgressIndicator myProgressIndicator;
@CalledInAwt
public void abort() {
synchronized (LOCK) {
cancelProgress();
myAlarm.cancelAllRequests();
}
}
private void cancelProgress() {
ProgressIndicator indicator = myProgressIndicator.getAndSet(null);
if (indicator != null) indicator.cancel();
}
@CalledInAwt
public void abortAndSchedule(@NotNull final Runnable task, int millis) {
synchronized (LOCK) {
if (myDisposed) return;
abort();
myAlarm.addRequest(new Runnable() {
@Override
public void run() {
synchronized (LOCK) {
if (myDisposed) return;
}
task.run();
}
}, millis);
}
if (myProgressIndicator != null) myProgressIndicator.cancel();
myProgressIndicator = null;
}
@CalledInAwt
@@ -87,11 +42,7 @@ public class DiffTaskQueue implements Disposable {
@Nullable final Runnable onSlowAction,
final int waitMillis,
final boolean forceEDT) {
synchronized (LOCK) {
if (myDisposed) return;
abort();
myProgressIndicator.set(BackgroundTaskUtil.executeAndTryWait(backgroundTask, onSlowAction, waitMillis, forceEDT));
}
abort();
myProgressIndicator = BackgroundTaskUtil.executeAndTryWait(backgroundTask, onSlowAction, waitMillis, forceEDT);
}
}
@@ -31,7 +31,6 @@ import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.util.ProgressWindow;
import com.intellij.openapi.project.DumbAwareAction;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.vcs.changes.actions.diff.ChangeDiffRequestProducer;
import com.intellij.util.Function;
@@ -161,7 +160,7 @@ public abstract class CacheChangeProcessor extends DiffRequestProcessor {
@CalledInAwt
protected void onDispose() {
super.onDispose();
Disposer.dispose(myQueue);
myQueue.abort();
myRequestCache.clear();
}