IDEA-171479 Fix bug when a debug process leaked after session stopped

This commit is contained in:
Vitaliy.Bibaev
2017-04-14 16:06:35 +03:00
parent 7696c02712
commit bd88e84a94
2 changed files with 32 additions and 15 deletions
@@ -253,12 +253,9 @@ public class ClassesFilteredView extends BorderLayoutPanel implements Disposable
myDebugSessionListener = new MyDebuggerSessionListener();
debugSession.addSessionListener(myDebugSessionListener, this);
mySingleAlarm = new SingleAlarmWithMutableDelay(() -> {
final SuspendContextImpl suspendContext = debugProcess.getDebuggerContext().getSuspendContext();
if (suspendContext != null) {
ApplicationManager.getApplication().invokeLater(() -> myTable.setBusy(true));
managerThread.schedule(new MyUpdateClassesCommand(suspendContext));
}
mySingleAlarm = new SingleAlarmWithMutableDelay(suspendContext -> {
ApplicationManager.getApplication().invokeLater(() -> myTable.setBusy(true));
suspendContext.getDebugProcess().getManagerThread().schedule(new MyUpdateClassesCommand(suspendContext));
}, this);
mySingleAlarm.setDelay((int)TimeUnit.MILLISECONDS.toMillis(500));
@@ -336,8 +333,12 @@ public class ClassesFilteredView extends BorderLayoutPanel implements Disposable
if (debugSession != null) {
final DebugProcess debugProcess = DebuggerManager.getInstance(myProject)
.getDebugProcess(debugSession.getDebugProcess().getProcessHandler());
if (debugProcess != null && debugProcess.isAttached()) {
mySingleAlarm.cancelAndRequest();
if (debugProcess != null && debugProcess.isAttached() && debugProcess instanceof DebugProcessImpl) {
final DebugProcessImpl process = (DebugProcessImpl)debugProcess;
final SuspendContextImpl context = process.getDebuggerContext().getSuspendContext();
if (context != null) {
mySingleAlarm.cancelAndRequest(context);
}
}
}
}, x -> myProject.isDisposed());
@@ -15,16 +15,19 @@
*/
package com.intellij.debugger.memory.utils;
import com.intellij.debugger.engine.SuspendContextImpl;
import com.intellij.openapi.Disposable;
import com.intellij.util.Alarm;
import org.jetbrains.annotations.NotNull;
public class SingleAlarmWithMutableDelay extends Alarm {
private final Runnable myTask;
public class SingleAlarmWithMutableDelay {
private final Alarm myAlarm;
private final Task myTask;
private volatile int myDelayMillis;
public SingleAlarmWithMutableDelay(@NotNull Runnable task, @NotNull Disposable parentDisposable) {
super(ThreadToUse.POOLED_THREAD, parentDisposable);
public SingleAlarmWithMutableDelay(@NotNull Task task, @NotNull Disposable parentDisposable) {
myAlarm = new Alarm(Alarm.ThreadToUse.POOLED_THREAD, parentDisposable);
myTask = task;
}
@@ -32,10 +35,23 @@ public class SingleAlarmWithMutableDelay extends Alarm {
myDelayMillis = millis;
}
public void cancelAndRequest() {
if (!isDisposed()) {
public void cancelAndRequest(@NotNull SuspendContextImpl suspendContext) {
if (!myAlarm.isDisposed()) {
cancelAllRequests();
addRequest(myTask, myDelayMillis);
addRequest(() -> myTask.run(suspendContext));
}
}
public void cancelAllRequests() {
myAlarm.cancelAllRequests();
}
private void addRequest(@NotNull Runnable runnable) {
myAlarm.addRequest(runnable, myDelayMillis);
}
@FunctionalInterface
public interface Task {
void run(@NotNull SuspendContextImpl suspendContext);
}
}