diff options
author | Christian W. Damus | 2014-07-16 15:48:12 +0000 |
---|---|---|
committer | Christian W. Damus | 2014-07-16 15:50:33 +0000 |
commit | 2f5c8b0f46b6e256d6a98a650a61a85ff2291653 (patch) | |
tree | 4a421bd7750284cef7024d5dfba965ab10b14002 /extraplugins | |
parent | 82a73c86ead403dcd3e7e70197456eacb8973c3e (diff) | |
download | org.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.java | 79 |
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; } } } |