Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Xenos2016-08-31 00:37:08 +0000
committerStefan Xenos2016-08-31 00:37:08 +0000
commitb3bdb7f21fd25f056de062d902fec8e286a4572f (patch)
tree3cb428ef5cfb88db6711f8d0bd55ec91e51ad829
parent04d0bef8bc6079faf513c7e893ec321dc4e9b3d9 (diff)
downloadrt.equinox.bundles-b3bdb7f21fd25f056de062d902fec8e286a4572f.tar.gz
rt.equinox.bundles-b3bdb7f21fd25f056de062d902fec8e286a4572f.tar.xz
rt.equinox.bundles-b3bdb7f21fd25f056de062d902fec8e286a4572f.zip
Bug 500483 - Offer a cancellation-checking variant of Submonitor#worked
Change-Id: I0a2d3bceaaf5b80eaeb55699209f89bdb6dfb6b3 Signed-off-by: Stefan Xenos <sxenos@gmail.com>
-rw-r--r--bundles/org.eclipse.equinox.common/META-INF/MANIFEST.MF2
-rw-r--r--bundles/org.eclipse.equinox.common/pom.xml2
-rw-r--r--bundles/org.eclipse.equinox.common/src/org/eclipse/core/runtime/SubMonitor.java91
3 files changed, 81 insertions, 14 deletions
diff --git a/bundles/org.eclipse.equinox.common/META-INF/MANIFEST.MF b/bundles/org.eclipse.equinox.common/META-INF/MANIFEST.MF
index bba5bec7a..af3acd295 100644
--- a/bundles/org.eclipse.equinox.common/META-INF/MANIFEST.MF
+++ b/bundles/org.eclipse.equinox.common/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: %pluginName
Bundle-SymbolicName: org.eclipse.equinox.common; singleton:=true
-Bundle-Version: 3.8.100.qualifier
+Bundle-Version: 3.9.0.qualifier
Bundle-Localization: plugin
Export-Package: org.eclipse.core.internal.boot;x-friends:="org.eclipse.core.resources,org.eclipse.core.runtime.compatibility,org.eclipse.pde.build",
org.eclipse.core.internal.runtime;common=split;mandatory:=common;
diff --git a/bundles/org.eclipse.equinox.common/pom.xml b/bundles/org.eclipse.equinox.common/pom.xml
index bc207207d..0ad1c078c 100644
--- a/bundles/org.eclipse.equinox.common/pom.xml
+++ b/bundles/org.eclipse.equinox.common/pom.xml
@@ -19,6 +19,6 @@
</parent>
<groupId>org.eclipse.equinox</groupId>
<artifactId>org.eclipse.equinox.common</artifactId>
- <version>3.8.100-SNAPSHOT</version>
+ <version>3.9.0-SNAPSHOT</version>
<packaging>eclipse-plugin</packaging>
</project>
diff --git a/bundles/org.eclipse.equinox.common/src/org/eclipse/core/runtime/SubMonitor.java b/bundles/org.eclipse.equinox.common/src/org/eclipse/core/runtime/SubMonitor.java
index 9ec1f7705..14e278a8a 100644
--- a/bundles/org.eclipse.equinox.common/src/org/eclipse/core/runtime/SubMonitor.java
+++ b/bundles/org.eclipse.equinox.common/src/org/eclipse/core/runtime/SubMonitor.java
@@ -69,7 +69,7 @@ import org.eclipse.core.internal.runtime.TracingOptions;
* doSomeWork(progress.split(30));
*
* // Advance the monitor by another 30%
- * progress.worked(30);
+ * progress.step(30);
*
* // Use the remaining 40% of the progress to do some more work
* doSomeWork(progress.split(40));
@@ -110,7 +110,7 @@ import org.eclipse.core.internal.runtime.TracingOptions;
* } else {
* // Bad: Causes the progress monitor to appear to start at 50%, wasting half of the
* // space in the monitor.
- * progress.worked(50);
+ * progress.step(50);
* }
* </pre>
*
@@ -171,14 +171,41 @@ import org.eclipse.core.internal.runtime.TracingOptions;
public final class SubMonitor implements IProgressMonitorWithBlocking {
/**
- * Number of trivial operations (operations which do not report any progress) which can be
+ * Number of trivial split operations (operations which do not report any progress) which can be
* performed before the monitor performs a cancellation check. This ensures that cancellation
* checks do not create a performance problem in tight loops that create a lot of SubMonitors,
* while still ensuring that cancellation is checked occasionally in such loops. This only
* affects operations which are too small to report any progress. Operations which are large
* enough to consume at least one tick will always be checked for cancellation.
*/
- private static final int TRIVIAL_OPERATIONS_BEFORE_CANCELLATION_CHECK = 10;
+ private static final int TRIVIAL_SPLITS_BEFORE_CANCELLATION_CHECK = 10;
+
+ /**
+ * Number of trivial tick operations (operations which do not report any progress) which can be
+ * performed before the monitor performs a cancellation check. This ensures that cancellation
+ * checks do not create a performance problem in tight loops that report a lot of work
+ * while still ensuring that cancellation is checked occasionally in such loops. This only
+ * affects operations which are too small to report any progress. Operations which are large
+ * enough to consume at least one tick will always be checked for cancellation.
+ */
+ private static final int TRIVIAL_TICKS_BEFORE_CANCELLATION_CHECK = 10;
+
+ /**
+ * The limit for {@link RootInfo#cancellationCheckCounter} before performing a cancellation check.
+ */
+ private static final int TRIVIAL_OPERATION_COUNT_LIMIT = TRIVIAL_SPLITS_BEFORE_CANCELLATION_CHECK * TRIVIAL_TICKS_BEFORE_CANCELLATION_CHECK;
+
+ /**
+ * Amount to increment {@link RootInfo#cancellationCheckCounter} when performing
+ * a trivial {@link #split(int)} operation.
+ */
+ private static final int TRIVIAL_SPLIT_DELTA = TRIVIAL_OPERATION_COUNT_LIMIT / TRIVIAL_SPLITS_BEFORE_CANCELLATION_CHECK;
+
+ /**
+ * Amount to increment {@link RootInfo#cancellationCheckCounter} when performing
+ * a trivial {@link #step(int)} operation.
+ */
+ private static final int TRIVIAL_TICK_DELTA = TRIVIAL_OPERATION_COUNT_LIMIT / TRIVIAL_TICKS_BEFORE_CANCELLATION_CHECK;;
/**
* Minimum number of ticks to allocate when calling beginTask on an unknown IProgressMonitor.
@@ -266,6 +293,15 @@ public final class SubMonitor implements IProgressMonitorWithBlocking {
throw new OperationCanceledException();
}
}
+
+ public void reportTrivialOperation(int cancellationDelta) {
+ cancellationCheckCounter += cancellationDelta;
+ // This is a trivial operation. Only perform a cancellation check after the counter expires.
+ if (cancellationCheckCounter >= TRIVIAL_OPERATION_COUNT_LIMIT) {
+ cancellationCheckCounter = 0;
+ checkForCancellation();
+ }
+ }
}
/**
@@ -685,7 +721,7 @@ public final class SubMonitor implements IProgressMonitorWithBlocking {
*
* ////////////////////////////////////////////////////////////////////////////
* // Example 2: Demonstrates the function of active children. Creating children
- * // is sufficient to smoothly report progress, even if worked(...) and done()
+ * // is sufficient to smoothly report progress, even if step(...) and done()
* // are never called.
* void myMethod(IProgressMonitor parent) {
* SubMonitor progress = SubMonitor.convert(parent, 100);
@@ -789,7 +825,7 @@ public final class SubMonitor implements IProgressMonitorWithBlocking {
*
* ////////////////////////////////////////////////////////////////////////////
* // Example 2: Demonstrates the function of active children. Creating children
- * // is sufficient to smoothly report progress, even if worked(...) and done()
+ * // is sufficient to smoothly report progress, even if step(...) and done()
* // are never called.
* void myMethod(IProgressMonitor parent) {
* SubMonitor progress = SubMonitor.convert(parent, 100);
@@ -860,7 +896,7 @@ public final class SubMonitor implements IProgressMonitorWithBlocking {
*
* ////////////////////////////////////////////////////////////////////////////
* // Example 2: Demonstrates the function of active children. Creating children
- * // is sufficient to smoothly report progress, even if worked(...) and done()
+ * // is sufficient to smoothly report progress, even if step(...) and done()
* // are never called.
* void myMethod(IProgressMonitor parent) {
* SubMonitor progress = SubMonitor.convert(parent, 100);
@@ -917,16 +953,47 @@ public final class SubMonitor implements IProgressMonitorWithBlocking {
root.checkForCancellation();
}
} else {
- // This is a trivial operation. Only perform a cancellation check after the counter expires.
- if (++root.cancellationCheckCounter >= TRIVIAL_OPERATIONS_BEFORE_CANCELLATION_CHECK) {
- root.cancellationCheckCounter = 0;
- root.checkForCancellation();
- }
+ root.reportTrivialOperation(TRIVIAL_SPLIT_DELTA);
}
}
return result;
}
+ /**
+ * Notifies that a given number of work units of the main task
+ * has been completed. Note that this amount represents an
+ * installment, as opposed to a cumulative amount of work done
+ * to date.
+ * <p>
+ * This method is much like {@link #worked}, but will additionally check for cancellation and
+ * will throw an {@link OperationCanceledException} if the monitor has been cancelled. Not
+ * every call to this method will trigger a cancellation check. The checks will be performed
+ * as often as possible without degrading the performance of the caller.
+ *
+ * @param work a non-negative number of work units just completed
+ * @throws OperationCanceledException if the monitor has been cancelled
+ * @since 3.9
+ */
+ public void step(int work) throws OperationCanceledException {
+ if (TracingOptions.debugProgressMonitors) {
+ if (work == 0) {
+ logProblem("Attempted to report 0 ticks of work"); //$NON-NLS-1$
+ } else if (work < 0) {
+ logProblem("Attempted to report negative ticks of work"); //$NON-NLS-1$
+ }
+ }
+
+ cleanupActiveChild();
+
+ int delta = consume(Math.max(work, 0));
+ if (delta != 0) {
+ root.checkForCancellation();
+ root.worked(delta);
+ } else {
+ root.reportTrivialOperation(TRIVIAL_TICK_DELTA);
+ }
+ }
+
private void cleanupActiveChild() {
if (lastSubMonitor == null)
return;

Back to the top