Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/concurrent/Sequence.java37
-rw-r--r--dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/concurrent/DsfSequenceTests.java90
2 files changed, 103 insertions, 24 deletions
diff --git a/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/concurrent/Sequence.java b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/concurrent/Sequence.java
index da0f4f1913..79c868780a 100644
--- a/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/concurrent/Sequence.java
+++ b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/concurrent/Sequence.java
@@ -421,10 +421,19 @@ abstract public class Sequence extends DsfRunnable implements Future<Object> {
@Override
protected void handleErrorOrWarning() {
- abortExecution(getStatus());
+ abortExecution(getStatus(), true);
};
@Override
+ protected void handleRejectedExecutionException() {
+ abortExecution(
+ new Status(IStatus.ERROR, DsfPlugin.PLUGIN_ID, 0,
+ "Executor shut down while executing Sequence " + this + ", step #" + fCurrentStepIdx, //$NON-NLS-1$ //$NON-NLS-2$
+ null),
+ false);
+ }
+
+ @Override
public String toString() {
return "Sequence \"" + fTaskName + "\", result for executing step #" + fStepIdx + " = " + getStatus(); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
}
@@ -450,10 +459,11 @@ abstract public class Sequence extends DsfRunnable implements Future<Object> {
* when the execute submits other runnables, and the other runnables
* encounter the exception.
*/
- abortExecution(new Status(
- IStatus.ERROR, DsfPlugin.PLUGIN_ID, 0,
- "Unhandled exception when executing Sequence " + this + ", step #" + fCurrentStepIdx, //$NON-NLS-1$ //$NON-NLS-2$
- t));
+ abortExecution(
+ new Status(IStatus.ERROR, DsfPlugin.PLUGIN_ID, 0,
+ "Unhandled exception when executing Sequence " + this + ", step #" + fCurrentStepIdx, //$NON-NLS-1$ //$NON-NLS-2$
+ t),
+ true);
/*
* Since we caught the exception, it will not be logged by
@@ -548,8 +558,13 @@ abstract public class Sequence extends DsfRunnable implements Future<Object> {
/**
* Tells the sequence that its execution is to be aborted and it
* should start rolling back the sequence as if it was cancelled by user.
+ *
+ * @param status Status to use for reporting the error.
+ * @param rollBack Whether to start rolling back the sequence after abort.
+ * If this parameter is <code>false</code> then the sequence will also
+ * finish.
*/
- private void abortExecution(final IStatus error) {
+ private void abortExecution(final IStatus error, boolean rollBack) {
if (fRollbackTaskName != null) {
fProgressMonitor.subTask(fRollbackTaskName);
}
@@ -558,9 +573,13 @@ abstract public class Sequence extends DsfRunnable implements Future<Object> {
fRequestMonitor.setStatus(error);
}
fSync.doAbort(new CoreException(error));
-
- // Roll back starting with previous step, since current step failed.
- rollBackStep(fCurrentStepIdx - 1);
+
+ if (rollBack) {
+ // Roll back starting with previous step, since current step failed.
+ rollBackStep(fCurrentStepIdx - 1);
+ } else {
+ finish();
+ }
}
/**
diff --git a/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/concurrent/DsfSequenceTests.java b/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/concurrent/DsfSequenceTests.java
index e9019429db..4e1c0b2f53 100644
--- a/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/concurrent/DsfSequenceTests.java
+++ b/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/concurrent/DsfSequenceTests.java
@@ -43,9 +43,13 @@ public class DsfSequenceTests {
@After
public void shutdownExecutor() throws ExecutionException, InterruptedException {
- fExecutor.submit(new DsfRunnable() { public void run() {
- fExecutor.shutdown();
- }}).get();
+ if (!fExecutor.isShutdown()) {
+ // Some tests shut down the executor deliberatly)
+
+ fExecutor.submit(new DsfRunnable() { public void run() {
+ fExecutor.shutdown();
+ }}).get();
+ }
if (fExecutor.exceptionsCaught()) {
Throwable[] exceptions = fExecutor.getExceptions();
throw new ExecutionException(exceptions[0]);
@@ -81,8 +85,8 @@ public class DsfSequenceTests {
Sequence sequence = new Sequence(fExecutor) {
@Override public Step[] getSteps() { return steps; }
};
- Assert.assertTrue(!sequence.isDone());
- Assert.assertTrue(!sequence.isCancelled());
+ Assert.assertFalse(sequence.isDone());
+ Assert.assertFalse(sequence.isCancelled());
fExecutor.execute(sequence);
sequence.get();
@@ -92,7 +96,7 @@ public class DsfSequenceTests {
// Check post conditions
Assert.assertTrue(sequence.isDone());
- Assert.assertTrue(!sequence.isCancelled());
+ Assert.assertFalse(sequence.isCancelled());
}
@@ -129,8 +133,8 @@ public class DsfSequenceTests {
SimpleReflectionSequence sequence = new SimpleReflectionSequence();
//Sequence sequence = new SimpleReflectionSequence();
- Assert.assertTrue(!sequence.isDone());
- Assert.assertTrue(!sequence.isCancelled());
+ Assert.assertFalse(sequence.isDone());
+ Assert.assertFalse(sequence.isCancelled());
fExecutor.execute(sequence);
sequence.get();
@@ -140,7 +144,7 @@ public class DsfSequenceTests {
// Check post conditions
Assert.assertTrue(sequence.isDone());
- Assert.assertTrue(!sequence.isCancelled());
+ Assert.assertFalse(sequence.isCancelled());
}
@@ -183,7 +187,7 @@ public class DsfSequenceTests {
};
fExecutor.execute(sequence);
- // Block and wait for sequence to bomplete.
+ // Block and wait for sequence to complete.
try {
sequence.get();
} finally {
@@ -194,7 +198,63 @@ public class DsfSequenceTests {
// Check state from Future interface
Assert.assertTrue(sequence.isDone());
- Assert.assertTrue(!sequence.isCancelled());
+ Assert.assertFalse(sequence.isCancelled());
+ }
+ Assert.assertTrue("Exception should have been thrown", false); //$NON-NLS-1$
+ }
+
+ @Test (expected = ExecutionException.class)
+ public void rejectedTest() throws InterruptedException, ExecutionException {
+ // Create a counter for tracking number of steps performed and steps
+ // rolled back.
+ class IntegerHolder { int fInteger; }
+ final IntegerHolder stepCounter = new IntegerHolder();
+ final IntegerHolder rollBackCounter = new IntegerHolder();
+
+ // Create the steps of the sequence
+ final Sequence.Step[] steps = new Sequence.Step[] {
+ new Sequence.Step() {
+ @Override public void execute(RequestMonitor requestMonitor) {
+ stepCounter.fInteger++;
+ requestMonitor.done();
+ }
+ @Override public void rollBack(RequestMonitor requestMonitor) {
+ rollBackCounter.fInteger++;
+ requestMonitor.done();
+ }
+ },
+ new Sequence.Step() {
+ @Override public void execute(RequestMonitor requestMonitor) {
+ stepCounter.fInteger++;
+ // Shutdown exectutor to force a RejectedExecutionException
+ fExecutor.shutdown();
+ requestMonitor.done();
+ }
+ @Override public void rollBack(RequestMonitor requestMonitor) {
+ rollBackCounter.fInteger++;
+ requestMonitor.done();
+ }
+ }
+ };
+
+ // Create and start.
+ Sequence sequence = new Sequence(fExecutor) {
+ @Override public Step[] getSteps() { return steps; }
+ };
+ fExecutor.execute(sequence);
+
+ // Block and wait for sequence to complete.
+ try {
+ sequence.get();
+ } finally {
+ // Both steps should be performed
+ Assert.assertTrue(stepCounter.fInteger == 2);
+ // No steps should be rolled back.
+ Assert.assertTrue(rollBackCounter.fInteger == 0);
+
+ // Check state from Future interface
+ Assert.assertTrue(sequence.isDone());
+ Assert.assertFalse(sequence.isCancelled());
}
Assert.assertTrue("Exception should have been thrown", false); //$NON-NLS-1$
}
@@ -257,7 +317,7 @@ public class DsfSequenceTests {
// Check state from Future interface
Assert.assertTrue(sequence.isDone());
- Assert.assertTrue(!sequence.isCancelled());
+ Assert.assertFalse(sequence.isCancelled());
}
Assert.assertTrue("Exception should have been thrown", false); //$NON-NLS-1$
}
@@ -320,7 +380,7 @@ public class DsfSequenceTests {
// Check state from Future interface
Assert.assertTrue(sequence.isDone());
- Assert.assertTrue(!sequence.isCancelled());
+ Assert.assertFalse(sequence.isCancelled());
}
Assert.assertTrue("Exception should have been thrown", false); //$NON-NLS-1$
}
@@ -352,7 +412,7 @@ public class DsfSequenceTests {
} finally {
// Check state from Future interface
Assert.assertTrue(sequence.isDone());
- Assert.assertTrue(!sequence.isCancelled());
+ Assert.assertFalse(sequence.isCancelled());
}
Assert.assertTrue("Exception should have been thrown", false); //$NON-NLS-1$
}
@@ -375,7 +435,7 @@ public class DsfSequenceTests {
// Cancel before invoking the sequence.
sequence.cancel(false);
- Assert.assertTrue(!sequence.isDone());
+ Assert.assertFalse(sequence.isDone());
Assert.assertTrue(sequence.isCancelled());
// Start the sequence

Back to the top