diff options
author | Szymon Ptaszkiewicz | 2014-01-15 10:51:49 +0000 |
---|---|---|
committer | Gerrit Code Review @ Eclipse.org | 2014-02-14 12:35:44 +0000 |
commit | de700a09e57a02876a9c5a888b76f604df300555 (patch) | |
tree | ac176c453204beb538854544212b0adf8339efc7 | |
parent | 39d2772b91c00fe6c6d7dbccf135a2fd20bde60b (diff) | |
download | eclipse.platform.runtime-de700a09e57a02876a9c5a888b76f604df300555.tar.gz eclipse.platform.runtime-de700a09e57a02876a9c5a888b76f604df300555.tar.xz eclipse.platform.runtime-de700a09e57a02876a9c5a888b76f604df300555.zip |
Bug 293312 - Job.join() can not be interrupted even though the javadoc says it canI20140218-0800
Change-Id: Ib4a0c6a7df56a2f3e5050d038e62bb14562feadf
Signed-off-by: Szymon Ptaszkiewicz <szymon.ptaszkiewicz@pl.ibm.com>
-rw-r--r-- | bundles/org.eclipse.core.jobs/src/org/eclipse/core/internal/jobs/JobManager.java | 10 | ||||
-rw-r--r-- | tests/org.eclipse.core.tests.runtime/src/org/eclipse/core/tests/runtime/jobs/JobTest.java | 52 |
2 files changed, 58 insertions, 4 deletions
diff --git a/bundles/org.eclipse.core.jobs/src/org/eclipse/core/internal/jobs/JobManager.java b/bundles/org.eclipse.core.jobs/src/org/eclipse/core/internal/jobs/JobManager.java index d433cc6b7..e553003b1 100644 --- a/bundles/org.eclipse.core.jobs/src/org/eclipse/core/internal/jobs/JobManager.java +++ b/bundles/org.eclipse.core.jobs/src/org/eclipse/core/internal/jobs/JobManager.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2003, 2013 IBM Corporation and others. + * Copyright (c) 2003, 2014 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 @@ -814,7 +814,7 @@ public class JobManager implements IJobManager { /* (non-Javadoc) * @see org.eclipse.core.runtime.jobs.Job#job(org.eclipse.core.runtime.jobs.Job) */ - protected void join(InternalJob job) { + protected void join(InternalJob job) throws InterruptedException { final IJobChangeListener listener; final Semaphore barrier; synchronized (lock) { @@ -840,6 +840,7 @@ public class JobManager implements IJobManager { } //wait until listener notifies this thread. try { + boolean canBlock = lockManager.canBlock(); while (true) { //notify hook to service pending syncExecs before falling asleep lockManager.aboutToWait(job.getThread()); @@ -847,7 +848,10 @@ public class JobManager implements IJobManager { if (barrier.acquire(Long.MAX_VALUE)) break; } catch (InterruptedException e) { - //loop and keep trying + // if non-UI thread, re-throw the exception + if (canBlock) + throw e; + // if UI thread, loop and keep trying } } } finally { diff --git a/tests/org.eclipse.core.tests.runtime/src/org/eclipse/core/tests/runtime/jobs/JobTest.java b/tests/org.eclipse.core.tests.runtime/src/org/eclipse/core/tests/runtime/jobs/JobTest.java index 4ead549bf..11fca617e 100644 --- a/tests/org.eclipse.core.tests.runtime/src/org/eclipse/core/tests/runtime/jobs/JobTest.java +++ b/tests/org.eclipse.core.tests.runtime/src/org/eclipse/core/tests/runtime/jobs/JobTest.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2003, 2012 IBM Corporation and others. + * Copyright (c) 2003, 2014 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 @@ -829,6 +829,56 @@ public class JobTest extends AbstractJobTest { TestBarrier.waitForStatus(status, TestBarrier.STATUS_DONE); } + public void testJoinInterruptNonUIThread() throws InterruptedException { + final Job job = new TestJob("job", 1000, 100); + Thread t = new Thread(new Runnable() { + public void run() { + job.schedule(); + try { + job.join(); + } catch (InterruptedException e) { + job.cancel(); + } + } + }); + t.start(); + // make sure the job is running before we interrupt the thread + waitForState(job, Job.RUNNING); + t.interrupt(); + job.join(); + assertTrue("Thread not interrupted", job.getResult() == Status.CANCEL_STATUS); + } + + public void testJoinInterruptUIThread() throws InterruptedException { + final Job job = new TestJob("job", 1000, 100); + Thread t = new Thread(new Runnable() { + public void run() { + job.schedule(); + try { + job.join(); + } catch (InterruptedException e) { + job.cancel(); + } + } + }); + try { + Job.getJobManager().setLockListener(new LockListener() { + public boolean canBlock() { + // pretend to be the UI thread + return false; + } + }); + t.start(); + // make sure the job is running before we interrupt the thread + waitForState(job, Job.RUNNING); + t.interrupt(); + job.join(); + assertTrue("Thread interrupted", job.getResult() == Status.OK_STATUS); + } finally { + Job.getJobManager().setLockListener(null); + } + } + /** * Asserts that the LockListener is called correctly during invocation of * {@link Job#join()}. |