]> WPIA git - gigi.git/blob - lib/jetty/org/eclipse/jetty/util/CompletableCallback.java
Importing upstream Jetty jetty-9.2.1.v20140609
[gigi.git] / lib / jetty / org / eclipse / jetty / util / CompletableCallback.java
1 //
2 //  ========================================================================
3 //  Copyright (c) 1995-2014 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.
8 //
9 //      The Eclipse Public License is available at
10 //      http://www.eclipse.org/legal/epl-v10.html
11 //
12 //      The Apache License v2.0 is available at
13 //      http://www.opensource.org/licenses/apache2.0.php
14 //
15 //  You may elect to redistribute this code under either of these licenses.
16 //  ========================================================================
17 //
18
19 package org.eclipse.jetty.util;
20
21 import java.util.concurrent.atomic.AtomicBoolean;
22
23 /**
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.
28  * <p />
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.
33  * <p />
34  * Typical usage:
35  * <pre>
36  * CompletableCallback callback = new CompletableCallback()
37  * {
38  *     &#64;Override
39  *     public void resume()
40  *     {
41  *         // continue processing
42  *     }
43  *
44  *     &#64;Override
45  *     public void abort(Throwable failure)
46  *     {
47  *         // abort processing
48  *     }
49  * }
50  * asyncOperation(callback);
51  * boolean completed = callback.tryComplete();
52  * if (completed)
53  *     // suspend processing, async operation not done yet
54  * else
55  *     // continue processing, async operation already done
56  * </pre>
57  */
58 public abstract class CompletableCallback implements Callback
59 {
60     private final AtomicBoolean completed = new AtomicBoolean();
61
62     @Override
63     public void succeeded()
64     {
65         if (!tryComplete())
66             resume();
67     }
68
69     @Override
70     public void failed(Throwable x)
71     {
72         if (!tryComplete())
73             abort(x);
74     }
75
76     /**
77      * Callback method invoked when this callback is succeeded
78      * <em>after</em> a first call to {@link #tryComplete()}.
79      */
80     public abstract void resume();
81
82     /**
83      * Callback method invoked when this callback is failed
84      * <em>after</em> a first call to {@link #tryComplete()}.
85      */
86     public abstract void abort(Throwable failure);
87
88     /**
89      * Tries to complete this callback; driver code should call
90      * this method once <em>after</em> the asynchronous operation
91      * to detect whether the asynchronous operation has already
92      * completed or not.
93      *
94      * @return whether the attempt to complete was successful.
95      */
96     public boolean tryComplete()
97     {
98         return completed.compareAndSet(false, true);
99     }
100 }