jdk/src/share/classes/java/util/concurrent/FutureTask.java
author dl
Mon, 30 Jan 2012 11:44:45 +0000
changeset 11689 ffbfda5c3886
parent 9242 ef138d47df58
child 18790 d25399d849bc
permissions -rw-r--r--
7132378: Race in FutureTask if used with explicit set ( not Runnable ) Reviewed-by: chegar, dholmes
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     1
/*
90ce3da70b43 Initial load
duke
parents:
diff changeset
     2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
90ce3da70b43 Initial load
duke
parents:
diff changeset
     3
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
     4
 * This code is free software; you can redistribute it and/or modify it
90ce3da70b43 Initial load
duke
parents:
diff changeset
     5
 * under the terms of the GNU General Public License version 2 only, as
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
     6
 * published by the Free Software Foundation.  Oracle designates this
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     7
 * particular file as subject to the "Classpath" exception as provided
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
     8
 * by Oracle in the LICENSE file that accompanied this code.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     9
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    10
 * This code is distributed in the hope that it will be useful, but WITHOUT
90ce3da70b43 Initial load
duke
parents:
diff changeset
    11
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    12
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
90ce3da70b43 Initial load
duke
parents:
diff changeset
    13
 * version 2 for more details (a copy is included in the LICENSE file that
90ce3da70b43 Initial load
duke
parents:
diff changeset
    14
 * accompanied this code).
90ce3da70b43 Initial load
duke
parents:
diff changeset
    15
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    16
 * You should have received a copy of the GNU General Public License version
90ce3da70b43 Initial load
duke
parents:
diff changeset
    17
 * 2 along with this work; if not, write to the Free Software Foundation,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    18
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    19
 *
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
    20
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
    21
 * or visit www.oracle.com if you need additional information or have any
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
    22
 * questions.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    23
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    24
90ce3da70b43 Initial load
duke
parents:
diff changeset
    25
/*
90ce3da70b43 Initial load
duke
parents:
diff changeset
    26
 * This file is available under and governed by the GNU General Public
90ce3da70b43 Initial load
duke
parents:
diff changeset
    27
 * License version 2 only, as published by the Free Software Foundation.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    28
 * However, the following notice accompanied the original version of this
90ce3da70b43 Initial load
duke
parents:
diff changeset
    29
 * file:
90ce3da70b43 Initial load
duke
parents:
diff changeset
    30
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    31
 * Written by Doug Lea with assistance from members of JCP JSR-166
90ce3da70b43 Initial load
duke
parents:
diff changeset
    32
 * Expert Group and released to the public domain, as explained at
9242
ef138d47df58 7034657: Update Creative Commons license URL in legal notices
dl
parents: 7518
diff changeset
    33
 * http://creativecommons.org/publicdomain/zero/1.0/
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    34
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    35
90ce3da70b43 Initial load
duke
parents:
diff changeset
    36
package java.util.concurrent;
11689
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
    37
import java.util.concurrent.locks.LockSupport;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    38
90ce3da70b43 Initial load
duke
parents:
diff changeset
    39
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    40
 * A cancellable asynchronous computation.  This class provides a base
90ce3da70b43 Initial load
duke
parents:
diff changeset
    41
 * implementation of {@link Future}, with methods to start and cancel
90ce3da70b43 Initial load
duke
parents:
diff changeset
    42
 * a computation, query to see if the computation is complete, and
90ce3da70b43 Initial load
duke
parents:
diff changeset
    43
 * retrieve the result of the computation.  The result can only be
11689
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
    44
 * retrieved when the computation has completed; the {@code get}
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
    45
 * methods will block if the computation has not yet completed.  Once
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    46
 * the computation has completed, the computation cannot be restarted
11689
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
    47
 * or cancelled (unless the computation is invoked using
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
    48
 * {@link #runAndReset}).
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    49
 *
11689
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
    50
 * <p>A {@code FutureTask} can be used to wrap a {@link Callable} or
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
    51
 * {@link Runnable} object.  Because {@code FutureTask} implements
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
    52
 * {@code Runnable}, a {@code FutureTask} can be submitted to an
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
    53
 * {@link Executor} for execution.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    54
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    55
 * <p>In addition to serving as a standalone class, this class provides
11689
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
    56
 * {@code protected} functionality that may be useful when creating
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    57
 * customized task classes.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    58
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    59
 * @since 1.5
90ce3da70b43 Initial load
duke
parents:
diff changeset
    60
 * @author Doug Lea
11689
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
    61
 * @param <V> The result type returned by this FutureTask's {@code get} methods
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    62
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    63
public class FutureTask<V> implements RunnableFuture<V> {
11689
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
    64
    /*
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
    65
     * Revision notes: This differs from previous versions of this
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
    66
     * class that relied on AbstractQueuedSynchronizer, mainly to
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
    67
     * avoid surprising users about retaining interrupt status during
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
    68
     * cancellation races. Sync control in the current design relies
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
    69
     * on a "state" field updated via CAS to track completion, along
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
    70
     * with a simple Treiber stack to hold waiting threads.
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
    71
     *
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
    72
     * Style note: As usual, we bypass overhead of using
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
    73
     * AtomicXFieldUpdaters and instead directly use Unsafe intrinsics.
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
    74
     */
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    75
90ce3da70b43 Initial load
duke
parents:
diff changeset
    76
    /**
11689
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
    77
     * The run state of this task, initially NEW.  The run state
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
    78
     * transitions to a terminal state only in methods set,
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
    79
     * setException, and cancel.  During completion, state may take on
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
    80
     * transient values of COMPLETING (while outcome is being set) or
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
    81
     * INTERRUPTING (only while interrupting the runner to satisfy a
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
    82
     * cancel(true)). Transitions from these intermediate to final
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
    83
     * states use cheaper ordered/lazy writes because values are unique
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
    84
     * and cannot be further modified.
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
    85
     *
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
    86
     * Possible state transitions:
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
    87
     * NEW -> COMPLETING -> NORMAL
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
    88
     * NEW -> COMPLETING -> EXCEPTIONAL
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
    89
     * NEW -> CANCELLED
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
    90
     * NEW -> INTERRUPTING -> INTERRUPTED
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
    91
     */
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
    92
    private volatile int state;
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
    93
    private static final int NEW          = 0;
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
    94
    private static final int COMPLETING   = 1;
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
    95
    private static final int NORMAL       = 2;
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
    96
    private static final int EXCEPTIONAL  = 3;
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
    97
    private static final int CANCELLED    = 4;
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
    98
    private static final int INTERRUPTING = 5;
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
    99
    private static final int INTERRUPTED  = 6;
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   100
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   101
    /** The underlying callable; nulled out after running */
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   102
    private Callable<V> callable;
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   103
    /** The result to return or exception to throw from get() */
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   104
    private Object outcome; // non-volatile, protected by state reads/writes
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   105
    /** The thread running the callable; CASed during run() */
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   106
    private volatile Thread runner;
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   107
    /** Treiber stack of waiting threads */
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   108
    private volatile WaitNode waiters;
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   109
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   110
    /**
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   111
     * Returns result or throws exception for completed task.
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   112
     *
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   113
     * @param s completed state value
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   114
     */
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   115
    @SuppressWarnings("unchecked")
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   116
    private V report(int s) throws ExecutionException {
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   117
        Object x = outcome;
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   118
        if (s == NORMAL)
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   119
            return (V)x;
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   120
        if (s >= CANCELLED)
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   121
            throw new CancellationException();
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   122
        throw new ExecutionException((Throwable)x);
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   123
    }
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   124
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   125
    /**
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   126
     * Creates a {@code FutureTask} that will, upon running, execute the
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   127
     * given {@code Callable}.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   128
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   129
     * @param  callable the callable task
11689
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   130
     * @throws NullPointerException if the callable is null
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   131
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   132
    public FutureTask(Callable<V> callable) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   133
        if (callable == null)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   134
            throw new NullPointerException();
11689
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   135
        this.callable = callable;
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   136
        this.state = NEW;       // ensure visibility of callable
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   137
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   138
90ce3da70b43 Initial load
duke
parents:
diff changeset
   139
    /**
11689
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   140
     * Creates a {@code FutureTask} that will, upon running, execute the
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   141
     * given {@code Runnable}, and arrange that {@code get} will return the
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   142
     * given result on successful completion.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   143
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   144
     * @param runnable the runnable task
90ce3da70b43 Initial load
duke
parents:
diff changeset
   145
     * @param result the result to return on successful completion. If
90ce3da70b43 Initial load
duke
parents:
diff changeset
   146
     * you don't need a particular result, consider using
90ce3da70b43 Initial load
duke
parents:
diff changeset
   147
     * constructions of the form:
7518
0282db800fe1 7003745: Code style cleanups (sync from Dougs CVS)
dl
parents: 5506
diff changeset
   148
     * {@code Future<?> f = new FutureTask<Void>(runnable, null)}
11689
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   149
     * @throws NullPointerException if the runnable is null
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   150
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   151
    public FutureTask(Runnable runnable, V result) {
11689
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   152
        this.callable = Executors.callable(runnable, result);
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   153
        this.state = NEW;       // ensure visibility of callable
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   154
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   155
90ce3da70b43 Initial load
duke
parents:
diff changeset
   156
    public boolean isCancelled() {
11689
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   157
        return state >= CANCELLED;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   158
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   159
90ce3da70b43 Initial load
duke
parents:
diff changeset
   160
    public boolean isDone() {
11689
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   161
        return state != NEW;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   162
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   163
90ce3da70b43 Initial load
duke
parents:
diff changeset
   164
    public boolean cancel(boolean mayInterruptIfRunning) {
11689
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   165
        if (state != NEW)
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   166
            return false;
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   167
        if (mayInterruptIfRunning) {
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   168
            if (!UNSAFE.compareAndSwapInt(this, stateOffset, NEW, INTERRUPTING))
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   169
                return false;
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   170
            Thread t = runner;
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   171
            if (t != null)
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   172
                t.interrupt();
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   173
            UNSAFE.putOrderedInt(this, stateOffset, INTERRUPTED); // final state
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   174
        }
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   175
        else if (!UNSAFE.compareAndSwapInt(this, stateOffset, NEW, CANCELLED))
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   176
            return false;
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   177
        finishCompletion();
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   178
        return true;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   179
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   180
90ce3da70b43 Initial load
duke
parents:
diff changeset
   181
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   182
     * @throws CancellationException {@inheritDoc}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   183
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   184
    public V get() throws InterruptedException, ExecutionException {
11689
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   185
        int s = state;
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   186
        if (s <= COMPLETING)
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   187
            s = awaitDone(false, 0L);
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   188
        return report(s);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   189
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   190
90ce3da70b43 Initial load
duke
parents:
diff changeset
   191
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   192
     * @throws CancellationException {@inheritDoc}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   193
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   194
    public V get(long timeout, TimeUnit unit)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   195
        throws InterruptedException, ExecutionException, TimeoutException {
11689
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   196
        if (unit == null)
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   197
            throw new NullPointerException();
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   198
        int s = state;
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   199
        if (s <= COMPLETING &&
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   200
            (s = awaitDone(true, unit.toNanos(timeout))) <= COMPLETING)
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   201
            throw new TimeoutException();
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   202
        return report(s);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   203
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   204
90ce3da70b43 Initial load
duke
parents:
diff changeset
   205
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   206
     * Protected method invoked when this task transitions to state
11689
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   207
     * {@code isDone} (whether normally or via cancellation). The
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   208
     * default implementation does nothing.  Subclasses may override
90ce3da70b43 Initial load
duke
parents:
diff changeset
   209
     * this method to invoke completion callbacks or perform
90ce3da70b43 Initial load
duke
parents:
diff changeset
   210
     * bookkeeping. Note that you can query status inside the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   211
     * implementation of this method to determine whether this task
90ce3da70b43 Initial load
duke
parents:
diff changeset
   212
     * has been cancelled.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   213
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   214
    protected void done() { }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   215
90ce3da70b43 Initial load
duke
parents:
diff changeset
   216
    /**
11689
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   217
     * Sets the result of this future to the given value unless
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   218
     * this future has already been set or has been cancelled.
11689
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   219
     *
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   220
     * <p>This method is invoked internally by the {@link #run} method
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   221
     * upon successful completion of the computation.
11689
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   222
     *
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   223
     * @param v the value
90ce3da70b43 Initial load
duke
parents:
diff changeset
   224
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   225
    protected void set(V v) {
11689
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   226
        if (UNSAFE.compareAndSwapInt(this, stateOffset, NEW, COMPLETING)) {
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   227
            outcome = v;
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   228
            UNSAFE.putOrderedInt(this, stateOffset, NORMAL); // final state
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   229
            finishCompletion();
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   230
        }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   231
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   232
90ce3da70b43 Initial load
duke
parents:
diff changeset
   233
    /**
11689
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   234
     * Causes this future to report an {@link ExecutionException}
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   235
     * with the given throwable as its cause, unless this future has
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   236
     * already been set or has been cancelled.
11689
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   237
     *
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   238
     * <p>This method is invoked internally by the {@link #run} method
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   239
     * upon failure of the computation.
11689
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   240
     *
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   241
     * @param t the cause of failure
90ce3da70b43 Initial load
duke
parents:
diff changeset
   242
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   243
    protected void setException(Throwable t) {
11689
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   244
        if (UNSAFE.compareAndSwapInt(this, stateOffset, NEW, COMPLETING)) {
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   245
            outcome = t;
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   246
            UNSAFE.putOrderedInt(this, stateOffset, EXCEPTIONAL); // final state
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   247
            finishCompletion();
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   248
        }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   249
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   250
90ce3da70b43 Initial load
duke
parents:
diff changeset
   251
    public void run() {
11689
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   252
        if (state != NEW ||
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   253
            !UNSAFE.compareAndSwapObject(this, runnerOffset,
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   254
                                         null, Thread.currentThread()))
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   255
            return;
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   256
        try {
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   257
            Callable<V> c = callable;
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   258
            if (c != null && state == NEW) {
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   259
                V result;
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   260
                boolean ran;
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   261
                try {
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   262
                    result = c.call();
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   263
                    ran = true;
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   264
                } catch (Throwable ex) {
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   265
                    result = null;
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   266
                    ran = false;
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   267
                    setException(ex);
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   268
                }
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   269
                if (ran)
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   270
                    set(result);
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   271
            }
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   272
        } finally {
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   273
            // runner must be non-null until state is settled to
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   274
            // prevent concurrent calls to run()
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   275
            runner = null;
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   276
            // state must be re-read after nulling runner to prevent
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   277
            // leaked interrupts
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   278
            int s = state;
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   279
            if (s >= INTERRUPTING)
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   280
                handlePossibleCancellationInterrupt(s);
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   281
        }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   282
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   283
90ce3da70b43 Initial load
duke
parents:
diff changeset
   284
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   285
     * Executes the computation without setting its result, and then
11689
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   286
     * resets this future to initial state, failing to do so if the
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   287
     * computation encounters an exception or is cancelled.  This is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   288
     * designed for use with tasks that intrinsically execute more
90ce3da70b43 Initial load
duke
parents:
diff changeset
   289
     * than once.
11689
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   290
     *
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   291
     * @return true if successfully run and reset
90ce3da70b43 Initial load
duke
parents:
diff changeset
   292
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   293
    protected boolean runAndReset() {
11689
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   294
        if (state != NEW ||
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   295
            !UNSAFE.compareAndSwapObject(this, runnerOffset,
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   296
                                         null, Thread.currentThread()))
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   297
            return false;
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   298
        boolean ran = false;
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   299
        int s = state;
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   300
        try {
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   301
            Callable<V> c = callable;
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   302
            if (c != null && s == NEW) {
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   303
                try {
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   304
                    c.call(); // don't set result
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   305
                    ran = true;
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   306
                } catch (Throwable ex) {
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   307
                    setException(ex);
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   308
                }
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   309
            }
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   310
        } finally {
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   311
            // runner must be non-null until state is settled to
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   312
            // prevent concurrent calls to run()
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   313
            runner = null;
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   314
            // state must be re-read after nulling runner to prevent
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   315
            // leaked interrupts
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   316
            s = state;
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   317
            if (s >= INTERRUPTING)
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   318
                handlePossibleCancellationInterrupt(s);
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   319
        }
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   320
        return ran && s == NEW;
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   321
    }
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   322
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   323
    /**
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   324
     * Ensures that any interrupt from a possible cancel(true) is only
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   325
     * delivered to a task while in run or runAndReset.
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   326
     */
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   327
    private void handlePossibleCancellationInterrupt(int s) {
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   328
        // It is possible for our interrupter to stall before getting a
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   329
        // chance to interrupt us.  Let's spin-wait patiently.
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   330
        if (s == INTERRUPTING)
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   331
            while (state == INTERRUPTING)
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   332
                Thread.yield(); // wait out pending interrupt
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   333
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   334
        // assert state == INTERRUPTED;
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   335
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   336
        // We want to clear any interrupt we may have received from
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   337
        // cancel(true).  However, it is permissible to use interrupts
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   338
        // as an independent mechanism for a task to communicate with
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   339
        // its caller, and there is no way to clear only the
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   340
        // cancellation interrupt.
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   341
        //
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   342
        // Thread.interrupted();
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   343
    }
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   344
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   345
    /**
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   346
     * Simple linked list nodes to record waiting threads in a Treiber
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   347
     * stack.  See other classes such as Phaser and SynchronousQueue
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   348
     * for more detailed explanation.
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   349
     */
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   350
    static final class WaitNode {
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   351
        volatile Thread thread;
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   352
        volatile WaitNode next;
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   353
        WaitNode() { thread = Thread.currentThread(); }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   354
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   355
90ce3da70b43 Initial load
duke
parents:
diff changeset
   356
    /**
11689
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   357
     * Removes and signals all waiting threads, invokes done(), and
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   358
     * nulls out callable.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   359
     */
11689
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   360
    private void finishCompletion() {
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   361
        // assert state > COMPLETING;
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   362
        for (WaitNode q; (q = waiters) != null;) {
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   363
            if (UNSAFE.compareAndSwapObject(this, waitersOffset, q, null)) {
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   364
                for (;;) {
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   365
                    Thread t = q.thread;
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   366
                    if (t != null) {
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   367
                        q.thread = null;
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   368
                        LockSupport.unpark(t);
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   369
                    }
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   370
                    WaitNode next = q.next;
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   371
                    if (next == null)
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   372
                        break;
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   373
                    q.next = null; // unlink to help gc
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   374
                    q = next;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   375
                }
11689
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   376
                break;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   377
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   378
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   379
11689
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   380
        done();
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   381
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   382
        callable = null;        // to reduce footprint
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   383
    }
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   384
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   385
    /**
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   386
     * Awaits completion or aborts on interrupt or timeout.
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   387
     *
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   388
     * @param timed true if use timed waits
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   389
     * @param nanos time to wait, if timed
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   390
     * @return state upon completion
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   391
     */
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   392
    private int awaitDone(boolean timed, long nanos)
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   393
        throws InterruptedException {
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   394
        final long deadline = timed ? System.nanoTime() + nanos : 0L;
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   395
        WaitNode q = null;
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   396
        boolean queued = false;
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   397
        for (;;) {
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   398
            if (Thread.interrupted()) {
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   399
                removeWaiter(q);
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   400
                throw new InterruptedException();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   401
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   402
11689
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   403
            int s = state;
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   404
            if (s > COMPLETING) {
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   405
                if (q != null)
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   406
                    q.thread = null;
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   407
                return s;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   408
            }
11689
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   409
            else if (s == COMPLETING) // cannot time out yet
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   410
                Thread.yield();
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   411
            else if (q == null)
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   412
                q = new WaitNode();
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   413
            else if (!queued)
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   414
                queued = UNSAFE.compareAndSwapObject(this, waitersOffset,
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   415
                                                     q.next = waiters, q);
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   416
            else if (timed) {
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   417
                nanos = deadline - System.nanoTime();
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   418
                if (nanos <= 0L) {
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   419
                    removeWaiter(q);
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   420
                    return state;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   421
                }
11689
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   422
                LockSupport.parkNanos(this, nanos);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   423
            }
11689
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   424
            else
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   425
                LockSupport.park(this);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   426
        }
11689
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   427
    }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   428
11689
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   429
    /**
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   430
     * Tries to unlink a timed-out or interrupted wait node to avoid
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   431
     * accumulating garbage.  Internal nodes are simply unspliced
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   432
     * without CAS since it is harmless if they are traversed anyway
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   433
     * by releasers.  To avoid effects of unsplicing from already
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   434
     * removed nodes, the list is retraversed in case of an apparent
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   435
     * race.  This is slow when there are a lot of nodes, but we don't
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   436
     * expect lists to be long enough to outweigh higher-overhead
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   437
     * schemes.
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   438
     */
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   439
    private void removeWaiter(WaitNode node) {
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   440
        if (node != null) {
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   441
            node.thread = null;
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   442
            retry:
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   443
            for (;;) {          // restart on removeWaiter race
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   444
                for (WaitNode pred = null, q = waiters, s; q != null; q = s) {
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   445
                    s = q.next;
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   446
                    if (q.thread != null)
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   447
                        pred = q;
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   448
                    else if (pred != null) {
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   449
                        pred.next = s;
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   450
                        if (pred.thread == null) // check for race
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   451
                            continue retry;
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   452
                    }
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   453
                    else if (!UNSAFE.compareAndSwapObject(this, waitersOffset,
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   454
                                                          q, s))
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   455
                        continue retry;
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   456
                }
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   457
                break;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   458
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   459
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   460
    }
11689
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   461
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   462
    // Unsafe mechanics
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   463
    private static final sun.misc.Unsafe UNSAFE;
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   464
    private static final long stateOffset;
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   465
    private static final long runnerOffset;
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   466
    private static final long waitersOffset;
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   467
    static {
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   468
        try {
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   469
            UNSAFE = sun.misc.Unsafe.getUnsafe();
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   470
            Class<?> k = FutureTask.class;
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   471
            stateOffset = UNSAFE.objectFieldOffset
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   472
                (k.getDeclaredField("state"));
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   473
            runnerOffset = UNSAFE.objectFieldOffset
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   474
                (k.getDeclaredField("runner"));
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   475
            waitersOffset = UNSAFE.objectFieldOffset
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   476
                (k.getDeclaredField("waiters"));
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   477
        } catch (Exception e) {
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   478
            throw new Error(e);
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   479
        }
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   480
    }
ffbfda5c3886 7132378: Race in FutureTask if used with explicit set ( not Runnable )
dl
parents: 9242
diff changeset
   481
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   482
}