diff options
7 files changed, 141 insertions, 94 deletions
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 e7a2b1158..d44ca2dbc 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 @@ -31,6 +31,7 @@ import javax.xml.transform.TransformerException; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IAdaptable; import org.eclipse.core.runtime.IConfigurationElement; import org.eclipse.core.runtime.IExtensionPoint; import org.eclipse.core.runtime.IProgressMonitor; @@ -42,7 +43,6 @@ 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; @@ -290,9 +290,28 @@ public class DebugPlugin extends Plugin { private static final int NOTIFY_FILTERS = 0; private static final int NOTIFY_EVENTS = 1; + /** + * An lock object used to indicate no locking was required. + * @since 3.1 + */ + private static Object NULL_LOCK = new Object(); + + /** + * Queue of debug events to fire to listeners. + * @since 3.1 + */ private List fEventQueue = new ArrayList(); + + /** + * Job to fire events to listeners. + * @since 3.1 + */ private EventDispatchJob fEventDispatchJob = new EventDispatchJob(); + /** + * Event dispatch job + * @since 3.1 + */ class EventDispatchJob extends Job { /** @@ -1283,30 +1302,101 @@ public class DebugPlugin extends Plugin { } /** + * Returns a scheduling rule that can be used to schedule a job + * that performs an access operation on the given debug artifact, + * or <code>null</code> if none. * - * @param element - * @return + * @param element debug artifact + * @return a scheduling rule for an access job, or <code>null</code> * @since 3.1 */ - public static ISchedulingRule accessRule(IDebugElement element) { - IDebugRuleFactory factory = (IDebugRuleFactory) element.getAdapter(IDebugRuleFactory.class); - if (factory != null) { - return factory.accessRule(element); - } + public static ISchedulingRule accessRule(Object element) { + if (element instanceof IAdaptable) { + IAdaptable adaptable = (IAdaptable) element; + IDebugRuleFactory factory = (IDebugRuleFactory) adaptable.getAdapter(IDebugRuleFactory.class); + if (factory != null) { + return factory.accessRule(element); + } + } + return null; } /** + * Obtains and returns a lock on the given debug artifact for an + * access operation. This method blocks until the lock is available. + * The lock must be released by the caller via <code>releaseLock(Object)</code>. + * + * @param element debug artifact for which an access lock is required + * @return access lock that must be subsequently released + * @since 3.1 + */ + public static Object getAccessLock(Object element) { + return getLock(accessRule(element)); + } + + /** + * Obtains and returns a lock on the given debug artifact for an + * modify operation. This method blocks until the lock is available. + * The lock must be released by the caller via <code>releaseLock(Object)</code>. + * + * @param element debug artifact for which a modification lock is required + * @return access lock that must be subsequently released + * @since 3.1 + */ + public static Object getModificationLock(Object element) { + return getLock(modificationRule(element)); + } + + /** + * Obtains a lock based on the given scheduling rule, in the + * job manager, and returns an object representing a lock + * that must be subsequently released. If the lock is + * <code>null</code>, no lock is obtained, but a dummy + * lock object is still returned. + * + * @param rule scheduling rule or <code>null</code> + * @return returns a lock that must be subsequently released + * @since 3.1 + */ + private static Object getLock(ISchedulingRule rule) { + if (rule == null) { + return NULL_LOCK; + } + Platform.getJobManager().beginRule(rule, null); + return rule; + } + + /** + * Releases the given lock. Must be called pairwise with + * <code>getAccessLock(Object)</code> or <code>getModificationLock(Object)</code>. * - * @param element - * @return + * @param lock lock to release * @since 3.1 */ - public static ISchedulingRule modificationRule(IDebugElement element) { - IDebugRuleFactory factory = (IDebugRuleFactory) element.getAdapter(IDebugRuleFactory.class); - if (factory != null) { - return factory.modificationRule(element); - } + public static void releaseLock(Object lock) { + if (lock instanceof ISchedulingRule) { + Platform.getJobManager().endRule((ISchedulingRule)lock); + } + } + + /** + * Returns a scheduling rule that can be used to schedule a job + * that performs a modification operation on the given debug artifact, + * or <code>null</code> if none. + * + * @param element debug artifact + * @return a scheduling rule for a modification job, or <code>null</code> + * @since 3.1 + */ + public static ISchedulingRule modificationRule(Object element) { + if (element instanceof IAdaptable) { + IAdaptable adaptable = (IAdaptable) element; + IDebugRuleFactory factory = (IDebugRuleFactory) adaptable.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/DefaultDebugRuleFactory.java b/org.eclipse.debug.core/core/org/eclipse/debug/internal/core/DefaultDebugRuleFactory.java index 7f1a6a7d5..080d791a0 100644 --- 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 @@ -75,17 +75,23 @@ public class DefaultDebugRuleFactory implements IDebugRuleFactory { } /* (non-Javadoc) - * @see org.eclipse.debug.internal.core.IDebugRuleFactory#accessRule(org.eclipse.debug.core.model.IDebugElement) + * @see org.eclipse.debug.internal.core.IDebugRuleFactory#accessRule(java.lang.Object) */ - public ISchedulingRule accessRule(IDebugElement debugElement) { - return new PessimisticRule(debugElement); + public ISchedulingRule accessRule(Object artifact) { + if (artifact instanceof IDebugElement) { + return new PessimisticRule((IDebugElement)artifact); + } + return null; } /* (non-Javadoc) - * @see org.eclipse.debug.internal.core.IDebugRuleFactory#modificationRule(org.eclipse.debug.core.model.IDebugElement) + * @see org.eclipse.debug.internal.core.IDebugRuleFactory#modificationRule(java.lang.Object) */ - public ISchedulingRule modificationRule(IDebugElement debugElement) { - return new PessimisticRule(debugElement); + public ISchedulingRule modificationRule(Object artifact) { + if (artifact instanceof IDebugElement) { + return new PessimisticRule((IDebugElement)artifact); + } + return null; } } 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 index 83a875278..de0c95ae3 100644 --- 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 @@ -11,7 +11,6 @@ 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. @@ -21,18 +20,20 @@ import org.eclipse.debug.core.model.IDebugElement; public interface IDebugRuleFactory { /** - * Returns a scheduling rule used to schedule a job that accesses a debug element. + * Returns a scheduling rule used to schedule a job that accesses a debug artifact, + * or <code>null</code> if none. * - * @param debugElement debug element to be accessed - * @return rule used to schedule a job that accesses a debug element. + * @param artifact debug artifact to be accessed + * @return rule used to schedule a job that accesses an artifact, or <code>null</code> */ - public ISchedulingRule accessRule(IDebugElement debugElement); + public ISchedulingRule accessRule(Object artifact); /** * 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 + * a debug artifact, or <code>null</code> if none. + * + * @param artifact debug artifact to be modified + * @return rule used to schedule a job that modifies an artifact, or <code>null</code> */ - public ISchedulingRule modificationRule(IDebugElement debugElement); + public ISchedulingRule modificationRule(Object artifact); } 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 2be3c4c74..aaa5f1d3c 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,16 +18,11 @@ import java.util.Map; 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; @@ -122,40 +117,16 @@ public class LazyModelPresentation implements IDebugModelPresentation, IDebugEdi */ public String getText(Object element) { String text = null; - ISchedulingRule rule = null; + Object lock = null; try { - rule = beginRule(element); + lock = DebugPlugin.getAccessLock(element); text = getPresentation().getText(element); } finally { - endRule(rule); + DebugPlugin.releaseLock(lock); } 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) */ diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/actions/ResumeActionDelegate.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/actions/ResumeActionDelegate.java index cc8864d7f..7730ff615 100644 --- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/actions/ResumeActionDelegate.java +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/actions/ResumeActionDelegate.java @@ -14,6 +14,7 @@ package org.eclipse.debug.internal.ui.actions; import java.util.Iterator; import org.eclipse.debug.core.DebugException; +import org.eclipse.debug.core.DebugPlugin; import org.eclipse.debug.core.model.IDebugElement; import org.eclipse.debug.core.model.ISuspendResume; import org.eclipse.debug.core.model.IThread; @@ -88,7 +89,9 @@ public class ResumeActionDelegate extends AbstractListenerActionDelegate { protected boolean isEnabledForAllThreads(Object element) { if (element instanceof IDebugElement) { IDebugElement debugElement = (IDebugElement) element; + Object lock = null; try { + lock = DebugPlugin.getAccessLock(debugElement); IThread[] threads = debugElement.getDebugTarget().getThreads(); for (int i = 0; i < threads.length; i++) { if (threads[i].canResume()) { @@ -96,6 +99,8 @@ public class ResumeActionDelegate extends AbstractListenerActionDelegate { } } } catch (DebugException e) { + } finally { + DebugPlugin.releaseLock(lock); } } return false; 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 94f0bbf6a..3b7d5fb02 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,13 +16,10 @@ import java.util.List; 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; @@ -34,8 +31,6 @@ import org.eclipse.ui.IWorkbenchWindow; 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. */ @@ -353,25 +348,5 @@ public abstract class AbstractDebugEventHandler implements IDebugEventSetListene */ 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/launch/LaunchViewEventHandler.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/views/launch/LaunchViewEventHandler.java index 657ba051d..e8a374414 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,7 +16,6 @@ import java.util.HashSet; 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; @@ -586,14 +585,14 @@ public class LaunchViewEventHandler extends AbstractDebugEventHandler implements case DebugEvent.SUSPEND: if (source instanceof IThread) { IThread thread = (IThread)source; - ISchedulingRule rule = null; + Object lock = null; try { - rule = beginAccessRule(thread); + lock = DebugPlugin.getAccessLock(thread); IStackFrame frame = thread.getTopStackFrame(); queueData(frame); } catch (DebugException e) { } finally { - endRule(rule); + DebugPlugin.releaseLock(lock); } } break; @@ -601,10 +600,10 @@ public class LaunchViewEventHandler extends AbstractDebugEventHandler implements if (source instanceof IThread) { // When a thread resumes, try to select another suspended thread // in the same target. - ISchedulingRule rule = null; + Object lock = null; try { IDebugTarget target = ((IThread) source).getDebugTarget(); - rule = beginAccessRule(target); + lock = DebugPlugin.getAccessLock(target); IThread[] threads= target.getThreads(); for (int j = 0; j < threads.length; j++) { IStackFrame frame = threads[j].getTopStackFrame(); @@ -615,7 +614,7 @@ public class LaunchViewEventHandler extends AbstractDebugEventHandler implements } } catch (DebugException e) { } finally { - endRule(rule); + DebugPlugin.releaseLock(lock); } } break; |