mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-08-05 15:25:49 +02:00
[243794] - [update policy] VM Cache can save updates after they were canceled.
This commit is contained in:
parent
eeb6b080ef
commit
4edc3e01e0
9 changed files with 329 additions and 132 deletions
5
plugins/org.eclipse.dd.dsf.ui/.options
Normal file
5
plugins/org.eclipse.dd.dsf.ui/.options
Normal file
|
@ -0,0 +1,5 @@
|
|||
org.eclipse.dd.dsf.ui/debug = false
|
||||
org.eclipse.dd.dsf.ui/debug/vm/contentProvider = false
|
||||
org.eclipse.dd.dsf.ui/debug/vm/delta = false
|
||||
org.eclipse.dd.dsf.ui/debug/vm/cache = false
|
||||
org.eclipse.dd.dsf.ui/debug/vm/presentationId =
|
|
@ -10,6 +10,7 @@
|
|||
*******************************************************************************/
|
||||
package org.eclipse.dd.dsf.internal.ui;
|
||||
|
||||
import org.eclipse.core.runtime.Platform;
|
||||
import org.eclipse.ui.plugin.AbstractUIPlugin;
|
||||
import org.osgi.framework.BundleContext;
|
||||
|
||||
|
@ -26,6 +27,8 @@ public class DsfUIPlugin extends AbstractUIPlugin {
|
|||
|
||||
private static BundleContext fgBundleContext;
|
||||
|
||||
public static boolean DEBUG = false;
|
||||
|
||||
/**
|
||||
* The constructor
|
||||
*/
|
||||
|
@ -41,6 +44,7 @@ public class DsfUIPlugin extends AbstractUIPlugin {
|
|||
public void start(BundleContext context) throws Exception {
|
||||
fgBundleContext = context;
|
||||
super.start(context);
|
||||
DEBUG = "true".equals(Platform.getDebugOption("org.eclipse.dd.dsf.ui/debug")); //$NON-NLS-1$//$NON-NLS-2$
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -67,4 +71,15 @@ public class DsfUIPlugin extends AbstractUIPlugin {
|
|||
return fgBundleContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* If the debug flag is set the specified message is printed to the console
|
||||
* @param message
|
||||
*/
|
||||
public static void debug(String message) {
|
||||
if (DEBUG) {
|
||||
System.out.println(message);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -15,15 +15,16 @@ import java.util.HashMap;
|
|||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.ListIterator;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.RejectedExecutionException;
|
||||
|
||||
import org.eclipse.core.runtime.Platform;
|
||||
import org.eclipse.dd.dsf.concurrent.CountingRequestMonitor;
|
||||
import org.eclipse.dd.dsf.concurrent.DataRequestMonitor;
|
||||
import org.eclipse.dd.dsf.concurrent.IDsfStatusConstants;
|
||||
import org.eclipse.dd.dsf.concurrent.RequestMonitor;
|
||||
import org.eclipse.dd.dsf.internal.ui.DsfUIPlugin;
|
||||
import org.eclipse.dd.dsf.ui.concurrent.SimpleDisplayExecutor;
|
||||
import org.eclipse.dd.dsf.ui.concurrent.ViewerDataRequestMonitor;
|
||||
import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenCountUpdate;
|
||||
|
@ -63,6 +64,22 @@ import org.eclipse.swt.widgets.Display;
|
|||
@SuppressWarnings("restriction")
|
||||
abstract public class AbstractVMProvider implements IVMProvider, IVMEventListener
|
||||
{
|
||||
// debug flags
|
||||
public static String DEBUG_PRESENTATION_ID = null;
|
||||
public static boolean DEBUG_CONTENT_PROVIDER = false;
|
||||
public static boolean DEBUG_DELTA = false;
|
||||
|
||||
static {
|
||||
DEBUG_PRESENTATION_ID = Platform.getDebugOption("org.eclipse.dd.dsf.ui/debug/vm/presentationId"); //$NON-NLS-1$
|
||||
if (!DsfUIPlugin.DEBUG || "".equals(DEBUG_PRESENTATION_ID)) { //$NON-NLS-1$
|
||||
DEBUG_PRESENTATION_ID = null;
|
||||
}
|
||||
DEBUG_CONTENT_PROVIDER = DsfUIPlugin.DEBUG && "true".equals( //$NON-NLS-1$
|
||||
Platform.getDebugOption("org.eclipse.dd.dsf.ui/debug/vm/contentProvider")); //$NON-NLS-1$
|
||||
|
||||
DEBUG_DELTA = DsfUIPlugin.DEBUG && "true".equals( //$NON-NLS-1$
|
||||
Platform.getDebugOption("org.eclipse.dd.dsf.ui/debug/vm/delta")); //$NON-NLS-1$
|
||||
}
|
||||
|
||||
/** Reference to the VM adapter that owns this provider */
|
||||
private final AbstractVMAdapter fVMAdapter;
|
||||
|
@ -126,12 +143,22 @@ abstract public class AbstractVMProvider implements IVMProvider, IVMEventListene
|
|||
*/
|
||||
private IRootVMNode fRootNode;
|
||||
|
||||
private class ModelProxyEventQueue {
|
||||
private boolean fProcessingEvent = false;
|
||||
private List<Object> fEventQueue = new LinkedList<Object>();
|
||||
private class EventInfo {
|
||||
EventInfo(Object event, RequestMonitor rm) {
|
||||
fEvent = event;
|
||||
fClientRm = rm;
|
||||
}
|
||||
Object fEvent;
|
||||
RequestMonitor fClientRm;
|
||||
}
|
||||
|
||||
private Map<IVMModelProxy, ModelProxyEventQueue> fEventQueues = new HashMap<IVMModelProxy, ModelProxyEventQueue>();
|
||||
private class ModelProxyEventQueue {
|
||||
EventInfo fCurrentEvent = null;
|
||||
RequestMonitor fCurrentRm = null;
|
||||
List<EventInfo> fEventQueue = new LinkedList<EventInfo>();
|
||||
}
|
||||
|
||||
private Map<IVMModelProxy, ModelProxyEventQueue> fProxyEventQueues = new HashMap<IVMModelProxy, ModelProxyEventQueue>();
|
||||
|
||||
/**
|
||||
* Constructs the view model provider for given DSF session. The
|
||||
|
@ -220,25 +247,47 @@ abstract public class AbstractVMProvider implements IVMProvider, IVMEventListene
|
|||
|
||||
for (final IVMModelProxy proxyStrategy : activeModelProxies) {
|
||||
if (proxyStrategy.isDeltaEvent(event)) {
|
||||
if (!fEventQueues.containsKey(proxyStrategy)) {
|
||||
fEventQueues.put(proxyStrategy, new ModelProxyEventQueue());
|
||||
if (DEBUG_DELTA && (DEBUG_PRESENTATION_ID == null || getPresentationContext().getId().equals(DEBUG_PRESENTATION_ID))) {
|
||||
DsfUIPlugin.debug("eventReceived(proxyRoot = " + proxyStrategy .getRootElement() + ", event = " + event + ")" ); //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$
|
||||
}
|
||||
final ModelProxyEventQueue queue = fEventQueues.get(proxyStrategy);
|
||||
if (queue.fProcessingEvent) {
|
||||
if (!queue.fEventQueue.isEmpty()) {
|
||||
for (ListIterator<Object> itr = queue.fEventQueue.listIterator(queue.fEventQueue.size() - 1); itr.hasPrevious();) {
|
||||
Object eventToSkip = itr.previous();
|
||||
if (canSkipHandlingEvent(event, eventToSkip)) {
|
||||
itr.remove();
|
||||
if (!fProxyEventQueues.containsKey(proxyStrategy)) {
|
||||
fProxyEventQueues.put(proxyStrategy, new ModelProxyEventQueue());
|
||||
if (DEBUG_DELTA && (DEBUG_PRESENTATION_ID == null || getPresentationContext().getId().equals(DEBUG_PRESENTATION_ID))) {
|
||||
DsfUIPlugin.debug("eventQueued(proxyRoot = " + proxyStrategy.getRootElement() + ", event = " + event + ")" ); //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$
|
||||
}
|
||||
}
|
||||
final ModelProxyEventQueue queue = fProxyEventQueues.get(proxyStrategy);
|
||||
if (queue.fCurrentEvent != null) {
|
||||
assert queue.fCurrentRm != null;
|
||||
// Iterate through the events in the queue and check if
|
||||
// they can be skipped. If they can be skipped, then just
|
||||
// mark their RM as done. Stop iterating through the queue
|
||||
// if an event that cannot be skipped is encountered.
|
||||
while (!queue.fEventQueue.isEmpty()) {
|
||||
EventInfo eventToSkipInfo = queue.fEventQueue.get(queue.fEventQueue.size() - 1);
|
||||
|
||||
if (canSkipHandlingEvent(event, eventToSkipInfo.fEvent)) {
|
||||
if (DEBUG_DELTA && (DEBUG_PRESENTATION_ID == null || getPresentationContext().getId().equals(DEBUG_PRESENTATION_ID))) {
|
||||
DsfUIPlugin.debug("eventSkipped(proxyRoot = " + proxyStrategy.getRootElement() + ", event = " + eventToSkipInfo + ")" ); //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$
|
||||
}
|
||||
queue.fEventQueue.remove(queue.fEventQueue.size() - 1);
|
||||
eventToSkipInfo.fClientRm.done();
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
// If the queue is empty check if the current event
|
||||
// being processed can be skipped. If so, cancel its
|
||||
// processing
|
||||
if (queue.fEventQueue.isEmpty() && canSkipHandlingEvent(event, queue.fCurrentEvent.fEvent)) {
|
||||
if (DEBUG_DELTA && (DEBUG_PRESENTATION_ID == null || getPresentationContext().getId().equals(DEBUG_PRESENTATION_ID))) {
|
||||
DsfUIPlugin.debug("eventCancelled(proxyRoot = " + proxyStrategy.getRootElement() + ", event = " + queue.fCurrentEvent + ")" ); //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$
|
||||
}
|
||||
crm.done();
|
||||
queue.fEventQueue.add(event);
|
||||
queue.fCurrentRm.cancel();
|
||||
}
|
||||
queue.fEventQueue.add(new EventInfo(event, crm));
|
||||
} else {
|
||||
doHandleEvent(queue, proxyStrategy, event, crm);
|
||||
doHandleEvent(queue, proxyStrategy, new EventInfo(event, crm));
|
||||
}
|
||||
} else {
|
||||
crm.done();
|
||||
|
@ -247,28 +296,30 @@ abstract public class AbstractVMProvider implements IVMProvider, IVMEventListene
|
|||
|
||||
// Clean up model proxies that were removed.
|
||||
List<IVMModelProxy> activeProxies = getActiveModelProxies();
|
||||
for (Iterator<IVMModelProxy> itr = fEventQueues.keySet().iterator(); itr.hasNext();) {
|
||||
for (Iterator<IVMModelProxy> itr = fProxyEventQueues.keySet().iterator(); itr.hasNext();) {
|
||||
if (!activeProxies.contains(itr.next())) {
|
||||
itr.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void doHandleEvent(final ModelProxyEventQueue queue, final IVMModelProxy proxyStrategy, final Object event, final RequestMonitor rm) {
|
||||
queue.fProcessingEvent = true;
|
||||
handleEvent(
|
||||
proxyStrategy, event,
|
||||
new RequestMonitor(getExecutor(), null) {
|
||||
private void doHandleEvent(final ModelProxyEventQueue queue, final IVMModelProxy proxyStrategy, final EventInfo eventInfo) {
|
||||
assert queue.fCurrentEvent == null && queue.fCurrentRm == null;
|
||||
|
||||
queue.fCurrentEvent = eventInfo;
|
||||
queue.fCurrentRm = new RequestMonitor(getExecutor(), null) {
|
||||
@Override
|
||||
protected void handleCompleted() {
|
||||
queue.fProcessingEvent = false;
|
||||
queue.fCurrentEvent = null;
|
||||
queue.fCurrentRm = null;
|
||||
if (!queue.fEventQueue.isEmpty()) {
|
||||
doHandleEvent(queue, proxyStrategy, queue.fEventQueue.remove(0), rm);
|
||||
} else {
|
||||
rm.done();
|
||||
EventInfo eventInfo = queue.fEventQueue.remove(0);
|
||||
doHandleEvent(queue, proxyStrategy, eventInfo);
|
||||
}
|
||||
eventInfo.fClientRm.done();
|
||||
}
|
||||
});
|
||||
};
|
||||
handleEvent(proxyStrategy, eventInfo.fEvent, queue.fCurrentRm);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -287,6 +338,9 @@ abstract public class AbstractVMProvider implements IVMProvider, IVMEventListene
|
|||
*/
|
||||
protected void handleEvent(final IVMModelProxy proxyStrategy, final Object event, RequestMonitor rm) {
|
||||
if (!proxyStrategy.isDisposed()) {
|
||||
if (DEBUG_DELTA && (DEBUG_PRESENTATION_ID == null || getPresentationContext().getId().equals(DEBUG_PRESENTATION_ID))) {
|
||||
DsfUIPlugin.debug("eventProcessing(proxyRoot = " + proxyStrategy.getRootElement() + ", event = " + event + ")" ); //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$
|
||||
}
|
||||
proxyStrategy.createDelta(
|
||||
event,
|
||||
new DataRequestMonitor<IModelDelta>(getExecutor(), rm) {
|
||||
|
@ -294,6 +348,9 @@ abstract public class AbstractVMProvider implements IVMProvider, IVMEventListene
|
|||
public void handleCompleted() {
|
||||
if (isSuccess()) {
|
||||
proxyStrategy.fireModelChanged(getData());
|
||||
if (DEBUG_DELTA && (DEBUG_PRESENTATION_ID == null || getPresentationContext().getId().equals(DEBUG_PRESENTATION_ID))) {
|
||||
DsfUIPlugin.debug("eventDeltaFired(proxyRoot = " + proxyStrategy.getRootElement() + ", event = " + event + ")" ); //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$
|
||||
}
|
||||
}
|
||||
super.handleCompleted();
|
||||
}
|
||||
|
@ -439,6 +496,9 @@ abstract public class AbstractVMProvider implements IVMProvider, IVMEventListene
|
|||
IHasChildrenUpdate[] updateProxies = new IHasChildrenUpdate[updates.length];
|
||||
for (int i = 0; i < updates.length; i++) {
|
||||
final IHasChildrenUpdate update = updates[i];
|
||||
if (DEBUG_CONTENT_PROVIDER && (DEBUG_PRESENTATION_ID == null || getPresentationContext().getId().equals(DEBUG_PRESENTATION_ID))) {
|
||||
DsfUIPlugin.debug("updateNodeHasChildren(node = " + node + ", update = " + update + ")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
|
||||
}
|
||||
updateProxies[i] = new VMHasChildrenUpdate(
|
||||
update,
|
||||
new ViewerDataRequestMonitor<Boolean>(getExecutor(), updates[i]) {
|
||||
|
@ -451,6 +511,9 @@ abstract public class AbstractVMProvider implements IVMProvider, IVMEventListene
|
|||
@Override
|
||||
protected void handleErrorOrWarning() {
|
||||
if (getStatus().getCode() == IDsfStatusConstants.NOT_SUPPORTED) {
|
||||
if (DEBUG_CONTENT_PROVIDER && (DEBUG_PRESENTATION_ID == null || getPresentationContext().getId().equals(DEBUG_PRESENTATION_ID))) {
|
||||
DsfUIPlugin.debug("not-supported:updateNodeHasChildren(node = " + node + ", update = " + update + ")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
|
||||
}
|
||||
updateNode(
|
||||
node,
|
||||
new VMChildrenUpdate(
|
||||
|
@ -484,6 +547,9 @@ abstract public class AbstractVMProvider implements IVMProvider, IVMEventListene
|
|||
* a cache.
|
||||
*/
|
||||
public void updateNode(final IVMNode node, final IChildrenCountUpdate update) {
|
||||
if (DEBUG_CONTENT_PROVIDER && (DEBUG_PRESENTATION_ID == null || getPresentationContext().getId().equals(DEBUG_PRESENTATION_ID))) {
|
||||
DsfUIPlugin.debug("updateNodeChildCount(node = " + node + ", update = " + update + ")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
|
||||
}
|
||||
node.update(new IChildrenCountUpdate[] {
|
||||
new VMChildrenCountUpdate(
|
||||
update,
|
||||
|
@ -497,6 +563,9 @@ abstract public class AbstractVMProvider implements IVMProvider, IVMEventListene
|
|||
@Override
|
||||
protected void handleErrorOrWarning() {
|
||||
if (getStatus().getCode() == IDsfStatusConstants.NOT_SUPPORTED) {
|
||||
if (DEBUG_CONTENT_PROVIDER && (DEBUG_PRESENTATION_ID == null || getPresentationContext().getId().equals(DEBUG_PRESENTATION_ID))) {
|
||||
DsfUIPlugin.debug("not-supported:updateNodeChildCount(node = " + node + ", update = " + update + ")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
|
||||
}
|
||||
updateNode(
|
||||
node,
|
||||
new VMChildrenUpdate(
|
||||
|
@ -527,6 +596,9 @@ abstract public class AbstractVMProvider implements IVMProvider, IVMEventListene
|
|||
* a cache.
|
||||
*/
|
||||
public void updateNode(IVMNode node, IChildrenUpdate update) {
|
||||
if (DEBUG_CONTENT_PROVIDER && (DEBUG_PRESENTATION_ID == null || getPresentationContext().getId().equals(DEBUG_PRESENTATION_ID))) {
|
||||
DsfUIPlugin.debug("updateNodeChildren(node = " + node + ", update = " + update + ")");
|
||||
}
|
||||
node.update(new IChildrenUpdate[] { update });
|
||||
}
|
||||
|
||||
|
|
|
@ -17,7 +17,6 @@ import java.util.Map;
|
|||
|
||||
import org.eclipse.core.runtime.ISafeRunnable;
|
||||
import org.eclipse.core.runtime.ListenerList;
|
||||
import org.eclipse.core.runtime.Platform;
|
||||
import org.eclipse.core.runtime.SafeRunner;
|
||||
import org.eclipse.dd.dsf.concurrent.ConfinedToDsfExecutor;
|
||||
import org.eclipse.dd.dsf.concurrent.CountingRequestMonitor;
|
||||
|
@ -63,16 +62,6 @@ public class DefaultVMModelProxyStrategy implements IVMModelProxy {
|
|||
private ListenerList fListeners = new ListenerList();
|
||||
private IDoubleClickListener fDoubleClickListener;
|
||||
|
||||
/**
|
||||
* Debug flag indicating whether the deltas should be traced in stdout.
|
||||
*/
|
||||
private static boolean DEBUG_DELTAS = false;
|
||||
|
||||
static {
|
||||
DEBUG_DELTAS = DebugUIPlugin.DEBUG && "true".equals( //$NON-NLS-1$
|
||||
Platform.getDebugOption("org.eclipse.debug.ui/debug/viewers/deltas")); //$NON-NLS-1$
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates this model proxy strategy for the given provider.
|
||||
*/
|
||||
|
@ -122,9 +111,6 @@ public class DefaultVMModelProxyStrategy implements IVMModelProxy {
|
|||
public void fireModelChanged(IModelDelta delta) {
|
||||
final IModelDelta root = getRootDelta(delta);
|
||||
Object[] listeners = getListeners();
|
||||
if (DEBUG_DELTAS) {
|
||||
DebugUIPlugin.debug("FIRE DELTA: " + delta.toString()); //$NON-NLS-1$
|
||||
}
|
||||
for (int i = 0; i < listeners.length; i++) {
|
||||
final IModelChangedListener listener = (IModelChangedListener) listeners[i];
|
||||
ISafeRunnable safeRunnable = new ISafeRunnable() {
|
||||
|
@ -353,6 +339,8 @@ public class DefaultVMModelProxyStrategy implements IVMModelProxy {
|
|||
// super-class to resort to the default behavior which may add a
|
||||
// delta for every element in this node.
|
||||
buildChildDeltasForAllContexts(node, event, parentDelta, nodeOffset, rm);
|
||||
} else {
|
||||
super.handleCompleted();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -388,13 +376,13 @@ public class DefaultVMModelProxyStrategy implements IVMModelProxy {
|
|||
node,
|
||||
new VMChildrenUpdate(
|
||||
parentDelta, getVMProvider().getPresentationContext(), -1, -1,
|
||||
new DataRequestMonitor<List<Object>>(getVMProvider().getExecutor(), null) {
|
||||
new DataRequestMonitor<List<Object>>(getVMProvider().getExecutor(), requestMonitor) {
|
||||
@Override
|
||||
protected void handleCompleted() {
|
||||
protected void handleSuccess() {
|
||||
// Check for an empty list of elements. If it's empty then we
|
||||
// don't have to call the children nodes, so return here.
|
||||
// No need to propagate error, there's no means or need to display it.
|
||||
if (!isSuccess() || getData().isEmpty()) {
|
||||
if (getData().isEmpty()) {
|
||||
requestMonitor.done();
|
||||
return;
|
||||
}
|
||||
|
@ -490,13 +478,12 @@ public class DefaultVMModelProxyStrategy implements IVMModelProxy {
|
|||
parentDelta, getVMProvider().getPresentationContext(), -1, -1,
|
||||
new DataRequestMonitor<List<Object>>(getVMProvider().getExecutor(), requestMonitor) {
|
||||
@Override
|
||||
protected void handleCompleted() {
|
||||
protected void handleSuccess() {
|
||||
if (fDisposed) return;
|
||||
|
||||
// Check for an empty list of elements. If it's empty then we
|
||||
// don't have to call the children nodes, so return here.
|
||||
// No need to propagate error, there's no means or need to display it.
|
||||
if (!isSuccess() || getData().size() == 0) {
|
||||
if (getData().size() == 0) {
|
||||
requestMonitor.done();
|
||||
return;
|
||||
}
|
||||
|
@ -556,7 +543,7 @@ public class DefaultVMModelProxyStrategy implements IVMModelProxy {
|
|||
node, delta, calculateOffsets,
|
||||
new DataRequestMonitor<Map<IVMNode, Integer>>(getVMProvider().getExecutor(), requestMonitor) {
|
||||
@Override
|
||||
protected void handleCompleted() {
|
||||
protected void handleSuccess() {
|
||||
final CountingRequestMonitor multiRm = new CountingRequestMonitor(getVMProvider().getExecutor(), requestMonitor);
|
||||
int multiRmCount = 0;
|
||||
|
||||
|
|
|
@ -45,6 +45,11 @@ public class VMChildrenCountUpdate extends VMViewerUpdate implements IChildrenCo
|
|||
fCountRequestMonitor.setData(count);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "VMChildrenCountUpdate: " + getElement(); //$NON-NLS-1$
|
||||
}
|
||||
|
||||
@Override
|
||||
public void done() {
|
||||
assert isCanceled() || fCountRequestMonitor.getData() != null || !fCountRequestMonitor.isSuccess();
|
||||
|
|
|
@ -13,11 +13,7 @@ package org.eclipse.dd.dsf.ui.viewmodel;
|
|||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.core.runtime.IStatus;
|
||||
import org.eclipse.core.runtime.Status;
|
||||
import org.eclipse.dd.dsf.concurrent.DataRequestMonitor;
|
||||
import org.eclipse.dd.dsf.concurrent.IDsfStatusConstants;
|
||||
import org.eclipse.dd.dsf.internal.ui.DsfUIPlugin;
|
||||
import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate;
|
||||
import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta;
|
||||
import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext;
|
||||
|
@ -92,7 +88,7 @@ public class VMChildrenUpdate extends VMViewerUpdate implements IChildrenUpdate
|
|||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "VMElementsUpdate for elements under parent = " + getElement() + ", in range " + getOffset() + " -> " + (getOffset() + getLength()); //$NON-NLS-1$ //$NON-NLS-2$//$NON-NLS-3$
|
||||
return "VMChildrenUpdate:" + getElement() + " {"+ getOffset() + "->" + (getOffset() + getLength()) + "}"; //$NON-NLS-1$ //$NON-NLS-2$//$NON-NLS-3$ //$NON-NLS-4$
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -105,32 +101,21 @@ public class VMChildrenUpdate extends VMViewerUpdate implements IChildrenUpdate
|
|||
* A flexible hierarchy bug/optimization causes query with incorrect
|
||||
* IChildrenUpdate[] array length.
|
||||
*
|
||||
* We found this while deleting a register node. Example:
|
||||
*
|
||||
* the register view displays:
|
||||
* The problem manifests itself while deleting a register node.
|
||||
* For example, if the register view displays:
|
||||
* PC
|
||||
* EAX
|
||||
* EBX
|
||||
* ECX
|
||||
* EDX
|
||||
* And EBX is deleted, forcing a refresh, the viewer will query
|
||||
* for IChildrenUpdate[5] and IChildrenCountUpdate at the same time.
|
||||
*
|
||||
* we delete EBX and force a context refresh.
|
||||
*
|
||||
* flexible hierarchy queries for IChildrenUpdate[5] and IChildrenCountUpdate at
|
||||
* the same time.
|
||||
*
|
||||
* VMElementsUpdate, used by VMCache to wrap the IChildrenUpdate, generates an
|
||||
* IStatus.ERROR with message "Incomplete elements of updates" when fElements
|
||||
* count (provided by service) does not match the length provided by the original
|
||||
* update query.
|
||||
*
|
||||
* Workaround, always set the elements array in the request monitor, but still set
|
||||
* the error status.
|
||||
* To avoid this problem do not generate an error if the list of
|
||||
* children is smaller than the list of requested indexes. Also,
|
||||
* do not check if any of the elements are null.
|
||||
*/
|
||||
rm.setData(fElements);
|
||||
if (rm.isSuccess() && fLength != -1 && fElements.size() != fLength) {
|
||||
rm.setStatus(new Status(IStatus.ERROR, DsfUIPlugin.PLUGIN_ID, IDsfStatusConstants.REQUEST_FAILED, "Incomplete elements of updates", null)); //$NON-NLS-1$
|
||||
}
|
||||
super.done();
|
||||
}
|
||||
|
||||
|
|
|
@ -46,6 +46,11 @@ public class VMHasChildrenUpdate extends VMViewerUpdate implements IHasChildrenU
|
|||
fHasElemsRequestMonitor.setData(hasChildren);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "VMHasChildrenUpdate: " + getElement(); //$NON-NLS-1$
|
||||
}
|
||||
|
||||
@Override
|
||||
public void done() {
|
||||
assert isCanceled() || fHasElemsRequestMonitor.getData() != null || !fHasElemsRequestMonitor.isSuccess();
|
||||
|
|
|
@ -20,6 +20,7 @@ import java.util.Map;
|
|||
import java.util.concurrent.Executor;
|
||||
|
||||
import org.eclipse.core.runtime.IStatus;
|
||||
import org.eclipse.core.runtime.Platform;
|
||||
import org.eclipse.dd.dsf.concurrent.CountingRequestMonitor;
|
||||
import org.eclipse.dd.dsf.concurrent.DataRequestMonitor;
|
||||
import org.eclipse.dd.dsf.concurrent.DsfRunnable;
|
||||
|
@ -27,6 +28,7 @@ import org.eclipse.dd.dsf.concurrent.RequestMonitor;
|
|||
import org.eclipse.dd.dsf.datamodel.IDMContext;
|
||||
import org.eclipse.dd.dsf.datamodel.IDMData;
|
||||
import org.eclipse.dd.dsf.datamodel.IDMService;
|
||||
import org.eclipse.dd.dsf.internal.ui.DsfUIPlugin;
|
||||
import org.eclipse.dd.dsf.ui.concurrent.ViewerCountingRequestMonitor;
|
||||
import org.eclipse.dd.dsf.ui.concurrent.ViewerDataRequestMonitor;
|
||||
import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMAdapter;
|
||||
|
@ -53,6 +55,14 @@ import org.eclipse.jface.viewers.TreePath;
|
|||
@SuppressWarnings("restriction")
|
||||
public class AbstractCachingVMProvider extends AbstractVMProvider implements ICachingVMProvider {
|
||||
|
||||
// debug flags
|
||||
public static boolean DEBUG_CACHE = false;
|
||||
|
||||
static {
|
||||
DEBUG_CACHE = DsfUIPlugin.DEBUG && "true".equals( //$NON-NLS-1$
|
||||
Platform.getDebugOption("org.eclipse.dd.dsf.ui/debug/vm/cache")); //$NON-NLS-1$
|
||||
}
|
||||
|
||||
private static final int MAX_CACHE_SIZE = 1000;
|
||||
|
||||
/**
|
||||
|
@ -139,14 +149,60 @@ public class AbstractCachingVMProvider extends AbstractVMProvider implements ICa
|
|||
super(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Counter of flush operations performed on this entry. It is used
|
||||
* by caching update operations to make sure that an update which
|
||||
* was issued for a given entry is still valid for that entry when
|
||||
* it is completed by the node.
|
||||
*/
|
||||
int fFlushCounter = 0;
|
||||
|
||||
/**
|
||||
* Indicates that the data in this cache entry is out of date with
|
||||
* the data on the target.
|
||||
*/
|
||||
Boolean fDirty = false;
|
||||
|
||||
/**
|
||||
* Cached {@link IHasChildrenUpdate} result.
|
||||
*/
|
||||
Boolean fHasChildren = null;
|
||||
|
||||
/**
|
||||
* Cached {@link IChildrenCountUpdate} result.
|
||||
*/
|
||||
Integer fChildrenCount = null;
|
||||
|
||||
/**
|
||||
* Flag indicating that all the children of the given element are
|
||||
* alredy cached.
|
||||
*/
|
||||
boolean fAllChildrenKnown = false;
|
||||
|
||||
/**
|
||||
* Map containing children of this element, keyed by child index.
|
||||
*/
|
||||
Map<Integer,Object> fChildren = null;
|
||||
|
||||
/**
|
||||
* Map of IDMData objects, keyed by the DM context.
|
||||
*/
|
||||
Map<IDMContext,Object> fDataOrStatus = new HashMap<IDMContext,Object>(1);
|
||||
|
||||
/**
|
||||
* Previous known value of the DM data objects.
|
||||
*/
|
||||
Map<IDMContext,IDMData> fArchiveData = new HashMap<IDMContext,IDMData>(1);;
|
||||
|
||||
void ensureChildrenMap() {
|
||||
if (fChildren == null) {
|
||||
Integer childrenCount = fChildrenCount;
|
||||
childrenCount = childrenCount != null ? childrenCount : 0;
|
||||
int capacity = Math.max((childrenCount.intValue() * 4)/3, 32);
|
||||
fChildren = new HashMap<Integer,Object>(capacity);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return fKey.toString() + " = " + //$NON-NLS-1$
|
||||
|
@ -315,23 +371,38 @@ public class AbstractCachingVMProvider extends AbstractVMProvider implements ICa
|
|||
}
|
||||
|
||||
@Override
|
||||
public void updateNode(IVMNode node, IHasChildrenUpdate[] updates) {
|
||||
public void updateNode(final IVMNode node, IHasChildrenUpdate[] updates) {
|
||||
LinkedList <IHasChildrenUpdate> missUpdates = new LinkedList<IHasChildrenUpdate>();
|
||||
for(final IHasChildrenUpdate update : updates) {
|
||||
// Find or create the cache entry for the element of this update.
|
||||
ElementDataKey key = makeEntryKey(node, update);
|
||||
final ElementDataEntry entry = getElementDataEntry(key);
|
||||
|
||||
if (entry.fHasChildren != null) {
|
||||
// Cache Hit! Just return the value.
|
||||
if (DEBUG_CACHE && (DEBUG_PRESENTATION_ID == null || getPresentationContext().getId().equals(DEBUG_PRESENTATION_ID))) {
|
||||
DsfUIPlugin.debug("cacheHitHasChildren(node = " + node + ", update = " + update + ", " + entry.fHasChildren + ")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
|
||||
}
|
||||
update.setHasChilren(entry.fHasChildren.booleanValue());
|
||||
update.done();
|
||||
} else {
|
||||
// Cache miss! Save the flush counter of the entry and create a proxy update.
|
||||
final int flushCounter = entry.fFlushCounter;
|
||||
missUpdates.add(
|
||||
new VMHasChildrenUpdate(
|
||||
update,
|
||||
new ViewerDataRequestMonitor<Boolean>(getExecutor(), update) {
|
||||
@Override
|
||||
protected void handleCompleted() {
|
||||
// Update completed. Write value to cache only if update successed
|
||||
// and the cache entry wasn't flushed in the mean time.
|
||||
if(isSuccess()) {
|
||||
if (flushCounter == entry.fFlushCounter) {
|
||||
if (DEBUG_CACHE && (DEBUG_PRESENTATION_ID == null || getPresentationContext().getId().equals(DEBUG_PRESENTATION_ID))) {
|
||||
DsfUIPlugin.debug("cacheSavedHasChildren(node = " + node + ", update = " + update + ", " + getData() + ")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
|
||||
}
|
||||
entry.fHasChildren = this.getData();
|
||||
}
|
||||
update.setHasChilren(getData());
|
||||
} else {
|
||||
update.setStatus(getStatus());
|
||||
|
@ -342,26 +413,42 @@ public class AbstractCachingVMProvider extends AbstractVMProvider implements ICa
|
|||
}
|
||||
}
|
||||
|
||||
// Issue all the update proxies with one call.
|
||||
if (!missUpdates.isEmpty()) {
|
||||
super.updateNode(node, missUpdates.toArray(new IHasChildrenUpdate[missUpdates.size()]));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateNode(IVMNode node, final IChildrenCountUpdate update) {
|
||||
public void updateNode(final IVMNode node, final IChildrenCountUpdate update) {
|
||||
// Find or create the cache entry for the element of this update.
|
||||
ElementDataKey key = makeEntryKey(node, update);
|
||||
final ElementDataEntry entry = getElementDataEntry(key);
|
||||
|
||||
if(entry.fChildrenCount != null) {
|
||||
// Cache Hit! Just return the value.
|
||||
if (DEBUG_CACHE && (DEBUG_PRESENTATION_ID == null || getPresentationContext().getId().equals(DEBUG_PRESENTATION_ID))) {
|
||||
DsfUIPlugin.debug("cacheHitChildrenCount(node = " + node + ", update = " + update + ", " + entry.fChildrenCount + ")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
|
||||
}
|
||||
update.setChildCount(entry.fChildrenCount.intValue());
|
||||
update.done();
|
||||
} else {
|
||||
// Cache miss! Save the flush counter of the entry and create a proxy update.
|
||||
final int flushCounter = entry.fFlushCounter;
|
||||
IChildrenCountUpdate updateProxy = new VMChildrenCountUpdate(
|
||||
update,
|
||||
new ViewerDataRequestMonitor<Integer>(getExecutor(), update) {
|
||||
@Override
|
||||
protected void handleCompleted() {
|
||||
// Update completed. Write value to cache only if update successed
|
||||
// and the cache entry wasn't flushed in the mean time.
|
||||
if(isSuccess()) {
|
||||
if (flushCounter == entry.fFlushCounter) {
|
||||
if (DEBUG_CACHE && (DEBUG_PRESENTATION_ID == null || getPresentationContext().getId().equals(DEBUG_PRESENTATION_ID))) {
|
||||
DsfUIPlugin.debug("cacheSavedChildrenCount(node = " + node + ", update = " + update + ", " + getData() + ")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
|
||||
}
|
||||
entry.fChildrenCount = this.getData();
|
||||
}
|
||||
update.setChildCount(getData());
|
||||
} else {
|
||||
update.setStatus(getStatus());
|
||||
|
@ -374,41 +461,37 @@ public class AbstractCachingVMProvider extends AbstractVMProvider implements ICa
|
|||
}
|
||||
|
||||
@Override
|
||||
public void updateNode(IVMNode node, final IChildrenUpdate update) {
|
||||
|
||||
public void updateNode(final IVMNode node, final IChildrenUpdate update) {
|
||||
// Find or create the cache entry for the element of this update.
|
||||
ElementDataKey key = makeEntryKey(node, update);
|
||||
|
||||
final ElementDataEntry entry = getElementDataEntry(key);
|
||||
|
||||
final int flushCounter = entry.fFlushCounter;
|
||||
if (entry.fChildren == null || (update.getOffset() < 0 && !entry.fAllChildrenKnown)) {
|
||||
// We need to retrieve all the children if we don't have any children information.
|
||||
// Or if the client requested all children (offset = -1, length -1) and we have not
|
||||
// retrieved that before.
|
||||
// Need to retrieve all the children if there is no children information yet.
|
||||
// Or if the client requested all children (offset = -1, length -1) and all
|
||||
// the children are not yet known.
|
||||
IChildrenUpdate updateProxy = new VMChildrenUpdate(
|
||||
update, update.getOffset(), update.getLength(),
|
||||
new ViewerDataRequestMonitor<List<Object>>(getExecutor(), update){
|
||||
@Override
|
||||
protected void handleCompleted()
|
||||
{
|
||||
// Workaround for a bug caused by an optimization in the viewer:
|
||||
// The viewer may request more children then there are at a given level.
|
||||
// This causes the update to return with an error.
|
||||
// See https://bugs.eclipse.org/bugs/show_bug.cgi?id=202109
|
||||
// Instead of checking isSuccess(), check getData() != null.
|
||||
if(getData() != null && !isCanceled()) {
|
||||
// Check if the udpate retrieved all children by specifying "offset = -1, length = -1"
|
||||
protected void handleSuccess() {
|
||||
// Check if the update retrieved all children by specifying "offset = -1, length = -1"
|
||||
int updateOffset = update.getOffset();
|
||||
if (updateOffset < 0) {
|
||||
if (updateOffset < 0)
|
||||
{
|
||||
updateOffset = 0;
|
||||
if (entry.fFlushCounter == flushCounter) {
|
||||
entry.fAllChildrenKnown = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Estimate size of children map.
|
||||
Integer childrenCount = entry.fChildrenCount;
|
||||
childrenCount = childrenCount != null ? childrenCount : 0;
|
||||
int capacity = Math.max((childrenCount.intValue() * 4)/3, 32);
|
||||
// Create a new map, but only if it hasn't been created yet by another update.
|
||||
if (entry.fChildren == null) {
|
||||
entry.fChildren = new HashMap<Integer,Object>(capacity);
|
||||
if (DEBUG_CACHE && (DEBUG_PRESENTATION_ID == null || getPresentationContext().getId().equals(DEBUG_PRESENTATION_ID))) {
|
||||
DsfUIPlugin.debug("cacheSavedChildren(node = " + node + ", update = " + update + ", children = {" + updateOffset + "->" + (updateOffset + getData().size()) + "})"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
|
||||
}
|
||||
|
||||
if (flushCounter == entry.fFlushCounter) {
|
||||
entry.ensureChildrenMap();
|
||||
}
|
||||
|
||||
// Set the children to map and update.
|
||||
|
@ -416,19 +499,32 @@ public class AbstractCachingVMProvider extends AbstractVMProvider implements ICa
|
|||
int offset = updateOffset + j;
|
||||
Object child = getData().get(j);
|
||||
if (child != null) {
|
||||
if (flushCounter == entry.fFlushCounter) {
|
||||
entry.fChildren.put(offset, child);
|
||||
}
|
||||
update.setChild(child, offset);
|
||||
}
|
||||
}
|
||||
}
|
||||
update.done();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void handleCancel() {
|
||||
if (DEBUG_CACHE && (DEBUG_PRESENTATION_ID == null || getPresentationContext().getId().equals(DEBUG_PRESENTATION_ID))) {
|
||||
DsfUIPlugin.debug("cacheCanceledChildren(node = " + node + ", update = " + update + ")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
|
||||
}
|
||||
super.handleCancel();
|
||||
}
|
||||
});
|
||||
super.updateNode(node, updateProxy);
|
||||
} else if (update.getOffset() < 0 ) {
|
||||
// The update requested all children. Fill in all children assuming that
|
||||
// the children array is complete.
|
||||
|
||||
if (DEBUG_CACHE && (DEBUG_PRESENTATION_ID == null || getPresentationContext().getId().equals(DEBUG_PRESENTATION_ID))) {
|
||||
DsfUIPlugin.debug("cacheHitChildren(node = " + node + ", update = " + update + ", children = " + entry.fChildren.keySet() + ")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
|
||||
}
|
||||
|
||||
// The following assert should never fail given the first if statement.
|
||||
assert entry.fAllChildrenKnown;
|
||||
|
||||
|
@ -438,13 +534,15 @@ public class AbstractCachingVMProvider extends AbstractVMProvider implements ICa
|
|||
}
|
||||
update.done();
|
||||
} else {
|
||||
// Make the list of missing children. If we've retrieved the
|
||||
// Update for a partial list of children was requested.
|
||||
// Iterate through the known children and make a list of missing
|
||||
// indexes.
|
||||
List<Integer> childrenMissingFromCache = new LinkedList<Integer>();
|
||||
for (int i = update.getOffset(); i < update.getOffset() + update.getLength(); i++) {
|
||||
childrenMissingFromCache.add(i);
|
||||
}
|
||||
|
||||
// Fill in the known children from cache.
|
||||
// Write known children from cache into the update.
|
||||
for(Integer position = update.getOffset(); position < update.getOffset() + update.getLength(); position++) {
|
||||
Object child = entry.fChildren.get(position);
|
||||
if (child != null) {
|
||||
|
@ -453,13 +551,15 @@ public class AbstractCachingVMProvider extends AbstractVMProvider implements ICa
|
|||
}
|
||||
}
|
||||
|
||||
if (DEBUG_CACHE && (DEBUG_PRESENTATION_ID == null || getPresentationContext().getId().equals(DEBUG_PRESENTATION_ID))) {
|
||||
DsfUIPlugin.debug("cachePartialHitChildren(node = " + node + ", update = " + update + ", missing = " + childrenMissingFromCache + ")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
|
||||
}
|
||||
|
||||
if (childrenMissingFromCache.size() > 0) {
|
||||
// perform a partial update; we only have some of the children of the update request
|
||||
|
||||
// Some children were not found in the cache, create separate
|
||||
// proxy updates for the continuous ranges of missing children.
|
||||
List<IChildrenUpdate> partialUpdates = new ArrayList<IChildrenUpdate>(2);
|
||||
|
||||
final CountingRequestMonitor multiRm = new ViewerCountingRequestMonitor(getExecutor(), update);
|
||||
|
||||
while(childrenMissingFromCache.size() > 0)
|
||||
{
|
||||
final int offset = childrenMissingFromCache.get(0);
|
||||
|
@ -475,10 +575,22 @@ public class AbstractCachingVMProvider extends AbstractVMProvider implements ICa
|
|||
update, offset, length,
|
||||
new DataRequestMonitor<List<Object>>(getExecutor(), multiRm) {
|
||||
@Override
|
||||
protected void handleCompleted() {
|
||||
if (getData() != null) {
|
||||
protected void handleSuccess() {
|
||||
// Only save the children to the cahce if the entry wasn't flushed.
|
||||
if (flushCounter == entry.fFlushCounter) {
|
||||
if (DEBUG_CACHE && (DEBUG_PRESENTATION_ID == null || getPresentationContext().getId().equals(DEBUG_PRESENTATION_ID))) {
|
||||
DsfUIPlugin.debug("cachePartialSaveChildren(node = " + node + ", update = " + update + ", saved = {" + offset + "->" + (offset + getData().size()) + "})"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
|
||||
}
|
||||
entry.ensureChildrenMap();
|
||||
}
|
||||
|
||||
for (int i = 0; i < getData().size(); i++) {
|
||||
if (getData().get(i) != null) {
|
||||
update.setChild(getData().get(i), offset + i);
|
||||
if (flushCounter == entry.fFlushCounter) {
|
||||
// Only save the children to the cahce if the entry wasn't flushed.
|
||||
entry.fChildren.put(offset + i, getData().get(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
multiRm.done();
|
||||
|
@ -491,7 +603,7 @@ public class AbstractCachingVMProvider extends AbstractVMProvider implements ICa
|
|||
}
|
||||
multiRm.setDoneCount(partialUpdates.size());
|
||||
} else {
|
||||
// we have all of the children in cache; return from cache
|
||||
// All children were found in cache. Compelte the update.
|
||||
update.done();
|
||||
}
|
||||
}
|
||||
|
@ -506,6 +618,9 @@ public class AbstractCachingVMProvider extends AbstractVMProvider implements ICa
|
|||
* @param archive
|
||||
*/
|
||||
private void flush(FlushMarkerKey flushKey) {
|
||||
if (DEBUG_CACHE && (DEBUG_PRESENTATION_ID == null || getPresentationContext().getId().equals(DEBUG_PRESENTATION_ID))) {
|
||||
DsfUIPlugin.debug("cacheFlushing(" + flushKey + ")"); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
}
|
||||
// For each entry that has the given context as a parent, perform the flush.
|
||||
// Iterate through the cache entries backwards. This means that we will be
|
||||
// iterating in order of most-recently-used to least-recently-used.
|
||||
|
@ -528,6 +643,7 @@ public class AbstractCachingVMProvider extends AbstractVMProvider implements ICa
|
|||
// now.
|
||||
if (entryFlushKey.includes(flushKey)) {
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
else if (entry instanceof ElementDataEntry) {
|
||||
|
@ -561,9 +677,11 @@ public class AbstractCachingVMProvider extends AbstractVMProvider implements ICa
|
|||
entry.remove();
|
||||
}
|
||||
}
|
||||
elementDataEntry.fFlushCounter++;
|
||||
elementDataEntry.fHasChildren = null;
|
||||
elementDataEntry.fChildrenCount = null;
|
||||
elementDataEntry.fChildren = null;
|
||||
elementDataEntry.fAllChildrenKnown = false;
|
||||
elementDataEntry.fDirty = false;
|
||||
} else if ((updateFlags & IVMUpdatePolicy.DIRTY) != 0) {
|
||||
elementDataEntry.fDirty = true;
|
||||
|
@ -754,7 +872,9 @@ public class AbstractCachingVMProvider extends AbstractVMProvider implements ICa
|
|||
entry.fDataOrStatus.put(dmc, getData());
|
||||
rm.setData(getData());
|
||||
} else {
|
||||
if (!isCanceled()) {
|
||||
entry.fDataOrStatus.put(dmc, getStatus());
|
||||
}
|
||||
rm.setStatus(getStatus());
|
||||
}
|
||||
rm.done();
|
||||
|
|
|
@ -136,7 +136,10 @@ public class RequestMonitor {
|
|||
* Sets the status of the result of the request. If status is OK, this
|
||||
* method does not need to be called.
|
||||
*/
|
||||
public synchronized void setStatus(IStatus status) { fStatus = status; }
|
||||
public synchronized void setStatus(IStatus status) {
|
||||
assert isCanceled() || status.getSeverity() != IStatus.CANCEL;
|
||||
fStatus = status;
|
||||
}
|
||||
|
||||
/** Returns the status of the completed method. */
|
||||
public synchronized IStatus getStatus() {
|
||||
|
|
Loading…
Add table
Reference in a new issue