Bug 336644 - Backport: ThreadJob#waitForRun can spin when blockingJob is not RUNNING
diff --git a/bundles/org.eclipse.core.jobs/META-INF/MANIFEST.MF b/bundles/org.eclipse.core.jobs/META-INF/MANIFEST.MF
index 5efc247..ccbe186 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.1.qualifier
+Bundle-Version: 3.5.2.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/ThreadJob.java b/bundles/org.eclipse.core.jobs/src/org/eclipse/core/internal/jobs/ThreadJob.java
index 146559e..6b9cf92 100644
--- a/bundles/org.eclipse.core.jobs/src/org/eclipse/core/internal/jobs/ThreadJob.java
+++ b/bundles/org.eclipse.core.jobs/src/org/eclipse/core/internal/jobs/ThreadJob.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2004, 2010 IBM Corporation and others.
+ * Copyright (c) 2004, 2011 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
@@ -262,11 +262,13 @@
 					try {
 						// Wait until we are no longer definitely blocked (not running). 
 						// The actual exit conditions are listed above at the beginning of
-						// this while loop. 
-						if (blockingJob.getState() == Job.RUNNING)
-							// If we canBlock do not use a timeout value. Otherwise, 
-							// timeout and recheck conditions other than #1 (above). 
-							blockingJob.jobStateLock.wait(canBlock ? 0 : 250);
+						// this while loop
+						int state = blockingJob.getState();
+						//ensure we don't wait forever if the blocker is waiting, because it might have yielded to me
+						if (state == Job.RUNNING && canBlock)
+							blockingJob.jobStateLock.wait();
+						else if (state != Job.NONE)
+							blockingJob.jobStateLock.wait(250);
 					} catch (InterruptedException e) {
 						// This thread may be interrupted via two common scenarios. 1) If
 						// the UISynchronizer is in use and this thread is a UI thread
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 4d5fe5b..9faf52e 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.6.1.qualifier
+Bundle-Version: 3.6.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_307282.java b/tests/org.eclipse.core.tests.runtime/src/org/eclipse/core/tests/runtime/jobs/Bug_307282.java
index f28f46d..75ea9fa 100644
--- a/tests/org.eclipse.core.tests.runtime/src/org/eclipse/core/tests/runtime/jobs/Bug_307282.java
+++ b/tests/org.eclipse.core.tests.runtime/src/org/eclipse/core/tests/runtime/jobs/Bug_307282.java
@@ -106,7 +106,7 @@
 		assertTrue(!lock2.acquire(0));
 
 		tb2.setStatus(RELEASE_LOCK);
-		assertTrue(lock2.acquire(100));
+		assertTrue(lock2.acquire(1000));
 
 		tb1.setStatus(TestBarrier.STATUS_WAIT_FOR_DONE);
 		tb2.setStatus(TestBarrier.STATUS_WAIT_FOR_DONE);
diff --git a/tests/org.eclipse.core.tests.runtime/src/org/eclipse/core/tests/runtime/jobs/Bug_320329.java b/tests/org.eclipse.core.tests.runtime/src/org/eclipse/core/tests/runtime/jobs/Bug_320329.java
new file mode 100644
index 0000000..ae26a85
--- /dev/null
+++ b/tests/org.eclipse.core.tests.runtime/src/org/eclipse/core/tests/runtime/jobs/Bug_320329.java
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ * Copyright (c) 2011 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:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.core.tests.runtime.jobs;
+
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.jobs.*;
+import org.eclipse.core.tests.harness.TestJob;
+
+/**
+ * Regression test for bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=320329.
+ */
+public class Bug_320329 extends AbstractJobManagerTest {
+
+	public void testBug() {
+		Job j1 = new TestJob("job1", 1000, 50);//5 seconds
+		Job j2 = new TestJob("job2");
+		ISchedulingRule rule1 = new IdentityRule();
+		ISchedulingRule rule2 = new IdentityRule();
+
+		j1.setRule(rule1);
+		j2.setRule(MultiRule.combine(rule1, rule2));
+		j1.schedule();
+		j2.schedule();
+
+		// busy wait here
+		Job.getJobManager().beginRule(rule2, new NullProgressMonitor());
+
+		// Clean up
+		Job.getJobManager().endRule(rule2);
+		waitForCompletion(j1);
+		waitForCompletion(j2);
+	}
+}
diff --git a/tests/org.eclipse.core.tests.runtime/src/org/eclipse/core/tests/runtime/jobs/YieldTest.java b/tests/org.eclipse.core.tests.runtime/src/org/eclipse/core/tests/runtime/jobs/YieldTest.java
index 2ea218b..6962655 100644
--- a/tests/org.eclipse.core.tests.runtime/src/org/eclipse/core/tests/runtime/jobs/YieldTest.java
+++ b/tests/org.eclipse.core.tests.runtime/src/org/eclipse/core/tests/runtime/jobs/YieldTest.java
@@ -839,7 +839,7 @@
 		final TestBarrier barrier = new TestBarrier();
 		final PathRule rule = new PathRule(getName());
 
-		final int count = 100;
+		final int count = 50;
 		Job yieldA = new Job(getName() + " YieldingA") {
 			protected IStatus run(IProgressMonitor monitor) {
 				barrier.waitForStatus(TestBarrier.STATUS_START);
@@ -878,7 +878,7 @@
 
 		// wait for jobs to start
 		try {
-			Thread.sleep(1000);
+			Thread.sleep(10000);
 		} catch (InterruptedException e) {
 			fail("4.99", e);
 		}