Bug 536053 - redefine thread name change listener to JDI listener
Moved ThreadNameChangeListener logic to a JDI listener, to avoid
suspending the target JVM whenever a thread in the Debug View should
change its name.
The listener can be disabled by passing an environment variable to
Eclipse:
-Dorg.eclipse.jdt.internal.debug.core.model.ThreadNameChangeListener.disable=true
Change-Id: I9c8e23b2e461de31412b073ef92be09a258f9c8c
Signed-off-by: Simeon Andreev <simeon.danailov.andreev@gmail.com>
diff --git a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/breakpoints/ThreadNameChangeTests.java b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/breakpoints/ThreadNameChangeTests.java
index de4d889..d40f7a7 100644
--- a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/breakpoints/ThreadNameChangeTests.java
+++ b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/breakpoints/ThreadNameChangeTests.java
@@ -28,7 +28,6 @@
import org.eclipse.jdt.debug.core.IJavaThread;
import org.eclipse.jdt.debug.tests.AbstractDebugTest;
import org.eclipse.jdt.debug.tests.TestUtil;
-import org.eclipse.jdt.internal.debug.ui.IJDIPreferencesConstants;
import org.eclipse.jdt.internal.debug.ui.JDIDebugUIPlugin;
import org.eclipse.jface.preference.IPreferenceStore;
@@ -37,6 +36,8 @@
*/
public class ThreadNameChangeTests extends AbstractDebugTest {
+ private static final String DISABLE_THREAD_NAME_CHANGE_LISTENER = "org.eclipse.jdt.internal.debug.core.model.ThreadNameChangeListener.disable";
+
/**
* Constructor
* @param name
@@ -59,8 +60,6 @@
IJavaLineBreakpoint bp2 = createLineBreakpoint(bpLine2, "", typeName + ".java", typeName);
bp1.setSuspendPolicy(IJavaBreakpoint.SUSPEND_THREAD);
bp2.setSuspendPolicy(IJavaBreakpoint.SUSPEND_THREAD);
- boolean oldValue = getPrefStore().getBoolean(IJDIPreferencesConstants.PREF_LISTEN_ON_THREAD_NAME_CHANGES);
- getPrefStore().setValue(IJDIPreferencesConstants.PREF_LISTEN_ON_THREAD_NAME_CHANGES, true);
AtomicReference<List<DebugEvent>> events = new AtomicReference<>(new ArrayList<DebugEvent>());
IDebugEventSetListener listener = new IDebugEventSetListener() {
@Override
@@ -84,7 +83,7 @@
// expect one single "CHANGE" event for second thread
List<DebugEvent> changeEvents = getStateChangeEvents(events, second);
- assertEquals(1, changeEvents.size());
+ assertEquals("unexpected number of events: " + changeEvents, 1, changeEvents.size());
// expect that thread name is changed to "2"
assertEquals("2", second.getName());
@@ -93,7 +92,6 @@
terminateAndRemove(thread);
removeAllBreakpoints();
DebugPlugin.getDefault().removeDebugEventListener(listener);
- getPrefStore().setValue(IJDIPreferencesConstants.PREF_LISTEN_ON_THREAD_NAME_CHANGES, oldValue);
}
}
@@ -103,6 +101,8 @@
* @throws Exception
*/
public void testListenToThreadNameChangeDisabled() throws Exception {
+ System.setProperty(DISABLE_THREAD_NAME_CHANGE_LISTENER, String.valueOf(Boolean.TRUE));
+
String typeName = "ThreadNameChange";
final int bpLine1 = 36;
final int bpLine2 = 40;
@@ -111,8 +111,6 @@
IJavaLineBreakpoint bp2 = createLineBreakpoint(bpLine2, "", typeName + ".java", typeName);
bp1.setSuspendPolicy(IJavaBreakpoint.SUSPEND_THREAD);
bp2.setSuspendPolicy(IJavaBreakpoint.SUSPEND_THREAD);
- boolean oldValue = getPrefStore().getBoolean(IJDIPreferencesConstants.PREF_LISTEN_ON_THREAD_NAME_CHANGES);
- getPrefStore().setValue(IJDIPreferencesConstants.PREF_LISTEN_ON_THREAD_NAME_CHANGES, false);
AtomicReference<List<DebugEvent>> events = new AtomicReference<>(new ArrayList<DebugEvent>());
IDebugEventSetListener listener = new IDebugEventSetListener() {
@Override
@@ -136,7 +134,7 @@
// expect no "CHANGE" events
List<DebugEvent> changeEvents = getStateChangeEvents(events, second);
- assertEquals(0, changeEvents.size());
+ assertEquals("expected no events, instead got: " + changeEvents, 0, changeEvents.size());
// expect that thread name is changed to "2"
assertEquals("2", second.getName());
@@ -145,7 +143,7 @@
terminateAndRemove(thread);
removeAllBreakpoints();
DebugPlugin.getDefault().removeDebugEventListener(listener);
- getPrefStore().setValue(IJDIPreferencesConstants.PREF_LISTEN_ON_THREAD_NAME_CHANGES, oldValue);
+ System.getProperties().remove(DISABLE_THREAD_NAME_CHANGE_LISTENER);
}
}
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 24d0056..6a1db03 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
@@ -23,7 +23,6 @@
import org.eclipse.jdt.debug.core.IJavaThread;
import org.eclipse.jdt.debug.tests.AbstractDebugTest;
import org.eclipse.jdt.internal.debug.core.model.JDIDebugTarget;
-import org.eclipse.jdt.internal.debug.ui.JavaDebugOptionsManager;
/**
* Tests IJavaDebugTarget API
@@ -178,7 +177,6 @@
private List<IBreakpoint> getUserBreakpoints(JDIDebugTarget target) {
List<IBreakpoint> breakpoints = target.getBreakpoints();
- breakpoints.remove(JavaDebugOptionsManager.getDefault().getThreadNameChangeBreakpoint());
return breakpoints;
}
diff --git a/org.eclipse.jdt.debug.ui/plugin.xml b/org.eclipse.jdt.debug.ui/plugin.xml
index 0290a93..7d4b03a 100644
--- a/org.eclipse.jdt.debug.ui/plugin.xml
+++ b/org.eclipse.jdt.debug.ui/plugin.xml
@@ -3614,10 +3614,6 @@
class="org.eclipse.jdt.internal.debug.ui.breakpoints.SuspendOnUncaughtExceptionListener"
id="org.eclipse.jdt.debug.ui.uncaughtExceptionListener">
</breakpointListener>
- <breakpointListener
- class="org.eclipse.jdt.internal.debug.ui.breakpoints.ThreadNameChangeListener"
- id="org.eclipse.jdt.debug.ui.threadNameChangeListener">
- </breakpointListener>
</extension>
<extension
point="org.eclipse.debug.ui.detailPaneFactories">
diff --git a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/IJDIPreferencesConstants.java b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/IJDIPreferencesConstants.java
index e95a611..f401392 100644
--- a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/IJDIPreferencesConstants.java
+++ b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/IJDIPreferencesConstants.java
@@ -33,11 +33,6 @@
public static final String PREF_SUSPEND_ON_COMPILATION_ERRORS = IJavaDebugUIConstants.PLUGIN_ID + ".suspend_on_compilation_errors"; //$NON-NLS-1$
/**
- * Boolean preference controlling whether to listen to thread name changes (while debugging).
- */
- public static final String PREF_LISTEN_ON_THREAD_NAME_CHANGES = IJavaDebugUIConstants.PLUGIN_ID + ".javaDebug.ListenOnThreadNameChanges"; //$NON-NLS-1$
-
- /**
* Boolean preference controlling whether synthetic
* methods are to be filtered when stepping (and step
* filters are enabled).
diff --git a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/JDIDebugUIPreferenceInitializer.java b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/JDIDebugUIPreferenceInitializer.java
index 4246f0f..859781c 100644
--- a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/JDIDebugUIPreferenceInitializer.java
+++ b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/JDIDebugUIPreferenceInitializer.java
@@ -29,7 +29,6 @@
IPreferenceStore store = JDIDebugUIPlugin.getDefault().getPreferenceStore();
store.setDefault(IJDIPreferencesConstants.PREF_SUSPEND_ON_COMPILATION_ERRORS, true);
store.setDefault(IJDIPreferencesConstants.PREF_SUSPEND_ON_UNCAUGHT_EXCEPTIONS, true);
- store.setDefault(IJDIPreferencesConstants.PREF_LISTEN_ON_THREAD_NAME_CHANGES, true);
store.setDefault(IJDIPreferencesConstants.PREF_ALERT_HCR_FAILED, true);
store.setDefault(IJDIPreferencesConstants.PREF_ALERT_HCR_NOT_SUPPORTED, true);
store.setDefault(IJDIPreferencesConstants.PREF_ALERT_OBSOLETE_METHODS, true);
diff --git a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/JavaDebugOptionsManager.java b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/JavaDebugOptionsManager.java
index d229f28..eea88e1 100644
--- a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/JavaDebugOptionsManager.java
+++ b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/JavaDebugOptionsManager.java
@@ -62,7 +62,6 @@
import org.eclipse.jdt.internal.debug.ui.actions.JavaBreakpointPropertiesAction;
import org.eclipse.jdt.internal.debug.ui.breakpoints.SuspendOnCompilationErrorListener;
import org.eclipse.jdt.internal.debug.ui.breakpoints.SuspendOnUncaughtExceptionListener;
-import org.eclipse.jdt.internal.debug.ui.breakpoints.ThreadNameChangeListener;
import org.eclipse.jdt.internal.debug.ui.snippeteditor.ScrapbookLauncher;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.util.IPropertyChangeListener;
@@ -105,11 +104,6 @@
private IJavaExceptionBreakpoint fSuspendOnErrorBreakpoint = null;
/**
- * Breakpoint used to listen on thread name changes
- */
- private IJavaMethodEntryBreakpoint fThreadNameChangeBreakpoint;
-
- /**
* A label provider
*/
private static ILabelProvider fLabelProvider= DebugUITools.newDebugModelPresentation();
@@ -176,18 +170,6 @@
status.add(e.getStatus());
}
- // thread name change breakpoint
- try {
- IJavaMethodEntryBreakpoint bp = JDIDebugModel.createMethodEntryBreakpoint(ResourcesPlugin.getWorkspace().getRoot(), "java.lang.Thread", "setName", //$NON-NLS-1$ //$NON-NLS-2$
- "(Ljava/lang/String;)V", -1, -1, -1, 0, false, null); //$NON-NLS-1$
- bp.setPersisted(false);
- bp.addBreakpointListener(ThreadNameChangeListener.ID_THREAD_CHANGE_NAME_LISTENER);
- setThreadNameChangeBreakpoint(bp);
- }
- catch (CoreException e) {
- status.add(e.getStatus());
- }
-
if (status.getChildren().length == 0) {
return Status.OK_STATUS;
}
@@ -346,15 +328,6 @@
}
notifyTargets(breakpoint, kind);
}
- } else if (property.equals(IJDIPreferencesConstants.PREF_LISTEN_ON_THREAD_NAME_CHANGES)) {
- IBreakpoint breakpoint = getThreadNameChangeBreakpoint();
- if (breakpoint != null) {
- int kind = REMOVED;
- if (isListeningOnThreadNameChanges()) {
- kind = ADDED;
- }
- notifyTargets(breakpoint, kind);
- }
} else if (fgDisplayOptions.contains(property)) {
variableViewSettingsChanged();
} else if (isUseFilterProperty(property)) {
@@ -425,15 +398,6 @@
}
/**
- * Returns whether listening on thread name changes is enabled
- *
- * @return whether listening on thread name changes is enabled
- */
- public boolean isListeningOnThreadNameChanges() {
- return JDIDebugUIPlugin.getDefault().getPreferenceStore().getBoolean(IJDIPreferencesConstants.PREF_LISTEN_ON_THREAD_NAME_CHANGES);
- }
-
- /**
* Sets the breakpoint used to suspend on uncaught exceptions
*
* @param breakpoint exception breakpoint
@@ -443,25 +407,6 @@
}
/**
- * Sets the breakpoint used to listen to thread name changes
- *
- * @param breakpoint
- * method entry breakpoint
- */
- private void setThreadNameChangeBreakpoint(IJavaMethodEntryBreakpoint breakpoint) {
- fThreadNameChangeBreakpoint = breakpoint;
- }
-
- /**
- * Returns the breakpoint used to listen to thread name changes
- *
- * @return method entry breakpoint
- */
- public IJavaMethodEntryBreakpoint getThreadNameChangeBreakpoint() {
- return fThreadNameChangeBreakpoint;
- }
-
- /**
* Returns the breakpoint used to suspend on uncaught exceptions
*
* @return exception breakpoint
@@ -571,11 +516,6 @@
notifyTarget(javaTarget, getSuspendOnCompilationErrorBreakpoint(), ADDED);
}
- // thread name change
- if (isListeningOnThreadNameChanges()) {
- notifyTarget(javaTarget, getThreadNameChangeBreakpoint(), ADDED);
- }
-
// uncaught exception breakpoint
if (isSuspendOnUncaughtExceptions()) {
ILaunchConfiguration launchConfiguration = javaTarget.getLaunch().getLaunchConfiguration();
diff --git a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/breakpoints/ThreadNameChangeListener.java b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/breakpoints/ThreadNameChangeListener.java
deleted file mode 100644
index 56c5b3a..0000000
--- a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/breakpoints/ThreadNameChangeListener.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2017 Andrey Loskutov.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Andrey Loskutov <loskutov@gmx.de> - initial API and implementation
- *******************************************************************************/
-package org.eclipse.jdt.internal.debug.ui.breakpoints;
-
-import org.eclipse.debug.core.DebugEvent;
-import org.eclipse.debug.core.DebugException;
-import org.eclipse.debug.core.DebugPlugin;
-import org.eclipse.jdt.core.dom.Message;
-import org.eclipse.jdt.debug.core.IJavaBreakpoint;
-import org.eclipse.jdt.debug.core.IJavaBreakpointListener;
-import org.eclipse.jdt.debug.core.IJavaDebugTarget;
-import org.eclipse.jdt.debug.core.IJavaLineBreakpoint;
-import org.eclipse.jdt.debug.core.IJavaThread;
-import org.eclipse.jdt.debug.core.IJavaType;
-import org.eclipse.jdt.internal.debug.ui.JDIDebugUIPlugin;
-import org.eclipse.jdt.internal.debug.ui.JavaDebugOptionsManager;
-
-/**
- * Breakpoint listener extension for the "thread name change" breakpoint.
- *
- * @since 3.9
- */
-public class ThreadNameChangeListener implements IJavaBreakpointListener {
-
- public static final String ID_THREAD_CHANGE_NAME_LISTENER = JDIDebugUIPlugin.getUniqueIdentifier() + ".threadNameChangeListener"; //$NON-NLS-1$
-
- @Override
- public void addingBreakpoint(IJavaDebugTarget target, IJavaBreakpoint breakpoint) {
- }
-
- @Override
- public void breakpointHasCompilationErrors(IJavaLineBreakpoint breakpoint, Message[] errors) {
- }
-
- @Override
- public void breakpointHasRuntimeException(IJavaLineBreakpoint breakpoint, DebugException exception) {
- }
-
- @Override
- public int breakpointHit(IJavaThread thread, IJavaBreakpoint breakpoint) {
- JavaDebugOptionsManager manager = JavaDebugOptionsManager.getDefault();
- if (!breakpoint.equals(manager.getThreadNameChangeBreakpoint())) {
- return DONT_CARE;
- }
- if (manager.isListeningOnThreadNameChanges()) {
- // notify debug view to refresh the thread name
- DebugPlugin.getDefault().fireDebugEventSet(new DebugEvent[] { new DebugEvent(thread, DebugEvent.CHANGE, DebugEvent.STATE) });
- }
- return DONT_SUSPEND;
- }
-
- @Override
- public void breakpointInstalled(IJavaDebugTarget target, IJavaBreakpoint breakpoint) {
- }
-
- @Override
- public void breakpointRemoved(IJavaDebugTarget target, IJavaBreakpoint breakpoint) {
- }
-
- @Override
- public int installingBreakpoint(IJavaDebugTarget target, IJavaBreakpoint breakpoint, IJavaType type) {
- return DONT_CARE;
- }
-
-}
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 bd619c8..ab1ea40 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
@@ -33,6 +33,7 @@
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
@@ -93,7 +94,10 @@
import org.eclipse.jdt.internal.debug.core.breakpoints.JavaLineBreakpoint;
import com.ibm.icu.text.MessageFormat;
+import com.sun.jdi.ClassType;
import com.sun.jdi.InternalException;
+import com.sun.jdi.Location;
+import com.sun.jdi.Method;
import com.sun.jdi.ObjectCollectedException;
import com.sun.jdi.ReferenceType;
import com.sun.jdi.ThreadGroupReference;
@@ -103,6 +107,7 @@
import com.sun.jdi.VirtualMachine;
import com.sun.jdi.event.Event;
import com.sun.jdi.event.EventSet;
+import com.sun.jdi.event.LocatableEvent;
import com.sun.jdi.event.ThreadDeathEvent;
import com.sun.jdi.event.ThreadStartEvent;
import com.sun.jdi.event.VMDeathEvent;
@@ -207,6 +212,11 @@
private ThreadStartHandler fThreadStartHandler;
/**
+ * Handles changes in thread names, detected via a breakpoint in {@link java.lang.Thread#setName(String)}.
+ */
+ private ThreadNameChangeHandler fThreadNameChangeHandler;
+
+ /**
* Whether this VM is suspended.
*/
private boolean fSuspended = true;
@@ -597,6 +607,7 @@
*/
protected void initializeRequests() {
setThreadStartHandler(new ThreadStartHandler());
+ setThreadNameChangeHandler(new ThreadNameChangeHandler());
new ThreadDeathHandler();
}
@@ -842,7 +853,7 @@
try {
setDisconnecting(true);
- disposeThreadHandler();
+ disposeThreadHandlers();
VirtualMachine vm = getVM();
if (vm != null) {
vm.dispose();
@@ -863,11 +874,15 @@
/**
* Allows for ThreadStartHandler to do clean up/disposal.
*/
- private void disposeThreadHandler() {
+ private void disposeThreadHandlers() {
ThreadStartHandler handler = getThreadStartHandler();
if (handler != null) {
handler.deleteRequest();
}
+ ThreadNameChangeHandler nameChangeHandler = getThreadNameChangeHandler();
+ if (nameChangeHandler != null) {
+ nameChangeHandler.deleteRequest();
+ }
}
/**
@@ -1747,7 +1762,7 @@
}
try {
setTerminating(true);
- disposeThreadHandler();
+ disposeThreadHandlers();
VirtualMachine vm = getVM();
if (vm != null) {
vm.exit(1);
@@ -2360,6 +2375,93 @@
}
+ /**
+ * Triggers updates on a thread when {@link java.lang.Thread#setName(String)} is called on that thread, in the target JVM.
+ */
+ class ThreadNameChangeHandler implements IJDIEventListener {
+
+ /**
+ * Environment variable that can be passed down to Eclipse, to disable this listener.
+ */
+ private static final String DISABLE_THREAD_NAME_CHANGE_LISTENER = "org.eclipse.jdt.internal.debug.core.model.ThreadNameChangeListener.disable"; //$NON-NLS-1$
+ private static final String TYPE_NAME = "java.lang.Thread"; //$NON-NLS-1$
+ private static final String METHOD_NAME = "setName"; //$NON-NLS-1$
+ private static final String METHOD_SIGNATURE = "(Ljava/lang/String;)V"; //$NON-NLS-1$
+
+ private EventRequest request;
+
+ ThreadNameChangeHandler() {
+ String disableListenerSystemProperty = System.getProperty(DISABLE_THREAD_NAME_CHANGE_LISTENER);
+ boolean isDisabled = String.valueOf(Boolean.TRUE).equals(disableListenerSystemProperty);
+ if (!isDisabled) {
+ createRequest();
+ }
+ }
+
+ /**
+ * Creates a breakpoint request at {@link java.lang.Thread#setName(String)} that doesn't suspend the target JVM.
+ */
+ void createRequest() {
+ EventRequestManager manager = getEventRequestManager();
+ if (manager != null) {
+ try {
+ Location location = setNameMethodLocation();
+ Assert.isNotNull(location, "Unable to locate Thread.setName method in debuggee JVM"); //$NON-NLS-1$
+ request = manager.createBreakpointRequest(location);
+ request.setSuspendPolicy(EventRequest.SUSPEND_NONE);
+ request.enable();
+ addJDIEventListener(this, request);
+ } catch (RuntimeException e) {
+ String errorMessage = "Failed to add thread name change listener to debug target " + JDIDebugTarget.this; //$NON-NLS-1$
+ IStatus errorStatus = new Status(IStatus.ERROR, JDIDebugPlugin.getUniqueIdentifier(), errorMessage, e);
+ JDIDebugPlugin.log(errorStatus);
+ }
+ }
+ }
+
+ private Location setNameMethodLocation() {
+ List<ReferenceType> types = jdiClassesByName(TYPE_NAME);
+ for (ReferenceType type : types) {
+ if (type instanceof ClassType) {
+ Method method = ((ClassType) type).concreteMethodByName(METHOD_NAME, METHOD_SIGNATURE);
+ if (method != null && !method.isNative()) {
+ Location location = method.location();
+ if (location != null && location.codeIndex() != -1) {
+ return location;
+ }
+ }
+ }
+ }
+ return null;
+ }
+
+ void deleteRequest() {
+ if (request != null) {
+ removeJDIEventListener(this, request);
+ }
+ }
+
+ @Override
+ public boolean handleEvent(Event event, JDIDebugTarget target, boolean suspend, EventSet eventSet) {
+ ThreadReference ref = ((LocatableEvent) event).thread();
+ JDIThread thread = findThread(ref);
+ if (thread == null) {
+ thread = target.findThread(ref);
+ }
+ if (thread != null) {
+ // trigger updates on the thread
+ DebugPlugin.getDefault().fireDebugEventSet(new DebugEvent[] { new DebugEvent(thread, DebugEvent.CHANGE, DebugEvent.STATE) });
+ }
+ // we never suspend the thread
+ return true;
+ }
+
+ @Override
+ public void eventSetComplete(Event event, JDIDebugTarget target, boolean suspendVote, EventSet eventSet) {
+ // nothing to do here, we do work in handleEvent
+ }
+ }
+
class CleanUpJob extends Job {
/**
@@ -2401,6 +2503,14 @@
fThreadStartHandler = threadStartHandler;
}
+ private ThreadNameChangeHandler getThreadNameChangeHandler() {
+ return fThreadNameChangeHandler;
+ }
+
+ private void setThreadNameChangeHandler(ThreadNameChangeHandler threadNameChangeHandler) {
+ fThreadNameChangeHandler = threadNameChangeHandler;
+ }
+
/**
* Java debug targets do not support storage retrieval.
*