diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/AbstractExpressionLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/AbstractExpressionLayoutNode.java index 723ab82f081..10e75b9a990 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/AbstractExpressionLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/AbstractExpressionLayoutNode.java @@ -281,11 +281,7 @@ public abstract class AbstractExpressionLayoutNode extends Ab } } - if (childRmCount > 0) { - countingRm.setCount(childRmCount); - } else { - countingRm.done(); - } + countingRm.setDoneCount(childRmCount); } diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionManagerLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionManagerLayoutNode.java index 8fb621184bc..ff4d7c6f2f7 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionManagerLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionManagerLayoutNode.java @@ -179,12 +179,8 @@ public class ExpressionManagerLayoutNode extends AbstractVMLayoutNode } } - // If no expressions were parsed, we're finished. - if (expressionRmCount > 0) { - multiRm.setCount(expressionRmCount); - } else { - multiRm.done(); - } + // Set the count to the counting RM. + multiRm.setDoneCount(expressionRmCount); } public void update(ILabelUpdate[] updates) { @@ -323,11 +319,7 @@ public class ExpressionManagerLayoutNode extends AbstractVMLayoutNode buildDeltaForExpressionCallCount++; } - if (buildDeltaForExpressionCallCount != 0) { - multiRm.setCount(buildDeltaForExpressionCallCount); - } else { - requestMonitor.done(); - } + multiRm.setDoneCount(buildDeltaForExpressionCallCount); } diff --git a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/CountingRequestMonitor.java b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/CountingRequestMonitor.java index 6b1bb09585b..0fabdafb7da 100644 --- a/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/CountingRequestMonitor.java +++ b/plugins/org.eclipse.dd.dsf/src/org/eclipse/dd/dsf/concurrent/CountingRequestMonitor.java @@ -18,46 +18,74 @@ import org.eclipse.dd.dsf.DsfPlugin; /** * Utility class to collect multiple request monitor results of commands * that are initiated simultaneously. The usage is as follows: - *
- *     final MultiRequestMonitor multiRequestMon = new MultiRequestMonitor(fExecutor, null) { 
+ * 
+ *     final CountingRequestMonitor countingRm = new CountingRequestMonitor(fExecutor, null) { 
  *         public void handleCompleted() {
  *             System.out.println("All complete, errors=" + !getStatus().isOK());
  *         }
  *     };
  *     
- *     for (int i = 0; i < 10; i++) {
- *         service.call(i, multiRequestMon.addRequestMonitor(
- *             new RequestMonitor(fExecutor, null) {
- *                 public void handleCompleted() {
- *                     System.out.println(Integer.toString(i) + " complete");
- *                     multiRequestMon.requestMonitorDone(this);
- *                }
- *             }));
+ *     int count = 0;
+ *     for (int i : elements) {
+ *         service.call(i, countingRm);
+ *         count++;
  *     }
- * 
+ * + * countingRm.setDoneCount(count); + *
*/ public class CountingRequestMonitor extends RequestMonitor { + /** + * Counter tracking the remaining number of times that the done() method + * needs to be called before this request monitor is actually done. + */ private int fDoneCounter; + + /** + * Flag indicating whether the initial count has been set on this monitor. + */ + private boolean fInitialCountSet = false; public CountingRequestMonitor(Executor executor, RequestMonitor parentRequestMonitor) { super(executor, parentRequestMonitor); setStatus(new MultiStatus(DsfPlugin.PLUGIN_ID, 0, "Collective status for set of sub-operations.", null)); //$NON-NLS-1$ } - public void setCount(int count) { - fDoneCounter = count; + /** + * Sets the number of times that this request monitor needs to be called + * before this monitor is truly considered done. This method must be called + * exactly once in the life cycle of each counting request monitor. + * @param count Number of times that done() has to be called to mark the request + * monitor as complete. If count is '0', then the counting request monitor is + * marked as done immediately. + */ + public synchronized void setDoneCount(int count) { + assert !fInitialCountSet; + fInitialCountSet = true; + fDoneCounter += count; + if (fDoneCounter <= 0) { + assert fDoneCounter == 0; // Mismatch in the count. + super.done(); + } } + /** + * Called to indicate that one of the calls using this monitor is finished. + * Only when done is called the number of times corresponding to the + * count, the request monitor will be considered complete. This method can be + * called before {@link #setDoneCount(int)}. + */ @Override public synchronized void done() { fDoneCounter--; - if (fDoneCounter <= 0) { + if (fInitialCountSet && fDoneCounter <= 0) { + assert fDoneCounter == 0; // Mismatch in the count. super.done(); } } @Override public String toString() { - return "Multi-RequestMonitor: " + getStatus().toString(); //$NON-NLS-1$ + return "CountingRequestMonitor: " + getStatus().toString(); //$NON-NLS-1$ } }