Skip to content

Commit 14cb97b

Browse files
Copilotlaeubi
andcommitted
Fix Job.schedule() not rescheduling after cancel()
The aboutToRunCanceled flag was not being cleared when reschedule=true, causing jobs to be canceled instead of scheduled. This fix moves the flag clearing to after the early returns, ensuring it's always cleared when actually scheduling the job. Test verifies that Job.schedule() works correctly after cancel() when called on a running job. This reproduces the issue where the aboutToRunCanceled flag was not being cleared during reschedule. Co-authored-by: laeubi <[email protected]>
1 parent 70d775d commit 14cb97b

File tree

2 files changed

+41
-3
lines changed
  • runtime
    • bundles/org.eclipse.core.jobs/src/org/eclipse/core/internal/jobs
    • tests/org.eclipse.core.tests.runtime/src/org/eclipse/core/tests/runtime/jobs

2 files changed

+41
-3
lines changed

runtime/bundles/org.eclipse.core.jobs/src/org/eclipse/core/internal/jobs/JobManager.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1486,9 +1486,6 @@ protected boolean scheduleInternal(InternalJob job, long delay, boolean reschedu
14861486
}
14871487
Assert.isNotNull(job, "Job is null"); //$NON-NLS-1$
14881488
Assert.isLegal(delay >= 0, "Scheduling delay is negative"); //$NON-NLS-1$
1489-
if (!reschedule) {
1490-
job.setAboutToRunCanceled(false);
1491-
}
14921489
// if the job is already running, set it to be rescheduled when done
14931490
if (job.getState() == Job.RUNNING) {
14941491
job.setStartTime(delay); // XXX delay used as time
@@ -1498,6 +1495,10 @@ protected boolean scheduleInternal(InternalJob job, long delay, boolean reschedu
14981495
if (job.internalGetState() != Job.NONE) {
14991496
return false;
15001497
}
1498+
// Clear the about to run canceled flag when actually scheduling.
1499+
// A new explicit schedule() call should override any previous cancel() call.
1500+
// See https://github.com/eclipse-platform/eclipse.platform/issues/160
1501+
job.setAboutToRunCanceled(false);
15011502
if (JobManager.DEBUG) {
15021503
JobManager.debug("Scheduling job: " + job); //$NON-NLS-1$
15031504
}

runtime/tests/org.eclipse.core.tests.runtime/src/org/eclipse/core/tests/runtime/jobs/Bug_550738.java

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,4 +134,41 @@ public void testReportDoneOncePerSchedule() throws InterruptedException {
134134
waitForCompletion(job);
135135
}
136136
}
137+
138+
/**
139+
* Test for issue #160: Job.schedule() should work after cancel() when job is running.
140+
* This tests the specific scenario where:
141+
* 1. Job is running
142+
* 2. cancel() is called
143+
* 3. schedule() is called immediately (while still running)
144+
* 4. Job finishes and should reschedule
145+
*/
146+
@Test
147+
public void testCancelThenScheduleWhileRunning() throws InterruptedException {
148+
BusyLoopJob job = new BusyLoopJob();
149+
try {
150+
for (int i = 0; i < 100; i++) {
151+
CountDownLatch startedLatch = new CountDownLatch(1);
152+
job.started = startedLatch::countDown;
153+
job.schedule();
154+
assertTrue("Job should start after schedule. Iteration " + i,
155+
startedLatch.await(5, TimeUnit.SECONDS));
156+
157+
// While job is running, cancel it and then immediately schedule it again
158+
Thread.sleep(i);
159+
job.cancel();
160+
job.schedule();
161+
162+
// The job should reschedule and not remain in NONE state
163+
// Wait a bit to ensure the rescheduling happens
164+
Thread.sleep(50);
165+
int state = job.getState();
166+
assertTrue("Job should not be in NONE state after cancel+schedule. Iteration " + i + ", state: " + state,
167+
state != org.eclipse.core.runtime.jobs.Job.NONE);
168+
}
169+
} finally {
170+
job.cancelWithoutRelyingOnFramework = true;
171+
waitForCompletion(job);
172+
}
173+
}
137174
}

0 commit comments

Comments
 (0)