diff --git a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/viewmodel/launch/DefaultDsfSelectionPolicy.java b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/viewmodel/launch/DefaultDsfSelectionPolicy.java
index a2c691c378f..6f56045e9bd 100644
--- a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/viewmodel/launch/DefaultDsfSelectionPolicy.java
+++ b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/viewmodel/launch/DefaultDsfSelectionPolicy.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2008, 2009 Wind River Systems, Inc. and others.
+ * Copyright (c) 2008, 2010 Wind River Systems, Inc. and others.
* 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
@@ -13,11 +13,14 @@ package org.eclipse.cdt.dsf.debug.ui.viewmodel.launch;
import java.util.concurrent.ExecutionException;
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
+import org.eclipse.cdt.dsf.concurrent.ImmediateExecutor;
import org.eclipse.cdt.dsf.concurrent.Query;
import org.eclipse.cdt.dsf.datamodel.DMContexts;
import org.eclipse.cdt.dsf.datamodel.IDMContext;
import org.eclipse.cdt.dsf.debug.service.IRunControl;
+import org.eclipse.cdt.dsf.debug.service.IRunControl.IContainerDMContext;
import org.eclipse.cdt.dsf.debug.service.IRunControl.IExecutionDMContext;
+import org.eclipse.cdt.dsf.debug.service.IRunControl.IExecutionDMData;
import org.eclipse.cdt.dsf.debug.service.IStack.IFrameDMContext;
import org.eclipse.cdt.dsf.internal.ui.DsfUIPlugin;
import org.eclipse.cdt.dsf.service.DsfServicesTracker;
@@ -99,6 +102,8 @@ public class DefaultDsfSelectionPolicy implements IModelSelectionPolicy {
IRunControl runControl= servicesTracker.getService(IRunControl.class);
if (runControl != null) {
rm.setData(runControl.isSuspended(execContext));
+ } else {
+ rm.setData(false);
}
} finally {
servicesTracker.dispose();
@@ -154,12 +159,86 @@ public class DefaultDsfSelectionPolicy implements IModelSelectionPolicy {
IExecutionDMContext currExecContext= DMContexts.getAncestorOfType(curr, IExecutionDMContext.class);
if (currExecContext != null) {
IExecutionDMContext candExecContext= DMContexts.getAncestorOfType(cand, IExecutionDMContext.class);
- return currExecContext.equals(candExecContext) || !isSticky(existing);
+ return currExecContext.equals(candExecContext) ||
+ !isSticky(existing) ||
+ frameOverrides((IFrameDMContext)curr, (IFrameDMContext)cand);
}
}
}
return !isSticky(existing);
}
+
+ /**
+ * Last test for whether a stack frame overrides another stack frame.
+ * If two stack frames are from the same execution container (process) and
+ * the entire process has stopped (as in all-stop run control), and the
+ * current frame's thread was stopped due to the container stopping, then
+ * the new frame selection should override the current one. This is because
+ * the new thread is most likely a the thread that triggered the container
+ * to stop.
+ * @param curr Currently selected stack frame.
+ * @param cand Candidate stack frame to be selected.
+ * @return true
if the new frame should override current selection.
+ */
+ private boolean frameOverrides(final IFrameDMContext curr, final IFrameDMContext cand) {
+ // We're assuming that frames are from different execution contexts.
+
+ // Check if they are from the same container context:
+ final IContainerDMContext currContContext= DMContexts.getAncestorOfType(curr, IContainerDMContext.class);
+ IContainerDMContext candContContext= DMContexts.getAncestorOfType(cand, IContainerDMContext.class);
+ if (currContContext == null || !currContContext.equals(candContContext)) {
+ // If from different containers, frames should not override each other.
+ return false;
+ }
+
+ Query query = new Query() {
+ @Override
+ protected void execute(final DataRequestMonitor rm) {
+ DsfServicesTracker servicesTracker = new DsfServicesTracker(DsfUIPlugin.getBundleContext(), curr.getSessionId());
+
+ // Check if container is not suspended.
+ IRunControl runControl= servicesTracker.getService(IRunControl.class);
+ if (runControl != null && runControl.isSuspended(currContContext)) {
+ IExecutionDMContext execDmc = DMContexts.getAncestorOfType(curr, IExecutionDMContext.class);
+ // If container is suspended, check whether the current thread was stopped due
+ // to container suspended event.
+ runControl.getExecutionData(
+ execDmc,
+ new DataRequestMonitor(ImmediateExecutor.getInstance(), rm) {
+ @Override
+ protected void handleSuccess() {
+ rm.setData( getData().getStateChangeReason() == IRunControl.StateChangeReason.CONTAINER );
+ rm.done();
+ };
+ });
+ } else {
+ // If container is not suspended it's running, then do not override the selection.
+ rm.setData(false);
+ rm.done();
+ }
+ // In either case, we won't need the services tracker anymore.
+ servicesTracker.dispose();
+ }
+ };
+
+ DsfSession session = DsfSession.getSession(curr.getSessionId());
+ if (session != null) {
+ if (session.getExecutor().isInExecutorThread()) {
+ query.run();
+ } else {
+ session.getExecutor().execute(query);
+ }
+ try {
+ Boolean result = query.get();
+ return result != null && result.booleanValue();
+ } catch (InterruptedException exc) {
+ Thread.currentThread().interrupt();
+ } catch (ExecutionException exc) {
+ DsfUIPlugin.log(exc);
+ }
+ }
+ return false;
+ }
/*
* @see org.eclipse.debug.internal.ui.viewers.model.provisional.IModelSelectionPolicy#replaceInvalidSelection(org.eclipse.jface.viewers.ISelection, org.eclipse.jface.viewers.ISelection)