OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libjava/] [classpath/] [external/] [jsr166/] [java/] [util/] [concurrent/] [FutureTask.java] - Blame information for rev 768

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 768 jeremybenn
/*
2
 * Written by Doug Lea with assistance from members of JCP JSR-166
3
 * Expert Group and released to the public domain, as explained at
4
 * http://creativecommons.org/licenses/publicdomain
5
 */
6
 
7
package java.util.concurrent;
8
import java.util.concurrent.locks.*;
9
 
10
/**
11
 * A cancellable asynchronous computation.  This class provides a base
12
 * implementation of {@link Future}, with methods to start and cancel
13
 * a computation, query to see if the computation is complete, and
14
 * retrieve the result of the computation.  The result can only be
15
 * retrieved when the computation has completed; the <tt>get</tt>
16
 * method will block if the computation has not yet completed.  Once
17
 * the computation has completed, the computation cannot be restarted
18
 * or cancelled.
19
 *
20
 * <p>A <tt>FutureTask</tt> can be used to wrap a {@link Callable} or
21
 * {@link java.lang.Runnable} object.  Because <tt>FutureTask</tt>
22
 * implements <tt>Runnable</tt>, a <tt>FutureTask</tt> can be
23
 * submitted to an {@link Executor} for execution.
24
 *
25
 * <p>In addition to serving as a standalone class, this class provides
26
 * <tt>protected</tt> functionality that may be useful when creating
27
 * customized task classes.
28
 *
29
 * @since 1.5
30
 * @author Doug Lea
31
 * @param <V> The result type returned by this FutureTask's <tt>get</tt> method
32
 */
