mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-08-10 09:45:39 +02:00
Fix problems accessing IExpressions2 outside executor thread (bug 306553)
This commit is contained in:
parent
b6852ffe40
commit
0794acbd0f
3 changed files with 91 additions and 12 deletions
|
@ -13,10 +13,13 @@ package org.eclipse.cdt.dsf.debug.internal.ui.viewmodel;
|
|||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
import org.eclipse.cdt.debug.core.model.ICastToArray;
|
||||
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.Query;
|
||||
import org.eclipse.cdt.dsf.datamodel.AbstractDMEvent;
|
||||
import org.eclipse.cdt.dsf.datamodel.DMContexts;
|
||||
import org.eclipse.cdt.dsf.debug.service.IExpressions.IExpressionChangedDMEvent;
|
||||
|
@ -57,8 +60,51 @@ public class DsfCastToTypeSupport {
|
|||
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() {
|
||||
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 {
|
||||
|
|
|
@ -248,12 +248,10 @@ public class ExpressionVMProvider extends AbstractDMVMProvider
|
|||
VariableVMNode variableNode = new VariableVMNode(this, getSession(), syncvarDataAccess);
|
||||
addChildNodes(variableNode, new IExpressionVMNode[] {variableNode});
|
||||
|
||||
/* Wire up the casting support if the IExpressions2 service is available. */
|
||||
DsfServicesTracker tracker = new DsfServicesTracker(DsfUIPlugin.getBundleContext(), getSession().getId());
|
||||
IExpressions2 expressions2 = tracker.getService(IExpressions2.class);
|
||||
if (expressions2 != null) {
|
||||
variableNode.setCastToTypeSupport(new DsfCastToTypeSupport(getSession(), this, syncvarDataAccess));
|
||||
}
|
||||
/*
|
||||
* Hook up IExpressions2 if it exists.
|
||||
*/
|
||||
hookUpCastingSupport(syncvarDataAccess, variableNode);
|
||||
|
||||
/*
|
||||
* Tell the expression node which sub-nodes it will directly support. It is very important
|
||||
|
@ -273,6 +271,25 @@ public class ExpressionVMProvider extends AbstractDMVMProvider
|
|||
*/
|
||||
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
|
||||
|
|
|
@ -101,17 +101,33 @@ public class VariableVMProvider extends AbstractDMVMProvider
|
|||
addChildNodes(rootNode, new IVMNode[] { subExpressioNode });
|
||||
|
||||
// Wire up the casting support if the IExpressions2 service is available.
|
||||
DsfServicesTracker tracker = new DsfServicesTracker(DsfUIPlugin.getBundleContext(), getSession().getId());
|
||||
IExpressions2 expressions2 = tracker.getService(IExpressions2.class);
|
||||
if (expressions2 != null) {
|
||||
subExpressioNode.setCastToTypeSupport(new DsfCastToTypeSupport(getSession(), this, varAccess));
|
||||
}
|
||||
hookUpCastingSupport(varAccess, subExpressioNode);
|
||||
|
||||
// Configure the sub-expression node to be a child of itself. This way the content
|
||||
// provider will recursively drill-down the variable hierarchy.
|
||||
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
|
||||
public IColumnPresentation createColumnPresentation(IPresentationContext context, Object element) {
|
||||
return new VariableColumnPresentation();
|
||||
|
|
Loading…
Add table
Reference in a new issue