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