提交 63d3b264 编写于 作者: K Kohsuke Kawaguchi

Fixed a race condition.

IIUC, the expectation here is that Queue.Executable will instantiate AsynchronousException as a handle, start something asynchronously (say send a JMS message) with a callback, and the callback will tickle AsynchronousException.

So AsynchronousException might complete before it gets its executor set. This code change ensures that that case gets handled correctly.
上级 4a7c2714
......@@ -55,6 +55,7 @@ import org.kohsuke.accmod.restrictions.NoExternalUse;
public abstract class AsynchronousExecution extends RuntimeException {
private Executor executor;
private Throwable result;
/** Constructor for subclasses. */
protected AsynchronousExecution() {}
......@@ -89,21 +90,33 @@ public abstract class AsynchronousExecution extends RuntimeException {
/**
* Obtains the associated executor.
*/
public final Executor getExecutor() {
public synchronized final Executor getExecutor() {
return executor;
}
@Restricted(NoExternalUse.class)
public final void setExecutor(Executor executor) {
public synchronized final void setExecutor(Executor executor) {
assert this.executor==null;
this.executor = executor;
if (result!=null) {
executor.completedAsynchronous( result!=NULL ? result : null );
result = null;
}
}
/**
* To be called when the task is actually complete.
* @param error normally null (preferable to handle errors yourself), but may be specified to simulate an exception from {@link Executable#run}, as per {@link ExecutorListener#taskCompletedWithProblems}
*/
public final void completed(@CheckForNull Throwable error) {
executor.completedAsynchronous(error);
public synchronized final void completed(@CheckForNull Throwable error) {
if (executor!=null) {
executor.completedAsynchronous(error);
} else {
result = error == null ? NULL : error;
}
}
private static final Throwable NULL = new Throwable("NULL");
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册