diff options
author | John Arthorne | 2012-01-13 19:13:03 +0000 |
---|---|---|
committer | John Arthorne | 2012-01-13 19:13:17 +0000 |
commit | 7c6740abca3b0243a4a745665df56d4372a1e16d (patch) | |
tree | f7e0ab07e238f074710c166b744fdc0f48062d63 | |
parent | 7224e6030758d5efcb82d8177eb3f8e6055c8197 (diff) | |
download | eclipse.platform.runtime-7c6740abca3b0243a4a745665df56d4372a1e16d.tar.gz eclipse.platform.runtime-7c6740abca3b0243a4a745665df56d4372a1e16d.tar.xz eclipse.platform.runtime-7c6740abca3b0243a4a745665df56d4372a1e16d.zip |
Bug 366170 - JobManager does not wake up a scheduled jobv20120113-1913
-rw-r--r-- | bundles/org.eclipse.core.jobs/src/org/eclipse/core/internal/jobs/WorkerPool.java | 4 | ||||
-rw-r--r-- | tests/org.eclipse.core.tests.runtime/src/org/eclipse/core/tests/runtime/jobs/Bug_366170.java | 109 |
2 files changed, 111 insertions, 2 deletions
diff --git a/bundles/org.eclipse.core.jobs/src/org/eclipse/core/internal/jobs/WorkerPool.java b/bundles/org.eclipse.core.jobs/src/org/eclipse/core/internal/jobs/WorkerPool.java index bd86bbbca..635440e42 100644 --- a/bundles/org.eclipse.core.jobs/src/org/eclipse/core/internal/jobs/WorkerPool.java +++ b/bundles/org.eclipse.core.jobs/src/org/eclipse/core/internal/jobs/WorkerPool.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2003, 2010 IBM Corporation and others. + * Copyright (c) 2003, 2012 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -240,7 +240,7 @@ class WorkerPool { manager.getLockManager().addLockThread(Thread.currentThread(), job.getRule()); } //see if we need to wake another worker - if (manager.sleepHint() <= 0) + if (manager.sleepHint() < InternalJob.T_INFINITE) jobQueued(); } } finally { diff --git a/tests/org.eclipse.core.tests.runtime/src/org/eclipse/core/tests/runtime/jobs/Bug_366170.java b/tests/org.eclipse.core.tests.runtime/src/org/eclipse/core/tests/runtime/jobs/Bug_366170.java new file mode 100644 index 000000000..18cbf1e20 --- /dev/null +++ b/tests/org.eclipse.core.tests.runtime/src/org/eclipse/core/tests/runtime/jobs/Bug_366170.java @@ -0,0 +1,109 @@ +/******************************************************************************* + * Copyright (c) 2012 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * ivan.motsch@bsiag.com - initial example + * IBM Corporation - converted to JUnit test + *******************************************************************************/ +package org.eclipse.core.tests.runtime.jobs; + +import java.util.concurrent.Semaphore; +import org.eclipse.core.runtime.*; +import org.eclipse.core.runtime.jobs.Job; + +/** + * Tests that scheduling multiple jobs with a delay and then blocking all active + * worker threads doesn't cause job manager to starve. This is a regression + * test for a situation where all worker threads were blocked and no workers + * were available to process sleeping jobs awaiting execution. For details see: + * https://bugs.eclipse.org/bugs/show_bug.cgi?id=366170 + */ +public class Bug_366170 extends AbstractJobManagerTest { + private Semaphore m_jobBStopHint = new Semaphore(1); + + public void testBug() throws Exception { + System.out.println("--- Running the examle ---"); + m_jobBStopHint.acquire(); + scheduleJobA(200); + scheduleJobC(300); + + Thread.sleep(2000L); + + //lock should now be free if C is finished + assertTrue("Failed: Job C was not run", m_jobBStopHint.tryAcquire()); + } + + private void scheduleJobA(long delay) throws Exception { + Job job = new Job("A") { + @Override + public boolean shouldSchedule() { + System.out.println("schedule " + getName()); + return true; + } + + protected IStatus run(IProgressMonitor monitor) { + System.out.println("begin " + getName()); + try { + scheduleJobB(0).join(); + } catch (Throwable t) { + t.printStackTrace(); + } + System.out.println("end " + getName()); + return Status.OK_STATUS; + } + }; + job.setSystem(true); + job.schedule(delay); + } + + private Job scheduleJobB(long delay) throws Exception { + Job job = new Job("B") { + @Override + public boolean shouldSchedule() { + System.out.println("schedule " + getName()); + return true; + } + + @Override + protected IStatus run(IProgressMonitor monitor) { + System.out.println("begin " + getName()); + try { + m_jobBStopHint.acquire(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + m_jobBStopHint.release(); + System.out.println("end " + getName()); + return Status.OK_STATUS; + } + }; + job.setSystem(true); + job.schedule(delay); + return job; + } + + private void scheduleJobC(long delay) throws Exception { + Job job = new Job("C") { + @Override + public boolean shouldSchedule() { + System.out.println("schedule " + getName()); + return true; + } + + @Override + protected IStatus run(IProgressMonitor monitor) { + System.out.println("begin " + getName()); + m_jobBStopHint.release(); + System.out.println("end " + getName()); + return Status.OK_STATUS; + } + }; + job.setSystem(true); + job.schedule(delay); + } + +} |