Bug 516043 - Ignore "disconnected" exceptions during disconnect
Introduced "fDisconnecting" flag, with similar implementation/behavior
on disconnect() and disconnected() as "fTerminating" and
terminate()/terminated(). isAvailable() checks this flag now.
Change-Id: Iab361cd22799971253ee756b4a52d1594faa87c8
Signed-off-by: Andrey Loskutov <loskutov@gmx.de>
diff --git a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/core/JavaDebugTargetTests.java b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/core/JavaDebugTargetTests.java
index e45d6e0..82681a9 100644
--- a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/core/JavaDebugTargetTests.java
+++ b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/core/JavaDebugTargetTests.java
@@ -10,9 +10,12 @@
*******************************************************************************/
package org.eclipse.jdt.debug.tests.core;
+import java.lang.reflect.Method;
+
import org.eclipse.jdt.debug.core.IJavaDebugTarget;
import org.eclipse.jdt.debug.core.IJavaThread;
import org.eclipse.jdt.debug.tests.AbstractDebugTest;
+import org.eclipse.jdt.internal.debug.core.model.JDIDebugTarget;
/**
* Tests IJavaDebugTarget API
@@ -61,4 +64,92 @@
}
}
+ public void testIsAvailable() throws Exception {
+ String typeName = "Breakpoints";
+ createLineBreakpoint(52, typeName);
+
+ IJavaThread thread = null;
+ try {
+ // do not register launch - see bug 130911
+ thread = launchToBreakpoint(typeName, false);
+ assertNotNull("Breakpoint not hit within timeout period", thread);
+ JDIDebugTarget target = (JDIDebugTarget) thread.getDebugTarget();
+ assertTrue(target.isAvailable());
+ JDIDebugTargetProxy proxy = new JDIDebugTargetProxy(target);
+ assertTrue(proxy.isAvailable());
+ assertFalse(proxy.isDisconnecting());
+ assertFalse(proxy.isTerminating());
+
+ proxy.setDisconnecting(true);
+ assertFalse(proxy.isAvailable());
+ assertTrue(proxy.isDisconnecting());
+ assertFalse(proxy.isTerminating());
+
+ proxy.setDisconnecting(false);
+ assertTrue(proxy.isAvailable());
+ assertFalse(proxy.isDisconnecting());
+ assertFalse(proxy.isTerminating());
+
+ proxy.setTerminating(true);
+ assertFalse(proxy.isAvailable());
+ assertFalse(proxy.isDisconnecting());
+ assertTrue(proxy.isTerminating());
+
+ proxy.setTerminating(false);
+ assertTrue(proxy.isAvailable());
+ assertFalse(proxy.isDisconnecting());
+ assertFalse(proxy.isTerminating());
+
+ terminateAndRemove(thread);
+ assertFalse(proxy.isAvailable());
+ assertFalse(proxy.isDisconnecting());
+ assertFalse(proxy.isTerminating());
+ }
+ finally {
+ terminateAndRemove(thread);
+ removeAllBreakpoints();
+ }
+ }
+
+ static private class JDIDebugTargetProxy {
+
+ private JDIDebugTarget target;
+
+ public JDIDebugTargetProxy(JDIDebugTarget target) {
+ this.target = target;
+ }
+
+ public boolean isAvailable() {
+ return target.isAvailable();
+ }
+
+ public boolean isTerminating() throws Exception {
+ return callBooleanGetMethod("isTerminating");
+ }
+
+ public boolean isDisconnecting() throws Exception {
+ return callBooleanGetMethod("isDisconnecting");
+ }
+
+ public void setTerminating(boolean terminating) throws Exception {
+ callBooleanSetMethod("setTerminating", terminating);
+ }
+
+ public void setDisconnecting(boolean disconnecting) throws Exception {
+ callBooleanSetMethod("setDisconnecting", disconnecting);
+ }
+
+ private boolean callBooleanGetMethod(String name) throws Exception {
+ Method method = JDIDebugTarget.class.getDeclaredMethod(name);
+ method.setAccessible(true);
+ return (Boolean) method.invoke(target);
+ }
+
+ private void callBooleanSetMethod(String name, boolean arg) throws Exception {
+ Method method = JDIDebugTarget.class.getDeclaredMethod(name, boolean.class);
+ method.setAccessible(true);
+ method.invoke(target, Boolean.valueOf(arg));
+ }
+ }
+
}
diff --git a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/model/JDIDebugTarget.java b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/model/JDIDebugTarget.java
index 519f877..5c49532 100644
--- a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/model/JDIDebugTarget.java
+++ b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/model/JDIDebugTarget.java
@@ -160,6 +160,12 @@
* Whether in the process of terminating
*/
private boolean fTerminating;
+
+ /**
+ * Whether in the process of disconnecting
+ */
+ private boolean fDisconnecting;
+
/**
* Whether disconnected
*/
@@ -349,6 +355,7 @@
setTerminated(false);
setTerminating(false);
setDisconnected(false);
+ setDisconnecting(false);
setName(name);
prepareBreakpointsSearchScope();
setBreakpoints(new ArrayList<IBreakpoint>(5));
@@ -862,6 +869,7 @@
}
try {
+ setDisconnecting(true);
disposeThreadHandler();
VirtualMachine vm = getVM();
if (vm != null) {
@@ -1136,7 +1144,7 @@
* Returns whether this target is available to handle VM requests
*/
public boolean isAvailable() {
- return !(isTerminated() || isTerminating() || isDisconnected());
+ return !(isTerminated() || isTerminating() || isDisconnected() || isDisconnecting());
}
/**
@@ -1839,6 +1847,7 @@
*/
@Override
protected void disconnected() {
+ setDisconnecting(false);
if (!isDisconnected()) {
setDisconnected(true);
cleanup();
@@ -2262,6 +2271,14 @@
fTerminating = terminating;
}
+ protected boolean isDisconnecting() {
+ return fDisconnecting;
+ }
+
+ protected void setDisconnecting(boolean disconnecting) {
+ fDisconnecting = disconnecting;
+ }
+
/**
* An event handler for thread start events. When a thread starts in the
* target VM, a model thread is created.