FrameView refresh fixed: because of alarm some "rebuild" updates could have been lost or substituted with "refresh" updates

This commit is contained in:
Eugene Zhuravlev
2011-09-22 17:14:41 +02:00
parent 51159cdc90
commit 44fc170bb7
3 changed files with 63 additions and 32 deletions
@@ -46,11 +46,15 @@ import com.intellij.openapi.Disposable;
import com.intellij.openapi.actionSystem.ActionManager;
import com.intellij.openapi.actionSystem.ActionPopupMenu;
import com.intellij.openapi.actionSystem.DefaultActionGroup;
import com.intellij.openapi.application.ModalityState;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.ComboBoxWithWidePopup;
import com.intellij.openapi.util.Disposer;
import com.intellij.ui.PopupHandler;
import com.intellij.ui.ScrollPaneFactory;
import com.intellij.util.Alarm;
import com.sun.jdi.ObjectCollectedException;
import com.sun.jdi.VMDisconnectedException;
import javax.swing.*;
import javax.swing.event.ListSelectionEvent;
@@ -63,6 +67,7 @@ import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicLong;
public class FramesPanel extends UpdatableDebuggerView {
@@ -72,7 +77,8 @@ public class FramesPanel extends UpdatableDebuggerView {
private final FramesListener myFramesListener;
private final DebuggerStateManager myStateManager;
private boolean myShowLibraryFrames = DebuggerSettings.getInstance().SHOW_LIBRARY_STACKFRAMES;
private final Alarm myRebuildAlarm = new Alarm(Alarm.ThreadToUse.SWING_THREAD);
public FramesPanel(Project project, DebuggerStateManager stateManager) {
super(project, stateManager);
myStateManager = stateManager;
@@ -164,14 +170,32 @@ public class FramesPanel extends UpdatableDebuggerView {
}
}
/*invoked in swing thread*/
private final AtomicBoolean myPerformFullRebuild = new AtomicBoolean(false);
protected void rebuild(int event) {
final DebuggerContextImpl context = getContext();
final boolean paused = context.getDebuggerSession().isPaused();
myRebuildAlarm.cancelAllRequests();
final boolean isRefresh = event == DebuggerSession.EVENT_REFRESH ||
event == DebuggerSession.EVENT_REFRESH_VIEWS_ONLY ||
event == DebuggerSession.EVENT_THREADS_REFRESH;
if (!paused || !isRefresh) {
if (!isRefresh) {
myPerformFullRebuild.set(true);
}
myRebuildAlarm.addRequest(new Runnable() {
public void run() {
try {
doRebuild(!myPerformFullRebuild.getAndSet(false));
}
catch (VMDisconnectedException e) {
// ignored
}
}
}, 100, ModalityState.NON_MODAL);
}
private void doRebuild(boolean refreshOnly) {
final DebuggerContextImpl context = getContext();
final boolean paused = context.getDebuggerSession().isPaused();
if (!paused || !refreshOnly) {
myThreadsCombo.removeAllItems();
synchronized (myFramesList) {
myFramesLastUpdateTime = getNextStamp();
@@ -182,11 +206,21 @@ public class FramesPanel extends UpdatableDebuggerView {
if (paused) {
final DebugProcessImpl process = context.getDebugProcess();
if (process != null) {
process.getManagerThread().schedule(new RefreshFramePanelCommand(isRefresh && myThreadsCombo.getItemCount() != 0));
process.getManagerThread().schedule(new RefreshFramePanelCommand(refreshOnly && myThreadsCombo.getItemCount() != 0));
}
}
}
@Override
public void dispose() {
try {
Disposer.dispose(myRebuildAlarm);
}
finally {
super.dispose();
}
}
public boolean isShowLibraryFrames() {
return myShowLibraryFrames;
}
@@ -196,7 +230,6 @@ public class FramesPanel extends UpdatableDebuggerView {
myShowLibraryFrames = showLibraryFrames;
rebuild(DebuggerSession.EVENT_CONTEXT);
}
}
private class RefreshFramePanelCommand extends DebuggerContextCommandImpl {
@@ -19,17 +19,20 @@
*/
package com.intellij.debugger.ui.impl;
import com.intellij.debugger.impl.DebuggerSession;
import com.intellij.debugger.impl.DebuggerContextImpl;
import com.intellij.debugger.impl.DebuggerStateManager;
import com.intellij.debugger.ui.impl.watch.DebuggerTree;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.application.ModalityState;
import com.intellij.openapi.keymap.KeymapManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.wm.ex.IdeFocusTraversalPolicy;
import com.intellij.ui.PopupHandler;
import com.intellij.util.Alarm;
import com.intellij.xdebugger.impl.actions.XDebuggerActions;
import com.sun.jdi.VMDisconnectedException;
import javax.swing.*;
import java.awt.*;
@@ -38,6 +41,7 @@ import java.awt.event.KeyEvent;
public abstract class DebuggerTreePanel extends UpdatableDebuggerView implements DataProvider {
public static final DataKey<DebuggerTreePanel> DATA_KEY = DataKey.create("DebuggerPanel");
private final Alarm myRebuildAlarm = new Alarm(Alarm.ThreadToUse.SWING_THREAD);
protected DebuggerTree myTree;
public DebuggerTreePanel(Project project, DebuggerStateManager stateManager) {
@@ -75,15 +79,24 @@ public abstract class DebuggerTreePanel extends UpdatableDebuggerView implements
protected void rebuild(int event) {
DebuggerSession debuggerSession = getContext().getDebuggerSession();
if(debuggerSession == null) {
return;
}
getTree().rebuild(getContext());
myRebuildAlarm.cancelAllRequests();
myRebuildAlarm.addRequest(new Runnable() {
public void run() {
try {
final DebuggerContextImpl context = getContext();
if(context.getDebuggerSession() != null) {
getTree().rebuild(context);
}
}
catch (VMDisconnectedException e) {
// ignored
}
}
}, 100, ModalityState.NON_MODAL);
}
public void dispose() {
Disposer.dispose(myRebuildAlarm);
try {
super.dispose();
}
@@ -23,11 +23,8 @@ import com.intellij.openapi.Disposable;
import com.intellij.openapi.actionSystem.ActionManager;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.ShortcutSet;
import com.intellij.openapi.application.ModalityState;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Disposer;
import com.intellij.util.Alarm;
import com.sun.jdi.VMDisconnectedException;
import javax.swing.*;
import java.awt.*;
@@ -36,9 +33,8 @@ import java.util.ArrayList;
public abstract class UpdatableDebuggerView extends JPanel implements DebuggerView {
private final Project myProject;
private final DebuggerStateManager myStateManager;
protected final Alarm myRebuildAlarm = new Alarm(Alarm.ThreadToUse.SWING_THREAD);
protected volatile boolean myRefreshNeeded = true;
protected final java.util.List<Disposable> myDisposables = new ArrayList<Disposable>();
private volatile boolean myRefreshNeeded = true;
private final java.util.List<Disposable> myDisposables = new ArrayList<Disposable>();
private boolean myUpdateEnabled;
protected UpdatableDebuggerView(final Project project, final DebuggerStateManager stateManager) {
@@ -82,17 +78,7 @@ public abstract class UpdatableDebuggerView extends JPanel implements DebuggerVi
public final void rebuildIfVisible(final int event) {
if(isUpdateEnabled()) {
myRefreshNeeded = false;
myRebuildAlarm.cancelAllRequests();
myRebuildAlarm.addRequest(new Runnable() {
public void run() {
try {
rebuild(event);
}
catch (VMDisconnectedException e) {
// ignored
}
}
}, 100, ModalityState.NON_MODAL);
rebuild(event);
}
else {
myRefreshNeeded = true;
@@ -118,7 +104,6 @@ public abstract class UpdatableDebuggerView extends JPanel implements DebuggerVi
}
public void dispose() {
Disposer.dispose(myRebuildAlarm);
for (Disposable disposable : myDisposables) {
Disposer.dispose(disposable);
}