Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -1486,9 +1486,6 @@ protected boolean scheduleInternal(InternalJob job, long delay, boolean reschedu
}
Assert.isNotNull(job, "Job is null"); //$NON-NLS-1$
Assert.isLegal(delay >= 0, "Scheduling delay is negative"); //$NON-NLS-1$
if (!reschedule) {
job.setAboutToRunCanceled(false);
}
// if the job is already running, set it to be rescheduled when done
if (job.getState() == Job.RUNNING) {
job.setStartTime(delay); // XXX delay used as time
Expand All @@ -1498,6 +1495,10 @@ protected boolean scheduleInternal(InternalJob job, long delay, boolean reschedu
if (job.internalGetState() != Job.NONE) {
return false;
}
// Clear the about to run canceled flag when actually scheduling.
// A new explicit schedule() call should override any previous cancel() call.
// See https://github.com/eclipse-platform/eclipse.platform/issues/160
job.setAboutToRunCanceled(false);
if (JobManager.DEBUG) {
JobManager.debug("Scheduling job: " + job); //$NON-NLS-1$
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -134,4 +134,41 @@ public void testReportDoneOncePerSchedule() throws InterruptedException {
waitForCompletion(job);
}
}

/**
* Test for issue #160: Job.schedule() should work after cancel() when job is running.
* This tests the specific scenario where:
* 1. Job is running
* 2. cancel() is called
* 3. schedule() is called immediately (while still running)
* 4. Job finishes and should reschedule
*/
@Test
public void testCancelThenScheduleWhileRunning() throws InterruptedException {
BusyLoopJob job = new BusyLoopJob();
try {
for (int i = 0; i < 100; i++) {
CountDownLatch startedLatch = new CountDownLatch(1);
job.started = startedLatch::countDown;
job.schedule();
assertTrue("Job should start after schedule. Iteration " + i,
startedLatch.await(5, TimeUnit.SECONDS));

// While job is running, cancel it and then immediately schedule it again
Thread.sleep(i);
job.cancel();
job.schedule();

// The job should reschedule and not remain in NONE state
// Wait a bit to ensure the rescheduling happens
Thread.sleep(50);
int state = job.getState();
assertTrue("Job should not be in NONE state after cancel+schedule. Iteration " + i + ", state: " + state,
state != org.eclipse.core.runtime.jobs.Job.NONE);
}
} finally {
job.cancelWithoutRelyingOnFramework = true;
waitForCompletion(job);
}
}
}