]> WPIA git - gigi.git/blob - lib/jetty/org/eclipse/jetty/util/FuturePromise.java
Importing upstream Jetty jetty-9.2.1.v20140609
[gigi.git] / lib / jetty / org / eclipse / jetty / util / FuturePromise.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.io.IOException;
22 import java.util.concurrent.CancellationException;
23 import java.util.concurrent.CountDownLatch;
24 import java.util.concurrent.ExecutionException;
25 import java.util.concurrent.Future;
26 import java.util.concurrent.TimeUnit;
27 import java.util.concurrent.TimeoutException;
28 import java.util.concurrent.atomic.AtomicBoolean;
29
30 public class FuturePromise<C> implements Future<C>,Promise<C>
31 {
32     private static Throwable COMPLETED=new Throwable();
33     private final AtomicBoolean _done=new AtomicBoolean(false);
34     private final CountDownLatch _latch=new CountDownLatch(1);
35     private Throwable _cause;
36     private C _result;
37     
38     public FuturePromise()
39     {}
40
41     public FuturePromise(C result)
42     {
43         _cause=COMPLETED;
44         _result=result;
45         _done.set(true);
46         _latch.countDown();
47     }
48
49     public FuturePromise(C ctx, Throwable failed)
50     {
51         _result=ctx;
52         _cause=failed;
53         _done.set(true);
54         _latch.countDown();
55     }
56
57     @Override
58     public void succeeded(C result)
59     {
60         if (_done.compareAndSet(false,true))
61         {
62             _result=result;
63             _cause=COMPLETED;
64             _latch.countDown();
65         }
66     }
67
68     @Override
69     public void failed(Throwable cause)
70     {
71         if (_done.compareAndSet(false,true))
72         {
73             _cause=cause;
74             _latch.countDown();
75         }
76     }
77
78     @Override
79     public boolean cancel(boolean mayInterruptIfRunning)
80     {
81         if (_done.compareAndSet(false,true))
82         {
83             _result=null;
84             _cause=new CancellationException();
85             _latch.countDown();
86             return true;
87         }
88         return false;
89     }
90
91     @Override
92     public boolean isCancelled()
93     {
94         if (_done.get())
95         {
96             try
97             {
98                 _latch.await();
99             }
100             catch (InterruptedException e)
101             {
102                 throw new RuntimeException(e);
103             }
104             return _cause instanceof CancellationException;
105         }
106         return false;
107     }
108
109     @Override
110     public boolean isDone()
111     {
112         return _done.get() && _latch.getCount()==0;
113     }
114
115     @Override
116     public C get() throws InterruptedException, ExecutionException
117     {
118         _latch.await();
119         if (_cause==COMPLETED)
120             return _result;
121         if (_cause instanceof CancellationException)
122             throw (CancellationException) new CancellationException().initCause(_cause);
123         throw new ExecutionException(_cause);
124     }
125
126     @Override
127     public C get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException
128     {
129         if (!_latch.await(timeout,unit))
130             throw new TimeoutException();
131
132         if (_cause==COMPLETED)
133             return _result;
134         if (_cause instanceof TimeoutException)
135             throw (TimeoutException)_cause;
136         if (_cause instanceof CancellationException)
137             throw (CancellationException) new CancellationException().initCause(_cause);
138         throw new ExecutionException(_cause);
139     }
140
141     public static void rethrow(ExecutionException e) throws IOException
142     {
143         Throwable cause=e.getCause();
144         if (cause instanceof IOException)
145             throw (IOException)cause;
146         if (cause instanceof Error)
147             throw (Error)cause;
148         if (cause instanceof RuntimeException)
149             throw (RuntimeException)cause;
150         throw new RuntimeException(cause);
151     }
152     
153     @Override
154     public String toString()
155     {
156         return String.format("FutureCallback@%x{%b,%b,%s}",hashCode(),_done,_cause==COMPLETED,_result);
157     }
158     
159 }