Bug 368581 - JobManager does not wake up a scheduled job
diff --git a/bundles/org.eclipse.core.jobs/META-INF/MANIFEST.MF b/bundles/org.eclipse.core.jobs/META-INF/MANIFEST.MF
index d10a320..4b5cead 100644
--- a/bundles/org.eclipse.core.jobs/META-INF/MANIFEST.MF
+++ b/bundles/org.eclipse.core.jobs/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@
 Bundle-ManifestVersion: 2
 Bundle-Name: %pluginName
 Bundle-SymbolicName: org.eclipse.core.jobs; singleton:=true
-Bundle-Version: 3.5.100.qualifier
+Bundle-Version: 3.5.101.qualifier
 Bundle-Vendor: %providerName
 Bundle-Localization: plugin
 Export-Package: org.eclipse.core.internal.jobs;x-internal:=true,
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 bd86bbb..bf2afd7 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
@@ -240,7 +240,7 @@
 					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/META-INF/MANIFEST.MF b/tests/org.eclipse.core.tests.runtime/META-INF/MANIFEST.MF
index e480d20..0c174be 100644
--- a/tests/org.eclipse.core.tests.runtime/META-INF/MANIFEST.MF
+++ b/tests/org.eclipse.core.tests.runtime/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@
 Bundle-ManifestVersion: 2
 Bundle-Name: Eclipse Core Tests Runtime
 Bundle-SymbolicName: org.eclipse.core.tests.runtime; singleton:=true
-Bundle-Version: 3.7.1.qualifier
+Bundle-Version: 3.7.2.qualifier
 Bundle-ClassPath: runtimetests.jar
 Bundle-Activator: org.eclipse.core.tests.runtime.RuntimeTestsPlugin
 Bundle-Vendor: Eclipse.org
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 0000000..a64b8b1
--- /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);

+	}

+

+}
\ No newline at end of file