1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-08-13 19:25:38 +02:00

Fix problems accessing IExpressions2 outside executor thread (bug 306553)

This commit is contained in:
Ed Swartz 2010-03-29 13:43:38 +00:00
parent b6852ffe40
commit 0794acbd0f
3 changed files with 91 additions and 12 deletions

View file

@ -13,10 +13,13 @@ package org.eclipse.cdt.dsf.debug.internal.ui.viewmodel;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.concurrent.ExecutionException;
import org.eclipse.cdt.debug.core.model.ICastToArray; import org.eclipse.cdt.debug.core.model.ICastToArray;
import org.eclipse.cdt.debug.core.model.ICastToType; import org.eclipse.cdt.debug.core.model.ICastToType;
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
import org.eclipse.cdt.dsf.concurrent.IDsfStatusConstants; import org.eclipse.cdt.dsf.concurrent.IDsfStatusConstants;
import org.eclipse.cdt.dsf.concurrent.Query;
import org.eclipse.cdt.dsf.datamodel.AbstractDMEvent; import org.eclipse.cdt.dsf.datamodel.AbstractDMEvent;
import org.eclipse.cdt.dsf.datamodel.DMContexts; import org.eclipse.cdt.dsf.datamodel.DMContexts;
import org.eclipse.cdt.dsf.debug.service.IExpressions.IExpressionChangedDMEvent; import org.eclipse.cdt.dsf.debug.service.IExpressions.IExpressionChangedDMEvent;
@ -57,8 +60,51 @@ public class DsfCastToTypeSupport {
this.memento = createCastedExpressionMemento(exprDMC); this.memento = createCastedExpressionMemento(exprDMC);
} }
public class TestExpressions2Query extends Query<Boolean> {
public TestExpressions2Query() {
super();
}
@Override
protected void execute(final DataRequestMonitor<Boolean> rm) {
/*
* We're in another dispatch, so we must guard against executor
* shutdown again.
*/
final DsfSession session = DsfSession.getSession(
dmvmProvider.getSession().getId());
if (session == null) {
cancel(false);
rm.done();
return;
}
DsfServicesTracker tracker = new DsfServicesTracker(
DsfUIPlugin.getBundleContext(), dmvmProvider.getSession().getId());
IExpressions2 expressions2 = tracker.getService(IExpressions2.class);
rm.setData(expressions2 != null);
rm.done();
tracker.dispose();
}
}
private boolean isValid() { private boolean isValid() {
return (serviceTracker.getService(IExpressions2.class) != null && exprDMC != null); TestExpressions2Query query = new TestExpressions2Query();
dmvmProvider.getSession().getExecutor().execute(query);
try {
/*
* Return value is irrelevant, any error would come through with an
* exception.
*/
return query.get();
} catch (InterruptedException e) {
assert false;
return false;
} catch (ExecutionException e) {
return false;
}
} }
private void throwIfNotValid() throws DebugException { private void throwIfNotValid() throws DebugException {

View file

@ -248,12 +248,10 @@ public class ExpressionVMProvider extends AbstractDMVMProvider
VariableVMNode variableNode = new VariableVMNode(this, getSession(), syncvarDataAccess); VariableVMNode variableNode = new VariableVMNode(this, getSession(), syncvarDataAccess);
addChildNodes(variableNode, new IExpressionVMNode[] {variableNode}); addChildNodes(variableNode, new IExpressionVMNode[] {variableNode});
/* Wire up the casting support if the IExpressions2 service is available. */ /*
DsfServicesTracker tracker = new DsfServicesTracker(DsfUIPlugin.getBundleContext(), getSession().getId()); * Hook up IExpressions2 if it exists.
IExpressions2 expressions2 = tracker.getService(IExpressions2.class); */
if (expressions2 != null) { hookUpCastingSupport(syncvarDataAccess, variableNode);
variableNode.setCastToTypeSupport(new DsfCastToTypeSupport(getSession(), this, syncvarDataAccess));
}
/* /*
* Tell the expression node which sub-nodes it will directly support. It is very important * Tell the expression node which sub-nodes it will directly support. It is very important
@ -274,6 +272,25 @@ public class ExpressionVMProvider extends AbstractDMVMProvider
setRootNode(rootNode); setRootNode(rootNode);
} }
private void hookUpCastingSupport(final SyncVariableDataAccess syncvarDataAccess,
final VariableVMNode variableNode) {
try {
getSession().getExecutor().execute(new DsfRunnable() {
public void run() {
DsfServicesTracker tracker = new DsfServicesTracker(DsfUIPlugin.getBundleContext(), getSession().getId());
IExpressions2 expressions2 = tracker.getService(IExpressions2.class);
if (expressions2 != null) {
variableNode.setCastToTypeSupport(new DsfCastToTypeSupport(
getSession(), ExpressionVMProvider.this, syncvarDataAccess));
}
tracker.dispose();
}
});
} catch (RejectedExecutionException e) {
// Session disposed, ignore.
}
}
/** /**
* Finds the expression node which can parse the given expression. This * Finds the expression node which can parse the given expression. This
* method is used by the expression content and model proxy strategies. * method is used by the expression content and model proxy strategies.

View file

@ -101,17 +101,33 @@ public class VariableVMProvider extends AbstractDMVMProvider
addChildNodes(rootNode, new IVMNode[] { subExpressioNode }); addChildNodes(rootNode, new IVMNode[] { subExpressioNode });
// Wire up the casting support if the IExpressions2 service is available. // Wire up the casting support if the IExpressions2 service is available.
DsfServicesTracker tracker = new DsfServicesTracker(DsfUIPlugin.getBundleContext(), getSession().getId()); hookUpCastingSupport(varAccess, subExpressioNode);
IExpressions2 expressions2 = tracker.getService(IExpressions2.class);
if (expressions2 != null) {
subExpressioNode.setCastToTypeSupport(new DsfCastToTypeSupport(getSession(), this, varAccess));
}
// Configure the sub-expression node to be a child of itself. This way the content // Configure the sub-expression node to be a child of itself. This way the content
// provider will recursively drill-down the variable hierarchy. // provider will recursively drill-down the variable hierarchy.
addChildNodes(subExpressioNode, new IVMNode[] { subExpressioNode }); addChildNodes(subExpressioNode, new IVMNode[] { subExpressioNode });
} }
private void hookUpCastingSupport(final SyncVariableDataAccess syncvarDataAccess,
final VariableVMNode variableNode) {
try {
getSession().getExecutor().execute(new DsfRunnable() {
public void run() {
DsfServicesTracker tracker = new DsfServicesTracker(DsfUIPlugin.getBundleContext(), getSession().getId());
IExpressions2 expressions2 = tracker.getService(IExpressions2.class);
if (expressions2 != null) {
variableNode.setCastToTypeSupport(new DsfCastToTypeSupport(
getSession(), VariableVMProvider.this, syncvarDataAccess));
}
tracker.dispose();
}
});
} catch (RejectedExecutionException e) {
// Session disposed, ignore.
}
}
@Override @Override
public IColumnPresentation createColumnPresentation(IPresentationContext context, Object element) { public IColumnPresentation createColumnPresentation(IPresentationContext context, Object element) {
return new VariableColumnPresentation(); return new VariableColumnPresentation();