diff options
4 files changed, 62 insertions, 2 deletions
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 5ed7a3d2d..b70794838 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 @@ -84,7 +84,7 @@ public class ThreadNameChangeTests extends AbstractDebugTest { events.get().clear(); resumeToLineBreakpoint(thread, bp2); - TestUtil.waitForJobs(getName(), 100, 3000); + TestUtil.waitForJobs(getName(), 1000, 3000); // expect one single "CHANGE" event for second thread List<DebugEvent> changeEvents = getStateChangeEvents(events, second); diff --git a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/model/JDIDebugModelMessages.java b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/model/JDIDebugModelMessages.java index 4002c5e63..96ab09a9d 100644 --- a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/model/JDIDebugModelMessages.java +++ b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/model/JDIDebugModelMessages.java @@ -61,6 +61,7 @@ public class JDIDebugModelMessages extends NLS { public static String JDIDebugTarget_Unable_to_create_class_prepare_request__3; public static String JDIDebugTarget_Unable_to_retrieve_types___VM_disconnected__4; public static String JDIDebugTarget_0; + public static String JDIDebugTarget_ThreadNameNotifier; public static String JDIFieldVariable_exception_modifying_value; public static String JDIFieldVariable_exception_retrieving_field_name; diff --git a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/model/JDIDebugModelMessages.properties b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/model/JDIDebugModelMessages.properties index c110c4dc6..6c32a5f7d 100644 --- a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/model/JDIDebugModelMessages.properties +++ b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/model/JDIDebugModelMessages.properties @@ -207,3 +207,4 @@ JDIDebugTarget_0=Disconnecting Java Debug Target JDIDebugTarget_1=Error retrieving top level thread groups JDIDebugTarget_2=Unable to retrieve name JDIDebugTarget_4=Unable to retrieve version +JDIDebugTarget_ThreadNameNotifier=Thread name change notifier 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 cd34bb409..bb604cc40 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 @@ -2391,12 +2391,14 @@ public class JDIDebugTarget extends JDIDebugElement implements private static final String METHOD_SIGNATURE = "(Ljava/lang/String;)V"; //$NON-NLS-1$ private EventRequest request; + private ThreadChangeNotifierJob notfierJob; ThreadNameChangeHandler() { String disableListenerSystemProperty = System.getProperty(DISABLE_THREAD_NAME_CHANGE_LISTENER); boolean isDisabled = String.valueOf(Boolean.TRUE).equals(disableListenerSystemProperty); if (!isDisabled) { createRequest(); + notfierJob = new ThreadChangeNotifierJob(); } } @@ -2450,6 +2452,9 @@ public class JDIDebugTarget extends JDIDebugElement implements if (request != null) { removeJDIEventListener(this, request); } + if (notfierJob != null) { + notfierJob.stop(); + } } @Override @@ -2461,7 +2466,7 @@ public class JDIDebugTarget extends JDIDebugElement implements } if (thread != null) { // trigger updates on the thread - DebugPlugin.getDefault().fireDebugEventSet(new DebugEvent[] { new DebugEvent(thread, DebugEvent.CHANGE, DebugEvent.STATE) }); + notfierJob.notifyAboutChange(thread); } // we never suspend the thread return true; @@ -2484,6 +2489,59 @@ public class JDIDebugTarget extends JDIDebugElement implements } } + /** + * Job to throttle thread name change events notification. + */ + class ThreadChangeNotifierJob extends Job { + + private final LinkedHashSet<JDIThread> queue; + + public ThreadChangeNotifierJob() { + super(JDIDebugModelMessages.JDIDebugTarget_ThreadNameNotifier); + setSystem(true); + setPriority(Job.DECORATE); + queue = new LinkedHashSet<>(); + } + + public void notifyAboutChange(JDIThread thread) { + synchronized (queue) { + if (queue.add(thread)) { + // if there are too many threads changing names, they may slow down debugger + int delay = Math.min(1000, 300 * queue.size()); + schedule(delay); + } + } + } + + void stop() { + synchronized (queue) { + queue.clear(); + } + cancel(); + } + + @Override + protected IStatus run(IProgressMonitor monitor) { + DebugEvent[] events; + synchronized (queue) { + events = queue.stream().map(t -> new DebugEvent(t, DebugEvent.CHANGE, DebugEvent.STATE)).toArray(DebugEvent[]::new); + queue.clear(); + } + if (monitor.isCanceled()) { + return Status.CANCEL_STATUS; + } + // Dispatch known events + DebugPlugin.getDefault().fireDebugEventSet(events); + return Status.OK_STATUS; + } + + + @Override + public boolean belongsTo(Object family) { + return family == JDIDebugTarget.this; + } + } + class CleanUpJob extends Job { /** |