diff options
author | Pawel Piech | 2012-03-29 04:49:34 +0000 |
---|---|---|
committer | Pawel Piech | 2012-03-29 04:50:59 +0000 |
commit | 839411a4f1e70c4876fe56c2481c4f5cecb50f86 (patch) | |
tree | 82c41006e7f97bd6b1c1b548de4b8c0de1d1bdbf | |
parent | 79038a3960ccc865356a29e06c097ebfaf4c446f (diff) | |
download | eclipse.platform.debug-839411a4f1e70c4876fe56c2481c4f5cecb50f86.tar.gz eclipse.platform.debug-839411a4f1e70c4876fe56c2481c4f5cecb50f86.tar.xz eclipse.platform.debug-839411a4f1e70c4876fe56c2481c4f5cecb50f86.zip |
Bug 373790 - Debug view stays busy after Resume
4 files changed, 88 insertions, 10 deletions
diff --git a/org.eclipse.debug.tests/src/org/eclipe/debug/tests/viewer/model/ITestModelUpdatesListenerConstants.java b/org.eclipse.debug.tests/src/org/eclipe/debug/tests/viewer/model/ITestModelUpdatesListenerConstants.java index 4437d40e1..9fadb0cdb 100644 --- a/org.eclipse.debug.tests/src/org/eclipe/debug/tests/viewer/model/ITestModelUpdatesListenerConstants.java +++ b/org.eclipse.debug.tests/src/org/eclipe/debug/tests/viewer/model/ITestModelUpdatesListenerConstants.java @@ -17,17 +17,18 @@ package org.eclipe.debug.tests.viewer.model; */ public interface ITestModelUpdatesListenerConstants { - public static final int LABEL_SEQUENCE_COMPLETE = 0X00000001; - public static final int CONTENT_SEQUENCE_COMPLETE = 0X00000002; - public static final int CONTENT_SEQUENCE_STARTED = 0X00020000; + public static final int LABEL_SEQUENCE_COMPLETE = 0X00000001; + public static final int CONTENT_SEQUENCE_COMPLETE = 0X00000002; + public static final int CONTENT_SEQUENCE_STARTED = 0X00020000; public static final int LABEL_UPDATES = 0X00000004; - public static final int LABEL_SEQUENCE_STARTED = 0X00040000; + public static final int LABEL_SEQUENCE_STARTED = 0X00040000; public static final int HAS_CHILDREN_UPDATES = 0X00000008; public static final int HAS_CHILDREN_UPDATES_STARTED = 0X00080000; public static final int CHILD_COUNT_UPDATES = 0X00000010; public static final int CHILD_COUNT_UPDATES_STARTED = 0X00100000; public static final int CHILDREN_UPDATES = 0X00000020; public static final int CHILDREN_UPDATES_STARTED = 0X00200000; + public static final int CHILDREN_UPDATES_RUNNING = 0X00400000; public static final int MODEL_CHANGED_COMPLETE = 0X00000040; public static final int MODEL_PROXIES_INSTALLED = 0X00000080; public static final int STATE_SAVE_COMPLETE = 0X00000100; diff --git a/org.eclipse.debug.tests/src/org/eclipe/debug/tests/viewer/model/TestModelUpdatesListener.java b/org.eclipse.debug.tests/src/org/eclipe/debug/tests/viewer/model/TestModelUpdatesListener.java index 8b540b121..ff39eba06 100644 --- a/org.eclipse.debug.tests/src/org/eclipe/debug/tests/viewer/model/TestModelUpdatesListener.java +++ b/org.eclipse.debug.tests/src/org/eclipe/debug/tests/viewer/model/TestModelUpdatesListener.java @@ -484,8 +484,12 @@ public class TestModelUpdatesListener if (!fChildCountUpdatesScheduled.isEmpty()) return false; } if ( (flags & CHILDREN_UPDATES_STARTED) != 0) { + // Some children updates have already been started or completed. if (fChildrenUpdatesRunning.isEmpty() && fChildrenUpdatesCompleted.isEmpty()) return false; } + if ( (flags & CHILDREN_UPDATES_RUNNING) != 0) { + if (!isFinishedChildrenRunning()) return false; + } if ( (flags & CHILDREN_UPDATES) != 0) { if (!fChildrenUpdatesScheduled.isEmpty()) return false; } @@ -522,10 +526,41 @@ public class TestModelUpdatesListener return false; } } - return true; } + + /** + * Returns true if all children updates that were scheduled are either currently + * running or have already completed. + * + * @see CHILDREN_UPDATES_RUNNING + * @return + */ + private boolean isFinishedChildrenRunning() { + // All children updates that have been scheduled are either running or completed. + int scheduledCount = 0; + for (Iterator itr = fChildrenUpdatesScheduled.values().iterator(); itr.hasNext();) { + scheduledCount += ((Set)itr.next()).size(); + } + + int runningCount = 0; + for (Iterator itr = fChildrenUpdatesRunning.iterator(); itr.hasNext();) { + IChildrenUpdate update = ((IChildrenUpdate)itr.next()); + Set set = (Set)fChildrenUpdatesScheduled.get( update.getElementPath() ); + for (int i = update.getOffset(); set != null && i < update.getOffset() + update.getLength(); i++) { + if (set.contains(new Integer(i))) runningCount++; + } + } + for (Iterator itr = fChildrenUpdatesCompleted.iterator(); itr.hasNext();) { + IChildrenUpdate update = ((IChildrenUpdate)itr.next()); + Set set = (Set)fChildrenUpdatesScheduled.get( update.getElementPath() ); + for (int i = update.getOffset(); set != null && i < update.getOffset() + update.getLength(); i++) { + if (set.contains(new Integer(i))) runningCount++; + } + } + return scheduledCount == runningCount; + } public void updateStarted(IViewerUpdate update) { synchronized (this) { diff --git a/org.eclipse.debug.tests/src/org/eclipe/debug/tests/viewer/model/UpdateTests.java b/org.eclipse.debug.tests/src/org/eclipe/debug/tests/viewer/model/UpdateTests.java index 7e465bdd0..4c365bca9 100644 --- a/org.eclipse.debug.tests/src/org/eclipe/debug/tests/viewer/model/UpdateTests.java +++ b/org.eclipse.debug.tests/src/org/eclipe/debug/tests/viewer/model/UpdateTests.java @@ -353,7 +353,7 @@ abstract public class UpdateTests extends TestCase implements ITestModelUpdatesL model.postDelta(new ModelDelta(rootElement, IModelDelta.CONTENT)); // Wait for the delta to be processed. - while (!fListener.isFinished(MODEL_CHANGED_COMPLETE | CHILD_COUNT_UPDATES)) if (!fDisplay.readAndDispatch ()) Thread.sleep(0); + while (!fListener.isFinished(MODEL_CHANGED_COMPLETE | CHILD_COUNT_UPDATES | CHILDREN_UPDATES_STARTED)) if (!fDisplay.readAndDispatch ()) Thread.sleep(0); // Update the model removeElement(model, 0, true); @@ -361,7 +361,6 @@ abstract public class UpdateTests extends TestCase implements ITestModelUpdatesL } } - /** * This test forces the viewer to cancel updates then process them at once. * <p> @@ -527,6 +526,44 @@ abstract public class UpdateTests extends TestCase implements ITestModelUpdatesL while (!fListener.isFinished(ALL_UPDATES_COMPLETE)) if (!fDisplay.readAndDispatch ()) Thread.sleep(0); } + /** + * This test removes an element while there are updates running on its + * sub-tree. With a precise timing this operation caused Bug 373790. + * <p> + * See Bug 373790 - Debug view stays busy after Resume + * </p> + * @see org.eclipse.debug.internal.ui.viewers.model.ModelContentProvider#rescheduleUpdates + */ + public void testCancelUpdates5() throws InterruptedException { + TestModel model = TestModel.simpleMultiLevel(); + fViewer.setAutoExpandLevel(-1); + + // Create the listener + fListener.reset(TreePath.EMPTY, model.getRootElement(), -1, false, false); + + // Set the input into the view and update the view. + fViewer.setInput(model.getRootElement()); + while (!fListener.isFinished()) if (!fDisplay.readAndDispatch ()) Thread.sleep(0); + model.validateData(fViewer, TreePath.EMPTY); + + // Refresh the viewer so that updates are generated. + fListener.reset(); + TreePath path = model.findElement("2"); + fListener.addUpdates(path, model.getElement(path), 1, CHILD_COUNT_UPDATES); + fListener.addChildreUpdate(path, 0); + model.postDelta(new ModelDelta(model.getRootElement(), IModelDelta.CONTENT)); + + // Wait for the delta to be processed and child updates for "2" to get started. + while (!fListener.isFinished(MODEL_CHANGED_COMPLETE | CHILD_COUNT_UPDATES | CHILDREN_UPDATES_RUNNING)) if (!fDisplay.readAndDispatch ()) Thread.sleep(0); + + // Remove element "2" + removeElement(model, 1, true); + + // Wait for all updates to finish. + while (!fListener.isFinished(ALL_UPDATES_COMPLETE)) if (!fDisplay.readAndDispatch ()) Thread.sleep(0); + } + + private void completeQueuedUpdatesOfType(TestModel model, Class updateClass) { List updatesToComplete = new LinkedList(); diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/TreeModelContentProvider.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/TreeModelContentProvider.java index 08b73d12f..386fe8c38 100644 --- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/TreeModelContentProvider.java +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/TreeModelContentProvider.java @@ -639,13 +639,13 @@ public class TreeModelContentProvider implements ITreeModelContentProvider, ICon // fRequestsInProgress map. This way updateStarted() will not send a // redundant "UPDATE SEQUENCE STARTED" notification. trigger(update.getSchedulingPath()); - if (requests != null && requests.isEmpty()) { - fRequestsInProgress.remove(update.getSchedulingPath()); - } } else { // Update may be removed from in progress list if it was canceled by schedule(). Assert.isTrue( update.isCanceled() ); } + if (requests != null && requests.isEmpty()) { + fRequestsInProgress.remove(update.getSchedulingPath()); + } } if (fRequestsInProgress.isEmpty() && fWaitingRequests.isEmpty()) { if (DebugUIPlugin.DEBUG_UPDATE_SEQUENCE && DebugUIPlugin.DEBUG_TEST_PRESENTATION_ID(getPresentationContext())) { @@ -755,6 +755,8 @@ public class TreeModelContentProvider implements ITreeModelContentProvider, ICon * @param update the update the schedule */ private void schedule(final ViewerUpdateMonitor update) { + Assert.isTrue(getViewer().getDisplay().getThread() == Thread.currentThread()); + TreePath schedulingPath = update.getSchedulingPath(); List requests = (List) fWaitingRequests.get(schedulingPath); if (requests == null) { @@ -780,6 +782,7 @@ public class TreeModelContentProvider implements ITreeModelContentProvider, ICon if (inProgressList == null || inProgressList.isEmpty()) { getViewer().getDisplay().asyncExec(new Runnable() { public void run() { + if (isDisposed()) return; trigger(update.getSchedulingPath()); } }); @@ -858,6 +861,8 @@ public class TreeModelContentProvider implements ITreeModelContentProvider, ICon * be <code>null</code> to start the shortest path request. */ private void trigger(TreePath schedulingPath) { + Assert.isTrue(getViewer().getDisplay().getThread() == Thread.currentThread()); + if (fWaitingRequests.isEmpty()) { return; } |