2 // ========================================================================
3 // Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
4 // ------------------------------------------------------------------------
5 // All rights reserved. This program and the accompanying materials
6 // are made available under the terms of the Eclipse Public License v1.0
7 // and Apache License v2.0 which accompanies this distribution.
9 // The Eclipse Public License is available at
10 // http://www.eclipse.org/legal/epl-v10.html
12 // The Apache License v2.0 is available at
13 // http://www.opensource.org/licenses/apache2.0.php
15 // You may elect to redistribute this code under either of these licenses.
16 // ========================================================================
19 package org.eclipse.jetty.util;
21 import java.util.concurrent.atomic.AtomicReference;
24 * A callback to be used by driver code that needs to know whether the callback has been
25 * succeeded or failed (that is, completed) just after the asynchronous operation or not,
26 * typically because further processing depends on the callback being completed.
27 * The driver code competes with the asynchronous operation to complete the callback.
29 * If the callback is already completed, the driver code continues the processing,
30 * otherwise it suspends it. If it is suspended, the callback will be completed some time
31 * later, and {@link #resume()} or {@link #abort(Throwable)} will be called to allow the
32 * application to resume the processing.
36 * CompletableCallback callback = new CompletableCallback()
39 * public void resume()
41 * // continue processing
45 * public void abort(Throwable failure)
50 * asyncOperation(callback);
51 * boolean completed = callback.tryComplete();
53 * // suspend processing, async operation not done yet
55 * // continue processing, async operation already done
58 public abstract class CompletableCallback implements Callback
60 private final AtomicReference<State> state = new AtomicReference<>(State.IDLE);
63 public void succeeded()
67 State current = state.get();
72 if (state.compareAndSet(current, State.SUCCEEDED))
78 if (state.compareAndSet(current, State.SUCCEEDED))
91 throw new IllegalStateException(current.toString());
98 public void failed(Throwable x)
102 State current = state.get();
108 if (state.compareAndSet(current, State.FAILED))
121 throw new IllegalStateException(current.toString());
128 * Callback method invoked when this callback is succeeded
129 * <em>after</em> a first call to {@link #tryComplete()}.
131 public abstract void resume();
134 * Callback method invoked when this callback is failed.
136 public abstract void abort(Throwable failure);
139 * Tries to complete this callback; driver code should call
140 * this method once <em>after</em> the asynchronous operation
141 * to detect whether the asynchronous operation has already
144 * @return whether the attempt to complete was successful.
146 public boolean tryComplete()
150 State current = state.get();
155 if (state.compareAndSet(current, State.COMPLETED))
166 throw new IllegalStateException(current.toString());
174 IDLE, SUCCEEDED, FAILED, COMPLETED