X-Git-Url: https://code.wpia.club/?p=gigi.git;a=blobdiff_plain;f=lib%2Fjetty%2Forg%2Feclipse%2Fjetty%2Futil%2FCompletableCallback.java;h=674afd5330cb5702d28e839e7f91f5cdac42cef3;hp=ec5a30a84e6f1241bbcc6433aab611ba8ae2f771;hb=ba4f228fa9f72d50991a2218cfd83987ef5d385e;hpb=73ef54a38e3930a1a789cdc6b5fa23cdd4c9d086 diff --git a/lib/jetty/org/eclipse/jetty/util/CompletableCallback.java b/lib/jetty/org/eclipse/jetty/util/CompletableCallback.java index ec5a30a8..674afd53 100644 --- a/lib/jetty/org/eclipse/jetty/util/CompletableCallback.java +++ b/lib/jetty/org/eclipse/jetty/util/CompletableCallback.java @@ -1,6 +1,6 @@ // // ======================================================================== -// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. +// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd. // ------------------------------------------------------------------------ // All rights reserved. This program and the accompanying materials // are made available under the terms of the Eclipse Public License v1.0 @@ -18,7 +18,7 @@ package org.eclipse.jetty.util; -import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicReference; /** * A callback to be used by driver code that needs to know whether the callback has been @@ -57,20 +57,71 @@ import java.util.concurrent.atomic.AtomicBoolean; */ public abstract class CompletableCallback implements Callback { - private final AtomicBoolean completed = new AtomicBoolean(); + private final AtomicReference state = new AtomicReference<>(State.IDLE); @Override public void succeeded() { - if (!tryComplete()) - resume(); + while (true) + { + State current = state.get(); + switch (current) + { + case IDLE: + { + if (state.compareAndSet(current, State.SUCCEEDED)) + return; + break; + } + case COMPLETED: + { + if (state.compareAndSet(current, State.SUCCEEDED)) + { + resume(); + return; + } + break; + } + case FAILED: + { + return; + } + default: + { + throw new IllegalStateException(current.toString()); + } + } + } } @Override public void failed(Throwable x) { - if (!tryComplete()) - abort(x); + while (true) + { + State current = state.get(); + switch (current) + { + case IDLE: + case COMPLETED: + { + if (state.compareAndSet(current, State.FAILED)) + { + abort(x); + return; + } + break; + } + case FAILED: + { + return; + } + default: + { + throw new IllegalStateException(current.toString()); + } + } + } } /** @@ -80,8 +131,7 @@ public abstract class CompletableCallback implements Callback public abstract void resume(); /** - * Callback method invoked when this callback is failed - * after a first call to {@link #tryComplete()}. + * Callback method invoked when this callback is failed. */ public abstract void abort(Throwable failure); @@ -95,6 +145,32 @@ public abstract class CompletableCallback implements Callback */ public boolean tryComplete() { - return completed.compareAndSet(false, true); + while (true) + { + State current = state.get(); + switch (current) + { + case IDLE: + { + if (state.compareAndSet(current, State.COMPLETED)) + return true; + break; + } + case SUCCEEDED: + case FAILED: + { + return false; + } + default: + { + throw new IllegalStateException(current.toString()); + } + } + } + } + + private enum State + { + IDLE, SUCCEEDED, FAILED, COMPLETED } }