33
public class FutureTask<V> implements RunnableFuture<V> {
34
    /** Synchronization control for FutureTask */
35
    private final Sync sync;
36
 
37
    /**
38
     * Creates a <tt>FutureTask</tt> that will upon running, execute the
39
     * given <tt>Callable</tt>.
40
     *
41
     * @param  callable the callable task
42
     * @throws NullPointerException if callable is null
43
     */
44
    public FutureTask(Callable<V> callable) {
45
        if (callable == null)
46
            throw new NullPointerException();
47
        sync = new Sync(callable);
48
    }
49
 
50
    /**
51
     * Creates a <tt>FutureTask</tt> that will upon running, execute the
52
     * given <tt>Runnable</tt>, and arrange that <tt>get</tt> will return the
53
     * given result on successful completion.
54
     *
55
     * @param  runnable the runnable task
56
     * @param result the result to return on successful completion. If
57
     * you don't need a particular result, consider using
58
     * constructions of the form:
59
     * <tt>Future&lt;?&gt; f = new FutureTask&lt;Object&gt;(runnable, null)</tt>
60
     * @throws NullPointerException if runnable is null
61
     */
62
    public FutureTask(Runnable runnable, V result) {
63
        sync = new Sync(Executors.callable(runnable, result));
64
    }
65
 
66
    public boolean isCancelled() {
67
        return sync.innerIsCancelled();
68
    }
69
 
70
    public boolean isDone() {
71
        return sync.innerIsDone();
72
    }
73
 
74
    public boolean cancel(boolean mayInterruptIfRunning) {
75
        return sync.innerCancel(mayInterruptIfRunning);
76
    }
77
 
78
    /**
79
     * @throws CancellationException {@inheritDoc}
80
     */
81
    public V get() throws InterruptedException, ExecutionException {
82
        return sync.innerGet();
83
    }
84
 
85
    /**
86
     * @throws CancellationException {@inheritDoc}
87
     */
88
    public V get(long timeout, TimeUnit unit)
89
        throws InterruptedException, ExecutionException, TimeoutException {
90
        return sync.innerGet(unit.toNanos(timeout));
91
    }
92
 
93
    /**
94
     * Protected method invoked when this task transitions to state
95
     * <tt>isDone</tt> (whether normally or via cancellation). The
96
     * default implementation does nothing.  Subclasses may override
97
     * this method to invoke completion callbacks or perform
98
     * bookkeeping. Note that you can query status inside the
99
     * implementation of this method to determine whether this task
100
     * has been cancelled.
101
     */
102
    protected void done() { }
103
 
104
    /**
105
     * Sets the result of this Future to the given value unless
106
     * this future has already been set or has been cancelled.
107
     * This method is invoked internally by the <tt>run</tt> method
108
     * upon successful completion of the computation.
109
     * @param v the value
110
     */
111
    protected void set(V v) {
112
        sync.innerSet(v);
113
    }
114
 
115
    /**
116
     * Causes this future to report an <tt>ExecutionException</tt>
117
     * with the given throwable as its cause, unless this Future has
118
     * already been set or has been cancelled.
119
     * This method is invoked internally by the <tt>run</tt> method
120
     * upon failure of the computation.
121
     * @param t the cause of failure
122
     */
123
    protected void setException(Throwable t) {
124
        sync.innerSetException(t);
125
    }
126
 
127
    // The following (duplicated) doc comment can be removed once
128
    //
129
    // 6270645: Javadoc comments should be inherited from most derived
130
    //          superinterface or superclass
131
    // is fixed.
132
    /**
133
     * Sets this Future to the result of its computation
134
     * unless it has been cancelled.
135
     */
136
    public void run() {
137
        sync.innerRun();
138
    }
139
 
140
    /**
141
     * Executes the computation without setting its result, and then
142
     * resets this Future to initial state, failing to do so if the
143
     * computation encounters an exception or is cancelled.  This is
144
     * designed for use with tasks that intrinsically execute more
145
     * than once.
146
     * @return true if successfully run and reset
147
     */
148
    protected boolean runAndReset() {
149
        return sync.innerRunAndReset();
150
    }
151
 
152
    /**
153
     * Synchronization control for FutureTask. Note that this must be
154
     * a non-static inner class in order to invoke the protected
155
     * <tt>done</tt> method. For clarity, all inner class support
156
     * methods are same as outer, prefixed with "inner".
157
     *
158
     * Uses AQS sync state to represent run status
159
     */
160
    private final class Sync extends AbstractQueuedSynchronizer {
161
        private static final long serialVersionUID = -7828117401763700385L;
162
 
163
        /** State value representing that task is running */
164
        private static final int RUNNING   = 1;
165
        /** State value representing that task ran */
166
        private static final int RAN       = 2;
167
        /** State value representing that task was cancelled */
168
        private static final int CANCELLED = 4;
169
 
170
        /** The underlying callable */
171
        private final Callable<V> callable;
172
        /** The result to return from get() */
173
        private V result;
174
        /** The exception to throw from get() */
175
        private Throwable exception;
176
 
177
        /**
178
         * The thread running task. When nulled after set/cancel, this
179
         * indicates that the results are accessible.  Must be
180
         * volatile, to ensure visibility upon completion.
181
         */
182
        private volatile Thread runner;
183
 
184
        Sync(Callable<V> callable) {
185
            this.callable = callable;
186
        }
187
 
188
        private boolean ranOrCancelled(int state) {
189
            return (state & (RAN | CANCELLED)) != 0;
190
        }
191
 
192
        /**
193
         * Implements AQS base acquire to succeed if ran or cancelled
194
         */
195
        protected int tryAcquireShared(int ignore) {
196
            return innerIsDone()? 1 : -1;
197
        }
198
 
199
        /**
200
         * Implements AQS base release to always signal after setting
201
         * final done status by nulling runner thread.
202
         */
203
        protected boolean tryReleaseShared(int ignore) {
204
            runner = null;
205
            return true;
206
        }
207
 
208
        boolean innerIsCancelled() {
209
            return getState() == CANCELLED;
210
        }
211
 
212
        boolean innerIsDone() {
213
            return ranOrCancelled(getState()) && runner == null;
214
        }
215
 
216
        V innerGet() throws InterruptedException, ExecutionException {
217
            acquireSharedInterruptibly(0);
218
            if (getState() == CANCELLED)
219
                throw new CancellationException();
220
            if (exception != null)
221
                throw new ExecutionException(exception);
222
            return result;
223
        }
224
 
225
        V innerGet(long nanosTimeout) throws InterruptedException, ExecutionException, TimeoutException {
226
            if (!tryAcquireSharedNanos(0, nanosTimeout))
227
                throw new TimeoutException();
228
            if (getState() == CANCELLED)
229
                throw new CancellationException();
230
            if (exception != null)
231
                throw new ExecutionException(exception);
232
            return result;
233
        }
234
 
235
        void innerSet(V v) {
236
            for (;;) {
237
                int s = getState();
238
                if (s == RAN)
239
                    return;
240
                if (s == CANCELLED) {
241
                    // aggressively release to set runner to null,
242
                    // in case we are racing with a cancel request
243
                    // that will try to interrupt runner
244
                    releaseShared(0);
245
                    return;
246
                }
247
                if (compareAndSetState(s, RAN)) {
248
                    result = v;
249
                    releaseShared(0);
250
                    done();
251
                    return;
252
                }
253
            }
254
        }
255
 
256
        void innerSetException(Throwable t) {
257
            for (;;) {
258
                int s = getState();
259
                if (s == RAN)
260
                    return;
261
                if (s == CANCELLED) {
262
                    // aggressively release to set runner to null,
263
                    // in case we are racing with a cancel request
264
                    // that will try to interrupt runner
265
                    releaseShared(0);
266
                    return;
267
                }
268
                if (compareAndSetState(s, RAN)) {
269
                    exception = t;
270
                    result = null;
271
                    releaseShared(0);
272
                    done();
273
                    return;
274
                }
275
            }
276
        }
277
 
278
        boolean innerCancel(boolean mayInterruptIfRunning) {
279
            for (;;) {
280
                int s = getState();
281
                if (ranOrCancelled(s))
282
                    return false;
283
                if (compareAndSetState(s, CANCELLED))
284
                    break;
285
            }
286
            if (mayInterruptIfRunning) {
287
                Thread r = runner;
288
                if (r != null)
289
                    r.interrupt();
290
            }
291
            releaseShared(0);
292
            done();
293
            return true;
294
        }
295
 
296
        void innerRun() {
297
            if (!compareAndSetState(0, RUNNING))
298
                return;
299
            try {
300
                runner = Thread.currentThread();
301
                if (getState() == RUNNING) // recheck after setting thread
302
                    innerSet(callable.call());
303
                else
304
                    releaseShared(0); // cancel
305
            } catch (Throwable ex) {
306
                innerSetException(ex);
307
            }
308
        }
309
 
310
        boolean innerRunAndReset() {
311
            if (!compareAndSetState(0, RUNNING))
312
                return false;
313
            try {
314
                runner = Thread.currentThread();
315
                if (getState() == RUNNING)
316
                    callable.call(); // don't set result
317
                runner = null;
318
                return compareAndSetState(RUNNING, 0);
319
            } catch (Throwable ex) {
320
                innerSetException(ex);
321
                return false;
322
            }
323
        }
324
    }
325
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.