ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/concurrent/FutureTask.java
(Generate patch)

Comparing jsr166/src/main/java/util/concurrent/FutureTask.java (file contents):
Revision 1.85 by jsr166, Sun Jun 19 03:21:58 2011 UTC vs.
Revision 1.86 by jsr166, Sun Jun 19 06:06:24 2011 UTC

# Line 234 | Line 234 | public class FutureTask<V> implements Ru
234                      set(result);
235              }
236              runner = null;
237 <            if (state >= INTERRUPTING) {
238 <                while (state == INTERRUPTING)
239 <                    Thread.yield();   // wait out pending interrupt
240 <                Thread.interrupted(); // clear interrupt from cancel(true)
241 <            }
237 >            int s = state;
238 >            if (s >= INTERRUPTING)
239 >                handlePossibleCancellationInterrupt(s);
240          }
241      }
242  
# Line 269 | Line 267 | public class FutureTask<V> implements Ru
267              int s = state;
268              if (s != NEW) {
269                  rerun = false;
270 <                if (s >= INTERRUPTING) {
271 <                    while (state == INTERRUPTING)
274 <                        Thread.yield();   // wait out pending interrupt
275 <                    Thread.interrupted(); // clear interrupt from cancel(true)
276 <                }
270 >                if (s >= INTERRUPTING)
271 >                    handlePossibleCancellationInterrupt(s);
272              }
273          }
274          return rerun;
275      }
276  
277      /**
278 +     * Ensures that any interrupt from a possible cancel(true) does
279 +     * not leak into subsequent code.
280 +     */
281 +    private void handlePossibleCancellationInterrupt(int s) {
282 +        // It is possible for our interrupter to stall before getting a
283 +        // chance to interrupt us.  Let's spin-wait patiently.
284 +        if (s == INTERRUPTING) {
285 +            while ((s = state) == INTERRUPTING)
286 +                Thread.yield(); // wait out pending interrupt
287 +        }
288 +        assert state == INTERRUPTED;
289 +        // Clear any interrupt we may have received.
290 +        Thread.interrupted();   // clear interrupt from cancel(true)
291 +    }
292 +
293 +    /**
294       * Simple linked list nodes to record waiting threads in a Treiber
295       * stack.  See other classes such as Phaser and SynchronousQueue
296       * for more detailed explanation.
# Line 295 | Line 306 | public class FutureTask<V> implements Ru
306       * nulls out callable.
307       */
308      private void finishCompletion() {
309 +        assert state > NEW;
310          for (WaitNode q; (q = waiters) != null;) {
311              if (UNSAFE.compareAndSwapObject(this, waitersOffset, q, null)) {
312                  for (;;) {

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines