diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/DefaultVMContentProviderStrategy.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/DefaultVMContentProviderStrategy.java index 6009f7b16c9..fe27ec0e719 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/DefaultVMContentProviderStrategy.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/DefaultVMContentProviderStrategy.java @@ -319,7 +319,12 @@ public class DefaultVMContentProviderStrategy implements IElementContentProvider elementsMultiRequestMon.add(new DataRequestMonitor>(getVMProvider().getExecutor(), null) { @Override protected void handleCompleted() { - if (getStatus().isOK()) { + // 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 caues the update to return with an error. + // See https://bugs.eclipse.org/bugs/show_bug.cgi?id=202109 + // Instead of checking getStatus().isOK(), check getData() != null. + if (getData() != null) { for (int i = 0; i < elementsLength; i++) { update.setChild(getData().get(i), elementsStartIdx + nodeStartIdx + i); } diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMViewerUpdate.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMViewerUpdate.java index d3b383bfd3a..03d907edec6 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMViewerUpdate.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMViewerUpdate.java @@ -173,7 +173,12 @@ public class VMViewerUpdate implements IViewerUpdate { fRequestMonitor.setStatus(new Status( IStatus.CANCEL, DsfUIPlugin.PLUGIN_ID," Update was cancelled") ); //$NON-NLS-1$ } fRequestMonitor.done(); - } catch (RejectedExecutionException e) { // Ignore + } catch (RejectedExecutionException e) { + // If the request monitor cannot be invoked still, try to complete the update to avoid + // leaving the viewer in an inconsistent state. + if (fClientUpdate != null) { + fClientUpdate.done(); + } } } diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/AbstractCachingVMProvider.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/AbstractCachingVMProvider.java index 3851620e4db..fa14d97b2a1 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/AbstractCachingVMProvider.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/AbstractCachingVMProvider.java @@ -356,6 +356,11 @@ public class AbstractCachingVMProvider extends AbstractVMProvider implements ICa @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 caues the update to return with an error. + // See https://bugs.eclipse.org/bugs/show_bug.cgi?id=202109 + // Instead of checking getStatus().isOK(), check getData() != null. if(getData() != null) { // Check if the udpate retrieved all children by specifying "offset = -1, length = -1" int updateOffset = update.getOffset(); @@ -404,7 +409,16 @@ public class AbstractCachingVMProvider extends AbstractVMProvider implements ICa for (int i = update.getOffset(); i < update.getOffset() + update.getLength(); i++) { childrenMissingFromCache.add(i); } - childrenMissingFromCache.removeAll(entry.fChildren.keySet()); + + // Fill in the known children from cache. + for(int position = update.getOffset(); position < update.getOffset() + update.getLength(); position++) { + Object child = entry.fChildren.get(position); + if (child != null) { + update.setChild(entry.fChildren.get(position), position); + } else { + childrenMissingFromCache.remove(position); + } + } if (childrenMissingFromCache.size() > 0) { // perform a partial update; we only have some of the children of the update request @@ -445,9 +459,6 @@ public class AbstractCachingVMProvider extends AbstractVMProvider implements ICa multiRm.setDoneCount(partialUpdates.size()); } else { // we have all of the children in cache; return from cache - for(int position = update.getOffset(); position < update.getOffset() + update.getLength(); position++) { - update.setChild(entry.fChildren.get(position), position); - } update.done(); } }