aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSzymon Ptaszkiewicz2014-01-15 05:51:49 (EST)
committerGerrit Code Review @ Eclipse.org2014-02-14 07:35:44 (EST)
commitde700a09e57a02876a9c5a888b76f604df300555 (patch)
treeac176c453204beb538854544212b0adf8339efc7
parent39d2772b91c00fe6c6d7dbccf135a2fd20bde60b (diff)
downloadeclipse.platform.runtime-de700a09e57a02876a9c5a888b76f604df300555.zip
eclipse.platform.runtime-de700a09e57a02876a9c5a888b76f604df300555.tar.gz
eclipse.platform.runtime-de700a09e57a02876a9c5a888b76f604df300555.tar.bz2
Bug 293312 - Job.join() can not be interrupted even though the javadoc says it canI20140218-0800refs/changes/45/20645/3
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.java10
-rw-r--r--tests/org.eclipse.core.tests.runtime/src/org/eclipse/core/tests/runtime/jobs/JobTest.java52
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 d433cc6..e553003 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 4ead549..11fca61 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()}.