Bug 79913 - Concurrency support
diff --git a/org.eclipse.debug.core/core/org/eclipse/debug/core/DebugPlugin.java b/org.eclipse.debug.core/core/org/eclipse/debug/core/DebugPlugin.java index 9bf9d4e..e7a2b11 100644 --- a/org.eclipse.debug.core/core/org/eclipse/debug/core/DebugPlugin.java +++ b/org.eclipse.debug.core/core/org/eclipse/debug/core/DebugPlugin.java
@@ -40,13 +40,16 @@ import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.Plugin; import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.jobs.ISchedulingRule; import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.debug.core.model.IDebugElement; import org.eclipse.debug.core.model.IProcess; import org.eclipse.debug.core.model.IValue; import org.eclipse.debug.core.model.RuntimeProcess; import org.eclipse.debug.internal.core.BreakpointManager; import org.eclipse.debug.internal.core.DebugCoreMessages; import org.eclipse.debug.internal.core.ExpressionManager; +import org.eclipse.debug.internal.core.IDebugRuleFactory; import org.eclipse.debug.internal.core.LaunchManager; import org.eclipse.debug.internal.core.ListenerList; import org.eclipse.debug.internal.core.LogicalStructureManager; @@ -286,6 +289,52 @@ */ private static final int NOTIFY_FILTERS = 0; private static final int NOTIFY_EVENTS = 1; + + private List fEventQueue = new ArrayList(); + private EventDispatchJob fEventDispatchJob = new EventDispatchJob(); + + class EventDispatchJob extends Job { + + /** + * Creates a new event dispatch job. + */ + public EventDispatchJob() { + super("Debug Event Dispatch"); + setPriority(Job.INTERACTIVE); + } + /* (non-Javadoc) + * @see org.eclipse.core.runtime.jobs.Job#run(org.eclipse.core.runtime.IProgressMonitor) + */ + protected IStatus run(IProgressMonitor monitor) { + + while (!fEventQueue.isEmpty()) { + DebugEvent[] events = null; + synchronized (fEventQueue) { + if (!fEventQueue.isEmpty()) { + events = (DebugEvent[]) fEventQueue.remove(0); + } + } + if (events != null) { + getEventNotifier().dispatch(events); + } + } + return Status.OK_STATUS; + } + + /* (non-Javadoc) + * @see org.eclipse.core.runtime.jobs.Job#shouldRun() + */ + public boolean shouldRun() { + return shouldSchedule(); + } + /* (non-Javadoc) + * @see org.eclipse.core.internal.jobs.InternalJob#shouldSchedule() + */ + public boolean shouldSchedule() { + return !(isShuttingDown() || fEventListeners == null); + } + + } /** * Returns the singleton instance of the debug plug-in. @@ -352,7 +401,10 @@ public void fireDebugEventSet(DebugEvent[] events) { if (isShuttingDown() || events == null || fEventListeners == null) return; - getEventNotifier().dispatch(events); + synchronized (fEventQueue) { + fEventQueue.add(events); + } + fEventDispatchJob.schedule(); } /** @@ -1229,6 +1281,35 @@ return res; } + + /** + * + * @param element + * @return + * @since 3.1 + */ + public static ISchedulingRule accessRule(IDebugElement element) { + IDebugRuleFactory factory = (IDebugRuleFactory) element.getAdapter(IDebugRuleFactory.class); + if (factory != null) { + return factory.accessRule(element); + } + return null; + } + + /** + * + * @param element + * @return + * @since 3.1 + */ + public static ISchedulingRule modificationRule(IDebugElement element) { + IDebugRuleFactory factory = (IDebugRuleFactory) element.getAdapter(IDebugRuleFactory.class); + if (factory != null) { + return factory.modificationRule(element); + } + return null; + } + }
diff --git a/org.eclipse.debug.core/core/org/eclipse/debug/internal/core/DebugElement.java b/org.eclipse.debug.core/core/org/eclipse/debug/internal/core/DebugElement.java new file mode 100644 index 0000000..d3a0f9c --- /dev/null +++ b/org.eclipse.debug.core/core/org/eclipse/debug/internal/core/DebugElement.java
@@ -0,0 +1,137 @@ +/******************************************************************************* + * Copyright (c) 2000, 2004 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.debug.internal.core; + +import org.eclipse.core.runtime.PlatformObject; +import org.eclipse.debug.core.DebugEvent; +import org.eclipse.debug.core.DebugPlugin; +import org.eclipse.debug.core.ILaunch; +import org.eclipse.debug.core.model.IDebugElement; +import org.eclipse.debug.core.model.IDebugTarget; +import org.eclipse.debug.core.model.IProcess; +import org.eclipse.debug.core.model.IStepFilters; + +/** + * Implementation of common function for debug elements. + * <p> + * Clients may subclass this class. + * </p> + * @since 3.1 + */ +public abstract class DebugElement extends PlatformObject implements IDebugElement { + + private IDebugTarget fTarget; + + /** + * Constructs a debug element referring to an artifact in the given + * debug target. + * + * @param target debug target containing this element + */ + public DebugElement(IDebugTarget target) { + fTarget = target; + } + + /* (non-Javadoc) + * @see org.eclipse.debug.core.model.IDebugElement#getDebugTarget() + */ + public IDebugTarget getDebugTarget() { + return fTarget; + } + + /* (non-Javadoc) + * @see org.eclipse.debug.core.model.IDebugElement#getLaunch() + */ + public ILaunch getLaunch() { + return getDebugTarget().getLaunch(); + } + + /* (non-Javadoc) + * @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class) + */ + public Object getAdapter(Class adapter) { + if (adapter == IDebugElement.class) { + return this; + } + if (adapter == IStepFilters.class) { + return getDebugTarget(); + } + if (adapter == IDebugTarget.class) { + return getDebugTarget(); + } + if (adapter == IDebugRuleFactory.class) { + return DefaultDebugRuleFactory.getDefault(); + } + if (adapter == ILaunch.class) { + return getLaunch(); + } + if (adapter == IProcess.class) { + return getDebugTarget().getProcess(); + } + return super.getAdapter(adapter); + } + + /** + * Fires a debug event. + * + * @param event debug event to fire + */ + protected void fireEvent(DebugEvent event) { + DebugPlugin.getDefault().fireDebugEventSet(new DebugEvent[] {event}); + } + + /** + * Fires a change event for this debug element + * with the specified detail code. + * + * @param detail detail code for the change event, + * such as <code>DebugEvent.STATE</code> or <code>DebugEvent.CONTENT</code> + */ + public void fireChangeEvent(int detail) { + fireEvent(new DebugEvent(this, DebugEvent.CHANGE, detail)); + } + + /** + * Fires a creation event for this debug element. + */ + protected void fireCreationEvent() { + fireEvent(new DebugEvent(this, DebugEvent.CREATE)); + } + + /** + * Fires a resume for this debug element with + * the specified detail code. + * + * @param detail detail code for the resume event, such + * as <code>DebugEvent.STEP_OVER</code> + */ + protected void fireResumeEvent(int detail) { + fireEvent(new DebugEvent(this, DebugEvent.RESUME, detail)); + } + + /** + * Fires a suspend event for this debug element with + * the specified detail code. + * + * @param detail detail code for the suspend event, such + * as <code>DebugEvent.BREAKPOINT</code> + */ + protected void fireSuspendEvent(int detail) { + fireEvent(new DebugEvent(this, DebugEvent.SUSPEND, detail)); + } + + /** + * Fires a terminate event for this debug element. + */ + protected void fireTerminateEvent() { + fireEvent(new DebugEvent(this, DebugEvent.TERMINATE)); + } +}
diff --git a/org.eclipse.debug.core/core/org/eclipse/debug/internal/core/DefaultDebugRuleFactory.java b/org.eclipse.debug.core/core/org/eclipse/debug/internal/core/DefaultDebugRuleFactory.java new file mode 100644 index 0000000..7f1a6a7 --- /dev/null +++ b/org.eclipse.debug.core/core/org/eclipse/debug/internal/core/DefaultDebugRuleFactory.java
@@ -0,0 +1,91 @@ +/******************************************************************************* + * Copyright (c) 2000, 2004 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.debug.internal.core; + +import org.eclipse.core.runtime.jobs.ISchedulingRule; +import org.eclipse.debug.core.model.IDebugElement; +import org.eclipse.debug.core.model.IDebugTarget; + +/** + * Default rule factory returns rules that serialzie access and modification of + * debug elements. + * + * @since 3.1 + */ +public class DefaultDebugRuleFactory implements IDebugRuleFactory { + + private static IDebugRuleFactory fgDefault; + + class PessimisticRule implements ISchedulingRule { + + private IDebugElement fElement; + + PessimisticRule(IDebugElement element) { + fElement = element; + } + + /* (non-Javadoc) + * @see org.eclipse.core.runtime.jobs.ISchedulingRule#contains(org.eclipse.core.runtime.jobs.ISchedulingRule) + */ + public boolean contains(ISchedulingRule rule) { + if (rule instanceof PessimisticRule) { + return isSameTarget((PessimisticRule) rule, this); + } + return false; + } + + /* (non-Javadoc) + * @see org.eclipse.core.runtime.jobs.ISchedulingRule#isConflicting(org.eclipse.core.runtime.jobs.ISchedulingRule) + */ + public boolean isConflicting(ISchedulingRule rule) { + if (rule instanceof PessimisticRule) { + return isSameTarget((PessimisticRule) rule, this); + } + return false; + } + + private boolean isSameTarget(PessimisticRule a, PessimisticRule b) { + IDebugTarget t1 = a.fElement.getDebugTarget(); + IDebugTarget t2 = b.fElement.getDebugTarget(); + return t1 != null && t1.equals(t2); + } + + } + + public static IDebugRuleFactory getDefault() { + if (fgDefault == null) { + fgDefault = new DefaultDebugRuleFactory(); + } + return fgDefault; + } + + /** + * Constucts a rule factory. + */ + DefaultDebugRuleFactory() { + super(); + } + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.core.IDebugRuleFactory#accessRule(org.eclipse.debug.core.model.IDebugElement) + */ + public ISchedulingRule accessRule(IDebugElement debugElement) { + return new PessimisticRule(debugElement); + } + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.core.IDebugRuleFactory#modificationRule(org.eclipse.debug.core.model.IDebugElement) + */ + public ISchedulingRule modificationRule(IDebugElement debugElement) { + return new PessimisticRule(debugElement); + } + +}
diff --git a/org.eclipse.debug.core/core/org/eclipse/debug/internal/core/IDebugRuleFactory.java b/org.eclipse.debug.core/core/org/eclipse/debug/internal/core/IDebugRuleFactory.java new file mode 100644 index 0000000..83a8752 --- /dev/null +++ b/org.eclipse.debug.core/core/org/eclipse/debug/internal/core/IDebugRuleFactory.java
@@ -0,0 +1,38 @@ +/******************************************************************************* + * Copyright (c) 2000, 2004 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.debug.internal.core; + +import org.eclipse.core.runtime.jobs.ISchedulingRule; +import org.eclipse.debug.core.model.IDebugElement; + +/** + * Creates scheduling rules for debug elements. + * + * @since 3.1 + */ +public interface IDebugRuleFactory { + + /** + * Returns a scheduling rule used to schedule a job that accesses a debug element. + * + * @param debugElement debug element to be accessed + * @return rule used to schedule a job that accesses a debug element. + */ + public ISchedulingRule accessRule(IDebugElement debugElement); + + /** + * Returns a scheduling rule used to schedule a job that modifies the state of + * a debug element + * @param debugElement debug element to be modified + * @return rule used to schedule a job that modifies a debug element + */ + public ISchedulingRule modificationRule(IDebugElement debugElement); +}
diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/LazyModelPresentation.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/LazyModelPresentation.java index b59c5e3..2be3c4c 100644 --- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/LazyModelPresentation.java +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/LazyModelPresentation.java
@@ -18,10 +18,16 @@ import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.jobs.ISchedulingRule; +import org.eclipse.debug.core.DebugPlugin; +import org.eclipse.debug.core.model.IDebugElement; +import org.eclipse.debug.core.model.IDebugTarget; import org.eclipse.debug.core.model.IMemoryBlock; import org.eclipse.debug.core.model.IStackFrame; import org.eclipse.debug.core.model.IThread; import org.eclipse.debug.core.model.IValue; +import org.eclipse.debug.internal.core.IDebugRuleFactory; import org.eclipse.debug.internal.core.ListenerList; import org.eclipse.debug.internal.ui.views.memory.IMemoryBlockModelPresentation; import org.eclipse.debug.internal.ui.views.memory.IMemoryRenderingType; @@ -99,17 +105,58 @@ * @see IDebugModelPresentation#getImage(Object) */ public Image getImage(Object element) { - return getPresentation().getImage(element); + Image image = null; + // TODO: causes UI job blocking dialog to appear +// ISchedulingRule rule = null; +// try { +// rule = beginRule(element); + image = getPresentation().getImage(element); +// } finally { +// endRule(rule); +// } + return image; } /** * @see IDebugModelPresentation#getText(Object) */ public String getText(Object element) { - return getPresentation().getText(element); + String text = null; + ISchedulingRule rule = null; + try { + rule = beginRule(element); + text = getPresentation().getText(element); + } finally { + endRule(rule); + } + return text; } /** + * @param rule + */ + private void endRule(ISchedulingRule rule) { + if (rule != null) { + Platform.getJobManager().endRule(rule); + } + } + + /** + * @param element + * @return + */ + private ISchedulingRule beginRule(Object object) { + ISchedulingRule rule = null; + if (object instanceof IDebugElement) { + rule = DebugPlugin.accessRule((IDebugElement)object); + if (rule != null) { + Platform.getJobManager().beginRule(rule, null); + } + } + return rule; + } + + /** * @see IDebugModelPresentation#computeDetail(IValue, IValueDetailListener) */ public void computeDetail(IValue value, IValueDetailListener listener) {
diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/actions/AbstractDebugActionDelegate.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/actions/AbstractDebugActionDelegate.java index 77d8399..7326ebe 100644 --- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/actions/AbstractDebugActionDelegate.java +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/actions/AbstractDebugActionDelegate.java
@@ -16,8 +16,12 @@ import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.MultiStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.jobs.ISchedulingRule; import org.eclipse.core.runtime.jobs.Job; import org.eclipse.debug.core.DebugException; +import org.eclipse.debug.core.model.IDebugElement; +import org.eclipse.debug.internal.core.IDebugRuleFactory; import org.eclipse.debug.internal.ui.DebugUIPlugin; import org.eclipse.debug.ui.IDebugUIConstants; import org.eclipse.jface.action.IAction; @@ -65,14 +69,9 @@ */ protected IWorkbenchWindow fWindow; - /** - * Background job for this action, or <code>null</code> if none. - */ - private DebugRequestJob fBackgroundJob = null; - class DebugRequestJob extends Job { - private Object[] fElements = null; + private Object fElement; /** * Constructs a new job to perform a debug request (for example, step) @@ -80,35 +79,22 @@ * * @param name job name */ - public DebugRequestJob(String name) { + public DebugRequestJob(String name, Object target) { super(name); setPriority(Job.INTERACTIVE); + fElement = target; } /* (non-Javadoc) * @see org.eclipse.core.runtime.jobs.Job#run(org.eclipse.core.runtime.IProgressMonitor) */ protected IStatus run(IProgressMonitor monitor) { - MultiStatus status= - new MultiStatus(DebugUIPlugin.getUniqueIdentifier(), DebugException.REQUEST_FAILED, getStatusMessage(), null); - for (int i = 0; i < fElements.length; i++) { - Object element= fElements[i]; - try { - doAction(element); - } catch (DebugException e) { - status.merge(e.getStatus()); - } + try { + doAction(fElement); + } catch (DebugException e) { + return e.getStatus(); } - return status; - } - - /** - * Sets the selection to operate on. - * - * @param elements - */ - public void setTargets(Object[] elements) { - fElements = elements; + return Status.OK_STATUS; } } @@ -128,7 +114,6 @@ if (getWindow() != null) { getWindow().getSelectionService().removeSelectionListener(IDebugUIConstants.ID_DEBUG_VIEW, this); } - fBackgroundJob = null; } /* (non-Javadoc) @@ -163,11 +148,21 @@ private void runInBackground(IAction action, IStructuredSelection selection) { // disable the action action.setEnabled(false); - if (fBackgroundJob == null) { - fBackgroundJob = new DebugRequestJob(action.getText()); + Iterator iterator = selection.iterator(); + while (iterator.hasNext()) { + Object target = iterator.next(); + ISchedulingRule rule = null; + if (target instanceof IDebugElement) { + IDebugElement element = (IDebugElement) target; + IDebugRuleFactory ruleFactory = (IDebugRuleFactory) element.getAdapter(IDebugRuleFactory.class); + if (ruleFactory != null) { + rule = ruleFactory.modificationRule(element); + } + } + DebugRequestJob job = new DebugRequestJob(action.getText(), target); + job.setRule(rule); + job.schedule(); } - fBackgroundJob.setTargets(selection.toArray()); - fBackgroundJob.schedule(); } /**
diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/views/AbstractDebugEventHandler.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/views/AbstractDebugEventHandler.java index 769f3db..94f0bbf 100644 --- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/views/AbstractDebugEventHandler.java +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/views/AbstractDebugEventHandler.java
@@ -16,10 +16,13 @@ import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.jobs.ISchedulingRule; import org.eclipse.debug.core.DebugEvent; import org.eclipse.debug.core.DebugPlugin; import org.eclipse.debug.core.IDebugEventSetListener; +import org.eclipse.debug.core.model.IDebugElement; import org.eclipse.debug.ui.AbstractDebugView; import org.eclipse.jface.viewers.IBasicPropertyConstants; import org.eclipse.jface.viewers.ITreeContentProvider; @@ -31,6 +34,8 @@ import org.eclipse.ui.PlatformUI; import org.eclipse.ui.progress.UIJob; +import com.ibm.xslt4j.bcel.generic.FADD; + /** * Handles debug events, updating a view and viewer. */ @@ -42,11 +47,16 @@ private AbstractDebugView fView; /** - * Queued debug event sets (arrays of events) to process, or <code>null</code> if none. + * Queued debug event sets (arrays of events) to process. */ private List fEventSetQueue = new ArrayList(); /** + * Queued data associated with event sets. Entries may be <code>null</code>. + */ + private List fDataQueue = new ArrayList(); + + /** * Update job */ private EventProcessingJob fUpdateJob = new EventProcessingJob(); @@ -56,6 +66,8 @@ */ protected static final DebugEvent[] EMPTY_EVENT_SET = new DebugEvent[0]; + private Object NULL = new Object(); + /** * Job to dispatch debug event sets */ @@ -75,6 +87,7 @@ // to avoid blocking the UI thread, process a max of 50 event sets at once while (more && (count < 50)) { DebugEvent[] eventSet = null; + Object data = null; synchronized (fEventSetQueue) { if (fEventSetQueue.isEmpty()) { return Status.OK_STATUS; @@ -82,11 +95,17 @@ eventSet = (DebugEvent[]) fEventSetQueue.remove(0); more = !fEventSetQueue.isEmpty(); } + synchronized (fDataQueue) { + data = fDataQueue.remove(0); + if (data == NULL) { + data = null; + } + } if (isAvailable()) { if (isViewVisible()) { - doHandleDebugEvents(eventSet); + doHandleDebugEvents(eventSet, data); } - updateForDebugEvents(eventSet); + updateForDebugEvents(eventSet, data); } count++; } @@ -132,13 +151,32 @@ if (events.length == 0) { return; } + events = doPreprocessEvents(events); + if (events.length == 0) { + return; + } // add the event set to the queue and schedule update synchronized (fEventSetQueue) { fEventSetQueue.add(events); + synchronized (fDataQueue) { + if (fDataQueue.size() < fEventSetQueue.size()) { + fDataQueue.add(NULL); + } + } } fUpdateJob.schedule(); } + protected void queueData(Object data) { + synchronized (fDataQueue) { + fDataQueue.add(data); + } + } + + protected DebugEvent[] doPreprocessEvents(DebugEvent[] events) { + return events; + } + /** * Filters the given events before processing. * @@ -156,14 +194,14 @@ * updating that must always be performed, even when the view is not * visible. */ - protected void updateForDebugEvents(DebugEvent[] events) { + protected void updateForDebugEvents(DebugEvent[] events, Object data) { } /** * Implementation specific handling of debug events. * Subclasses should override. */ - protected abstract void doHandleDebugEvents(DebugEvent[] events); + protected abstract void doHandleDebugEvents(DebugEvent[] events, Object data); /** * Helper method for inserting the given element - must be called in UI thread @@ -316,5 +354,24 @@ protected void viewBecomesHidden() { } + /** + * + * @param element + * @return + * @since 3.1 + */ + protected ISchedulingRule beginAccessRule(IDebugElement element) { + ISchedulingRule rule = DebugPlugin.accessRule(element); + if (rule != null) { + Platform.getJobManager().beginRule(rule, null); + } + return rule; + } + + protected void endRule(ISchedulingRule rule) { + if (rule != null) { + Platform.getJobManager().endRule(rule); + } + } }
diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/views/DebugViewLabelDecorator.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/views/DebugViewLabelDecorator.java index 71f2a67..6c6119e 100644 --- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/views/DebugViewLabelDecorator.java +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/views/DebugViewLabelDecorator.java
@@ -258,7 +258,8 @@ public LabelJob(String name, IDebugModelPresentation presentation) { super(name); fJobPresentation= presentation; - setRule(this); + // TODO: why was this rule needed? + //setRule(this); setSystem(true); } @@ -284,17 +285,13 @@ * @see org.eclipse.core.runtime.jobs.Job#run(org.eclipse.core.runtime.IProgressMonitor) */ public IStatus run(IProgressMonitor monitor) { - synchronized(DebugViewLabelDecorator.this) { - fNextJob= null; - } - int numElements= fElementQueue.size(); monitor.beginTask(MessageFormat.format(DebugUIViewsMessages.getString("DebugViewLabelDecorator.1"), new String[] { Integer.toString(numElements) }), numElements); //$NON-NLS-1$ while (!fElementQueue.isEmpty() && !monitor.isCanceled()) { StringBuffer message= new StringBuffer(MessageFormat.format(DebugUIViewsMessages.getString("DebugViewLabelDecorator.1"), new String[] { Integer.toString(fElementQueue.size()) })); //$NON-NLS-1$ - if (fNextJob != null) { + //if (fNextJob != null) { message.append(MessageFormat.format(DebugUIViewsMessages.getString("DebugViewLabelDecorator.2"), new String[] { Integer.toString(fNextJob.fElementQueue.size()) })); //$NON-NLS-1$ - } + //} monitor.setTaskName(message.toString()); int blockSize= 10; if (fElementQueue.size() < blockSize) {
diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/views/launch/DeferredDebugElementWorkbenchAdapter.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/views/launch/DeferredDebugElementWorkbenchAdapter.java new file mode 100644 index 0000000..30acb0c --- /dev/null +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/views/launch/DeferredDebugElementWorkbenchAdapter.java
@@ -0,0 +1,47 @@ +/******************************************************************************* + * Copyright (c) 2000, 2004 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.debug.internal.ui.views.launch; + +import org.eclipse.core.runtime.jobs.ISchedulingRule; +import org.eclipse.debug.core.model.IDebugElement; +import org.eclipse.debug.internal.core.IDebugRuleFactory; +import org.eclipse.debug.ui.DebugElementWorkbenchAdapter; +import org.eclipse.ui.progress.IDeferredWorkbenchAdapter; + + +/** + * Default deferred content provider for a debug target + */ +public abstract class DeferredDebugElementWorkbenchAdapter extends DebugElementWorkbenchAdapter implements IDeferredWorkbenchAdapter { + + /* (non-Javadoc) + * @see org.eclipse.ui.progress.IDeferredWorkbenchAdapter#isContainer() + */ + public boolean isContainer() { + return true; + } + + /* (non-Javadoc) + * @see org.eclipse.ui.progress.IDeferredWorkbenchAdapter#getRule(java.lang.Object) + */ + public ISchedulingRule getRule(Object object) { + if (object instanceof IDebugElement) { + IDebugElement element = (IDebugElement)object; + IDebugRuleFactory factory = (IDebugRuleFactory) element.getAdapter(IDebugRuleFactory.class); + if (factory != null) { + return factory.accessRule(element); + } + } + return null; + } + + +}
diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/views/launch/DeferredTarget.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/views/launch/DeferredTarget.java index 42cc723..dcc0b8f 100644 --- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/views/launch/DeferredTarget.java +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/views/launch/DeferredTarget.java
@@ -11,11 +11,9 @@ package org.eclipse.debug.internal.ui.views.launch; import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.jobs.ISchedulingRule; import org.eclipse.debug.core.DebugException; import org.eclipse.debug.core.model.IDebugTarget; import org.eclipse.debug.core.model.IThread; -import org.eclipse.debug.ui.DebugElementWorkbenchAdapter; import org.eclipse.ui.progress.IDeferredWorkbenchAdapter; import org.eclipse.ui.progress.IElementCollector; @@ -23,7 +21,7 @@ /** * Default deferred content provider for a debug target */ -public class DeferredTarget extends DebugElementWorkbenchAdapter implements IDeferredWorkbenchAdapter { +public class DeferredTarget extends DeferredDebugElementWorkbenchAdapter implements IDeferredWorkbenchAdapter { /* (non-Javadoc) * @see org.eclipse.ui.progress.IDeferredWorkbenchAdapter#fetchDeferredChildren(java.lang.Object, org.eclipse.ui.progress.IElementCollector, org.eclipse.core.runtime.IProgressMonitor) @@ -37,20 +35,4 @@ } collector.done(); } - - /* (non-Javadoc) - * @see org.eclipse.ui.progress.IDeferredWorkbenchAdapter#isContainer() - */ - public boolean isContainer() { - return true; - } - - /* (non-Javadoc) - * @see org.eclipse.ui.progress.IDeferredWorkbenchAdapter#getRule(java.lang.Object) - */ - public ISchedulingRule getRule(Object object) { - return null; - } - - }
diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/views/launch/DeferredThread.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/views/launch/DeferredThread.java index 375d774..f7781c9 100644 --- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/views/launch/DeferredThread.java +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/views/launch/DeferredThread.java
@@ -11,11 +11,9 @@ package org.eclipse.debug.internal.ui.views.launch; import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.jobs.ISchedulingRule; import org.eclipse.debug.core.DebugException; import org.eclipse.debug.core.model.IStackFrame; import org.eclipse.debug.core.model.IThread; -import org.eclipse.debug.ui.DebugElementWorkbenchAdapter; import org.eclipse.ui.progress.IDeferredWorkbenchAdapter; import org.eclipse.ui.progress.IElementCollector; @@ -23,7 +21,7 @@ /** * Default deferred content provider for a debug target */ -public class DeferredThread extends DebugElementWorkbenchAdapter implements IDeferredWorkbenchAdapter { +public class DeferredThread extends DeferredDebugElementWorkbenchAdapter implements IDeferredWorkbenchAdapter { /* (non-Javadoc) * @see org.eclipse.ui.progress.IDeferredWorkbenchAdapter#fetchDeferredChildren(java.lang.Object, org.eclipse.ui.progress.IElementCollector, org.eclipse.core.runtime.IProgressMonitor) @@ -38,19 +36,4 @@ collector.done(); } - /* (non-Javadoc) - * @see org.eclipse.ui.progress.IDeferredWorkbenchAdapter#isContainer() - */ - public boolean isContainer() { - return true; - } - - /* (non-Javadoc) - * @see org.eclipse.ui.progress.IDeferredWorkbenchAdapter#getRule(java.lang.Object) - */ - public ISchedulingRule getRule(Object object) { - return null; - } - - }
diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/views/launch/LaunchViewEventHandler.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/views/launch/LaunchViewEventHandler.java index 9c97c3d..657ba05 100644 --- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/views/launch/LaunchViewEventHandler.java +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/views/launch/LaunchViewEventHandler.java
@@ -16,6 +16,7 @@ import java.util.Map; import java.util.Set; +import org.eclipse.core.runtime.jobs.ISchedulingRule; import org.eclipse.debug.core.DebugEvent; import org.eclipse.debug.core.DebugException; import org.eclipse.debug.core.DebugPlugin; @@ -29,7 +30,6 @@ import org.eclipse.debug.core.model.IThread; import org.eclipse.debug.internal.ui.DebugUIPlugin; import org.eclipse.debug.internal.ui.views.AbstractDebugEventHandler; -import org.eclipse.jface.viewers.ITreeContentProvider; /** * Handles debug events, updating the launch view and viewer. @@ -84,7 +84,7 @@ /** * @see AbstractDebugEventHandler#doHandleDebugEvents(DebugEvent[]) */ - protected void doHandleDebugEvents(DebugEvent[] events) { + protected void doHandleDebugEvents(DebugEvent[] events, Object data) { fThreadTimer.handleDebugEvents(events); Object suspendee = null; for (int i = 0; i < events.length; i++) { @@ -103,19 +103,24 @@ fThreadTimer.getTimedOutThreads().remove(source); remove(source); } else { + Object parent = null; if (source instanceof IDebugTarget) { clearSourceSelection(source); + parent = ((IDebugTarget)source).getLaunch(); + } else if (source instanceof IProcess) { + parent = ((IProcess)source).getLaunch(); } - Object parent = ((ITreeContentProvider)getTreeViewer().getContentProvider()).getParent(source); - refresh(parent); + if (parent != null) { + refresh(parent); + } } break; case DebugEvent.RESUME : - doHandleResumeEvent(event, source); + doHandleResumeEvent(event, source, data); break; case DebugEvent.SUSPEND : if (suspendee == null || !suspendee.equals(source)) { - doHandleSuspendEvent(source, event); + doHandleSuspendEvent(source, event, data); suspendee = source; } break; @@ -146,7 +151,7 @@ /** * Handles the given resume event with the given source. */ - protected void doHandleResumeEvent(DebugEvent event, Object source) { + protected void doHandleResumeEvent(DebugEvent event, Object source, Object data) { if (!event.isEvaluation()) { clearSourceSelection(source); } @@ -161,18 +166,9 @@ } refresh(source); if (source instanceof IThread) { - // When a thread resumes, try to select another suspended thread - // in the same target. - try { - IThread[] threads= ((IThread) source).getDebugTarget().getThreads(); - for (int i = 0; i < threads.length; i++) { - IStackFrame frame = threads[i].getTopStackFrame(); - if (frame != null) { - selectAndReveal(frame); - return; - } - } - } catch (DebugException e) { + if (data instanceof IStackFrame) { + selectAndReveal(data); + return; } selectAndReveal(source); return; @@ -191,7 +187,7 @@ clearSourceSelection(thread); } - protected void doHandleSuspendEvent(Object element, DebugEvent event) { + protected void doHandleSuspendEvent(Object element, DebugEvent event, Object data) { IThread thread= getThread(element); if (thread != null) { fThreadTimer.stopTimer(thread); @@ -205,7 +201,7 @@ } } if (element instanceof IThread) { - doHandleSuspendThreadEvent((IThread)element, event, wasTimedOut); + doHandleSuspendThreadEvent((IThread)element, event, wasTimedOut, data); return; } refresh(element); @@ -214,7 +210,7 @@ /** * Updates the given thread for the given suspend event. */ - protected void doHandleSuspendThreadEvent(IThread thread, DebugEvent event, boolean wasTimedOut) { + protected void doHandleSuspendThreadEvent(IThread thread, DebugEvent event, boolean wasTimedOut, Object data) { // if the thread has already resumed, do nothing if (!thread.isSuspended() || !isAvailable()) { return; @@ -223,48 +219,48 @@ // do not update source selection for evaluation events boolean evaluationEvent = event.isEvaluation(); + // get the top frame + IStackFrame frame = null; + if (data instanceof IStackFrame) { + frame = (IStackFrame) data; + } + // if the top frame is the same, only update labels and images, and re-select // the frame to display source - try { - IStackFrame frame = thread.getTopStackFrame(); - if (frame != null && frame.equals(fLastStackFrame)) { - if (wasTimedOut) { - getLaunchViewer().updateStackFrameImages(thread); - } - getLaunchViewer().update(new Object[] {thread, frame}, null); - if (!evaluationEvent) { - getLaunchViewer().deferExpansion(thread); - getLaunchViewer().setDeferredSelection(frame); - } else if (wasTimedOut) { - getLaunchView().showEditorForCurrentSelection(); - } - return; + if (frame != null && frame.equals(fLastStackFrame)) { + if (wasTimedOut) { + getLaunchViewer().updateStackFrameImages(thread); } - } catch (DebugException e) { + getLaunchViewer().update(new Object[] {thread, frame}, null); + if (!evaluationEvent) { + getLaunchViewer().deferExpansion(thread); + getLaunchViewer().setDeferredSelection(frame); + } else if (wasTimedOut) { + getLaunchView().showEditorForCurrentSelection(); + } + return; } - try { - fLastStackFrame = thread.getTopStackFrame(); + if (frame != null) { + fLastStackFrame = frame; // Auto-expand the thread. Only select the thread if this wasn't the end // of an evaluation getLaunchView().autoExpand(thread, false); if (fLastStackFrame != null) { getLaunchView().autoExpand(fLastStackFrame, !evaluationEvent); } - } catch (DebugException e) { - fLastStackFrame = null; } } /** * @see AbstractDebugEventHandler#updateForDebugEvents(DebugEvent[]) */ - protected void updateForDebugEvents(DebugEvent[] events) { - super.updateForDebugEvents(events); + protected void updateForDebugEvents(DebugEvent[] events, Object data) { + super.updateForDebugEvents(events, data); if (isViewVisible()) { return; } - doHandleDebugEvents(events); + doHandleDebugEvents(events, null); } /** @@ -579,4 +575,52 @@ getView().asyncExec(r); } + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.views.AbstractDebugEventHandler#doPreprocessEvents(org.eclipse.debug.core.DebugEvent[]) + */ + protected DebugEvent[] doPreprocessEvents(DebugEvent[] events) { + for (int i = 0; i < events.length; i++) { + DebugEvent event = events[i]; + Object source = event.getSource(); + switch (event.getKind()) { + case DebugEvent.SUSPEND: + if (source instanceof IThread) { + IThread thread = (IThread)source; + ISchedulingRule rule = null; + try { + rule = beginAccessRule(thread); + IStackFrame frame = thread.getTopStackFrame(); + queueData(frame); + } catch (DebugException e) { + } finally { + endRule(rule); + } + } + break; + case DebugEvent.RESUME: + if (source instanceof IThread) { + // When a thread resumes, try to select another suspended thread + // in the same target. + ISchedulingRule rule = null; + try { + IDebugTarget target = ((IThread) source).getDebugTarget(); + rule = beginAccessRule(target); + IThread[] threads= target.getThreads(); + for (int j = 0; j < threads.length; j++) { + IStackFrame frame = threads[j].getTopStackFrame(); + if (frame != null) { + queueData(frame); + break; + } + } + } catch (DebugException e) { + } finally { + endRule(rule); + } + } + break; + } + } + return events; + } }
diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/views/variables/VariablesViewEventHandler.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/views/variables/VariablesViewEventHandler.java index 5f6a831..57436cf 100644 --- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/views/variables/VariablesViewEventHandler.java +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/views/variables/VariablesViewEventHandler.java
@@ -35,7 +35,7 @@ /** * @see AbstractDebugEventHandler#handleDebugEvents(DebugEvent[]) */ - protected void doHandleDebugEvents(DebugEvent[] events) { + protected void doHandleDebugEvents(DebugEvent[] events, Object data) { for (int i = 0; i < events.length; i++) { DebugEvent event = events[i]; switch (event.getKind()) { @@ -55,7 +55,7 @@ /** * @see AbstractDebugEventHandler#updateForDebugEvents(DebugEvent[]) */ - protected void updateForDebugEvents(DebugEvent[] events) { + protected void updateForDebugEvents(DebugEvent[] events, Object data) { for (int i = 0; i < events.length; i++) { DebugEvent event = events[i]; switch (event.getKind()) {