Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian W. Damus2014-07-16 15:48:12 +0000
committerChristian W. Damus2014-07-16 15:50:33 +0000
commit2f5c8b0f46b6e256d6a98a650a61a85ff2291653 (patch)
tree4a421bd7750284cef7024d5dfba965ab10b14002 /extraplugins
parent82a73c86ead403dcd3e7e70197456eacb8973c3e (diff)
downloadorg.eclipse.papyrus-2f5c8b0f46b6e256d6a98a650a61a85ff2291653.tar.gz
org.eclipse.papyrus-2f5c8b0f46b6e256d6a98a650a61a85ff2291653.tar.xz
org.eclipse.papyrus-2f5c8b0f46b6e256d6a98a650a61a85ff2291653.zip
439725: [CDO] JobWaiter time-out on wait for a job family is unreliable
on some platforms https://bugs.eclipse.org/bugs/show_bug.cgi?id=439725 Refactor the specific job wait-listener to support also waiting for job families. Incidentally fixes a problem of job listeners never being removed from the job manager and waits for specific jobs finishing when any job at all completes.
Diffstat (limited to 'extraplugins')
-rw-r--r--extraplugins/cdo/org.eclipse.papyrus.cdo.core/src/org/eclipse/papyrus/cdo/core/util/JobWaiter.java79
1 files changed, 64 insertions, 15 deletions
diff --git a/extraplugins/cdo/org.eclipse.papyrus.cdo.core/src/org/eclipse/papyrus/cdo/core/util/JobWaiter.java b/extraplugins/cdo/org.eclipse.papyrus.cdo.core/src/org/eclipse/papyrus/cdo/core/util/JobWaiter.java
index e292fc6b102..cdce25a45b4 100644
--- a/extraplugins/cdo/org.eclipse.papyrus.cdo.core/src/org/eclipse/papyrus/cdo/core/util/JobWaiter.java
+++ b/extraplugins/cdo/org.eclipse.papyrus.cdo.core/src/org/eclipse/papyrus/cdo/core/util/JobWaiter.java
@@ -1,5 +1,5 @@
/*****************************************************************************
- * Copyright (c) 2013 CEA LIST.
+ * Copyright (c) 2013, 2014 CEA LIST and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
@@ -8,6 +8,8 @@
*
* Contributors:
* CEA LIST - Initial API and implementation
+ * Christian W. Damus (CEA) - bug 439725
+ *
*****************************************************************************/
package org.eclipse.papyrus.cdo.core.util;
@@ -101,7 +103,8 @@ public class JobWaiter {
// actual implementation in the JobManager is not
new JobFinishListener(targetJob).await();
} else {
- Job.getJobManager().join(targetFamily, null);
+ // On some platforms, cancellation of a family join is not reliable
+ new FamilyFinishListener(targetFamily).await();
}
result = true;
@@ -134,6 +137,7 @@ public class JobWaiter {
private final AtomicBoolean timedOut = new AtomicBoolean();
+ @Override
public void run() {
if(!cancelled.get()) {
timedOut.set(true);
@@ -150,35 +154,80 @@ public class JobWaiter {
}
}
- private static final class JobFinishListener extends JobChangeAdapter {
-
- private final Job job;
+ private static abstract class FinishListener extends JobChangeAdapter {
private boolean done;
- JobFinishListener(Job job) {
+ FinishListener() {
super();
- this.job = job;
Job.getJobManager().addJobChangeListener(this);
}
+ void dispose() {
+ Job.getJobManager().removeJobChangeListener(this);
+ }
+
synchronized void await() throws InterruptedException {
- for(;;) {
- // check running state because it may have finished already before we got here
- if(done || (job.getState() != Job.RUNNING)) {
- break;
+ try {
+ for(;;) {
+ // Check done condition because our job/family may have finished already before we got here
+ if(done || checkDone()) {
+ break;
+ }
+
+ wait();
}
-
- wait();
+ } finally {
+ // Can only wait on me once
+ dispose();
}
}
@Override
public synchronized void done(IJobChangeEvent event) {
- done = true;
+ if(checkDone()) {
+ try {
+ done = true;
+ dispose();
+ } finally {
+ notifyAll();
+ }
+ }
+ }
+
+ protected abstract boolean checkDone();
+ }
- notifyAll();
+ private static final class JobFinishListener extends FinishListener {
+
+ private final Job job;
+
+ JobFinishListener(Job job) {
+ super();
+
+ this.job = job;
+ }
+
+ @Override
+ protected boolean checkDone() {
+ return job.getState() != Job.RUNNING;
+ }
+ }
+
+ private static final class FamilyFinishListener extends FinishListener {
+
+ private final Object family;
+
+ FamilyFinishListener(Object family) {
+ super();
+
+ this.family = family;
+ }
+
+ @Override
+ protected boolean checkDone() {
+ return Job.getJobManager().find(family).length == 0;
}
}
}

Back to the top