| /******************************************************************************* |
| * Copyright (c) 2010, 2012 Broadcom 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: |
| * James Blackburn (Broadcom Corp.) - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.core.tests.runtime.jobs; |
| |
| import org.eclipse.core.runtime.*; |
| import org.eclipse.core.runtime.jobs.Job; |
| import org.eclipse.core.tests.harness.TestBarrier; |
| |
| /** |
| * Regression test for bug 307391 |
| * 'ImplicitJob' style Job doesn't correctly leave YIELDING state |
| */ |
| public class Bug_307391 extends AbstractJobManagerTest { |
| |
| /** |
| * Threads: main, j, t2 |
| * Locks: idSchedRule |
| * |
| * j owns idSchedRule with beginRule, t2 tries to acquire it |
| * |
| * Trips assertion: |
| * java.lang.IllegalArgumentException: Cannot yieldRule job that is YIELDING |
| * in JobManager#yieldRule |
| * |
| * @throws Exception |
| */ |
| public void testYieldWithlockAcquire() throws Exception { |
| final IdentityRule idSchedRule = new IdentityRule(); |
| |
| final TestBarrier tb1 = new TestBarrier(-1); |
| final TestBarrier tb2 = new TestBarrier(-1); |
| |
| final int YIELD2 = 10002; |
| final int ACQUIRE2 = 1005; |
| |
| // Job run with a scheduling rule begun inline |
| // yields it to the thread |
| Job j = new Job("rule-holding, lock-wanting job") { |
| @Override |
| protected IStatus run(IProgressMonitor monitor) { |
| Job.getJobManager().beginRule(idSchedRule, null); |
| |
| tb1.setStatus(TestBarrier.STATUS_WAIT_FOR_START); |
| tb1.waitForStatus(TestBarrier.STATUS_START); |
| |
| // Yield our rule |
| Job.getJobManager().currentJob().yieldRule(null); |
| |
| tb1.waitForStatusNoFail(YIELD2); |
| // Yield our rule |
| Job.getJobManager().currentJob().yieldRule(null); |
| tb1.setStatus(YIELD2); |
| |
| // The test executed successfully |
| Job.getJobManager().endRule(idSchedRule); |
| tb1.setStatus(TestBarrier.STATUS_DONE); |
| return Status.OK_STATUS; |
| } |
| }; |
| |
| Thread t2 = new Thread() { |
| public void run() { |
| tb2.setStatus(TestBarrier.STATUS_WAIT_FOR_START); |
| tb2.waitForStatus(TestBarrier.STATUS_START); |
| |
| Job.getJobManager().beginRule(idSchedRule, null); |
| Job.getJobManager().endRule(idSchedRule); |
| |
| tb2.waitForStatus(ACQUIRE2); |
| Job.getJobManager().beginRule(idSchedRule, null); |
| Job.getJobManager().endRule(idSchedRule); |
| |
| // that all went well, signal we've passed |
| tb2.setStatus(TestBarrier.STATUS_DONE); |
| } |
| }; |
| |
| // Start the threads |
| j.schedule(); |
| t2.start(); |
| |
| // wait for the threads to get to start and acquire sched rules |
| tb1.waitForStatus(TestBarrier.STATUS_WAIT_FOR_START); |
| tb2.waitForStatus(TestBarrier.STATUS_WAIT_FOR_START); |
| |
| // first acquire and yield |
| tb2.setStatus(TestBarrier.STATUS_START); |
| Thread.sleep(1000); |
| tb1.setStatus(TestBarrier.STATUS_START); |
| |
| // second acquire and yield |
| tb2.setStatus(ACQUIRE2); |
| Thread.sleep(1000); |
| tb1.setStatus(YIELD2); |
| |
| // Wait for them to finish |
| tb1.waitForStatus(TestBarrier.STATUS_DONE); |
| tb2.waitForStatus(TestBarrier.STATUS_DONE); |
| } |
| } |