diff: dispose viewers in EDT

avoid 'half-disposed' state with two-step disposing (on pooled and EDT threads)
This commit is contained in:
Aleksey Pivovarov
2015-05-18 14:16:39 +03:00
parent ab2d64247c
commit fa3714af83
9 changed files with 41 additions and 29 deletions
@@ -40,6 +40,10 @@ public interface FrameDiffTool extends DiffTool {
@NotNull
@CalledInAwt
ToolbarComponents init();
@Override
@CalledInAwt
void dispose();
}
class ToolbarComponents {
@@ -968,6 +968,7 @@ public abstract class DiffRequestProcessor implements Disposable {
private interface ViewerState {
void init();
@CalledInAwt
void destroy();
@Nullable
@@ -1008,6 +1009,7 @@ public abstract class DiffRequestProcessor implements Disposable {
}
@Override
@CalledInAwt
public void destroy() {
Disposer.dispose(myViewer);
}
@@ -1058,6 +1060,7 @@ public abstract class DiffRequestProcessor implements Disposable {
}
@Override
@CalledInAwt
public void destroy() {
Disposer.dispose(myViewer);
}
@@ -1130,6 +1133,7 @@ public abstract class DiffRequestProcessor implements Disposable {
}
@Override
@CalledInAwt
public void destroy() {
Disposer.dispose(myViewer);
Disposer.dispose(myWrapperViewer);
@@ -55,6 +55,7 @@ import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.CalledInAwt;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -118,12 +119,14 @@ public class BinaryDiffViewer extends ListenerDiffViewerBase {
}
@Override
@CalledInAwt
protected void onInit() {
super.onInit();
processContextHints();
}
@Override
@CalledInAwt
public void onDispose() {
updateContextHints();
destroyEditorListeners();
@@ -146,6 +146,7 @@ public class OnesideDiffViewer extends TextDiffViewerBase {
}
@Override
@CalledInAwt
protected void onInit() {
super.onInit();
processContextHints();
@@ -154,6 +155,7 @@ public class OnesideDiffViewer extends TextDiffViewerBase {
}
@Override
@CalledInAwt
protected void onDispose() {
updateContextHints();
EditorFactory.getInstance().releaseEditor(myEditor);
@@ -92,6 +92,7 @@ public class SimpleDiffViewer extends TwosideTextDiffViewer {
}
@Override
@CalledInAwt
protected void onInit() {
super.onInit();
myContentPanel.setPainter(new MyDividerPainter());
@@ -99,10 +100,11 @@ public class SimpleDiffViewer extends TwosideTextDiffViewer {
}
@Override
protected void onDisposeAwt() {
@CalledInAwt
protected void onDispose() {
myModifierProvider.destroy();
destroyChangedBlocks();
super.onDisposeAwt();
super.onDispose();
}
@NotNull
@@ -86,6 +86,7 @@ public class SimpleThreesideDiffViewer extends ThreesideTextDiffViewer {
}
@Override
@CalledInAwt
protected void onInit() {
super.onInit();
myContentPanel.setPainter(new MyDividerPainter(Side.LEFT), Side.LEFT);
@@ -94,9 +95,10 @@ public class SimpleThreesideDiffViewer extends ThreesideTextDiffViewer {
}
@Override
protected void onDisposeAwt() {
@CalledInAwt
protected void onDispose() {
destroyChangedBlocks();
super.onDisposeAwt();
super.onDispose();
}
@NotNull
@@ -37,7 +37,6 @@ import org.jetbrains.annotations.*;
import javax.swing.*;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
public abstract class DiffViewerBase implements DiffViewer, DataProvider {
protected static final Logger LOG = Logger.getInstance(DiffViewerBase.class);
@@ -47,7 +46,7 @@ public abstract class DiffViewerBase implements DiffViewer, DataProvider {
@NotNull protected final ContentDiffRequest myRequest;
@NotNull private final DiffTaskQueue myTaskExecutor = new DiffTaskQueue();
@NotNull private final AtomicBoolean myDisposed = new AtomicBoolean(false);
private volatile boolean myDisposed;
public DiffViewerBase(@NotNull DiffContext context, @NotNull ContentDiffRequest request) {
myProject = context.getProject();
@@ -69,22 +68,27 @@ public abstract class DiffViewerBase implements DiffViewer, DataProvider {
}
@Override
@CalledInAwt
public final void dispose() {
if (!myDisposed.compareAndSet(false, true)) return;
if (myDisposed) return;
onDispose();
UIUtil.invokeLaterIfNeeded(new Runnable() {
Runnable doDispose = new Runnable() {
@Override
public void run() {
onDisposeAwt();
if (myDisposed) return;
myDisposed = true;
onDispose();
}
});
};
if (!ApplicationManager.getApplication().isDispatchThread()) LOG.warn(new Throwable("dispose() not from EDT"));
UIUtil.invokeLaterIfNeeded(doDispose);
}
@CalledInAwt
public final void scheduleRediff() {
if (myDisposed.get()) return;
if (isDisposed()) return;
myTaskExecutor.abortAndSchedule(new Runnable() {
@Override
@@ -106,7 +110,7 @@ public abstract class DiffViewerBase implements DiffViewer, DataProvider {
@CalledInAwt
public final void rediff(boolean trySync) {
if (myDisposed.get()) return;
if (isDisposed()) return;
onBeforeRediff();
@@ -148,7 +152,7 @@ public abstract class DiffViewerBase implements DiffViewer, DataProvider {
}
public boolean isDisposed() {
return myDisposed.get();
return myDisposed;
}
//
@@ -191,14 +195,11 @@ public abstract class DiffViewerBase implements DiffViewer, DataProvider {
@NotNull
protected abstract Runnable performRediff(@NotNull ProgressIndicator indicator);
@CalledInAwt
protected void onDispose() {
Disposer.dispose(myTaskExecutor);
}
@CalledInAwt
protected void onDisposeAwt() {
}
@Nullable
protected OpenFileDescriptor getOpenFileDescriptor() {
return null;
@@ -111,21 +111,18 @@ public abstract class ThreesideTextDiffViewer extends TextDiffViewerBase {
}
@Override
@CalledInAwt
protected void onInit() {
super.onInit();
processContextHints();
}
@Override
@CalledInAwt
protected void onDispose() {
updateContextHints();
super.onDispose();
}
@Override
protected void onDisposeAwt() {
destroyEditors();
super.onDisposeAwt();
}
protected void processContextHints() {
@@ -114,21 +114,18 @@ public abstract class TwosideTextDiffViewer extends TextDiffViewerBase {
}
@Override
@CalledInAwt
protected void onInit() {
super.onInit();
processContextHints();
}
@Override
@CalledInAwt
protected void onDispose() {
updateContextHints();
super.onDispose();
}
@Override
protected void onDisposeAwt() {
destroyEditors();
super.onDisposeAwt();
}
protected void processContextHints() {