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.75 by jsr166, Sat Jun 18 01:38:51 2011 UTC vs.
Revision 1.76 by dl, Sat Jun 18 10:39:05 2011 UTC

# Line 298 | Line 298 | public class FutureTask<V> implements Ru
298       */
299      static final class WaitNode {
300          volatile Thread thread;
301 <        WaitNode next;
301 >        volatile WaitNode next;
302 >        WaitNode() { thread = Thread.currentThread(); }
303      }
304  
305      /**
# Line 353 | Line 354 | public class FutureTask<V> implements Ru
354              else if (!queued)
355                  queued = UNSAFE.compareAndSwapObject(this, waitersOffset,
356                                                       q.next = waiters, q);
356            else if (q.thread == null)
357                q.thread = Thread.currentThread();
357              else if (timed) {
358                  long now = System.nanoTime();
359                  if ((nanos -= (now - last)) <= 0L) {
# Line 373 | Line 372 | public class FutureTask<V> implements Ru
372       * Tries to unlink a timed-out or interrupted wait node to avoid
373       * accumulating garbage.  Internal nodes are simply unspliced
374       * without CAS since it is harmless if they are traversed anyway
375 <     * by releasers or concurrent calls to removeWaiter.
375 >     * by releasers. To avoid effects of unsplicing from already
376 >     * removed nodes, the list is retraversed until no cancelled nodes
377 >     * are found.  This is slow when there are a lot of nodes, but we
378 >     * don't expect lists to be long enough to outweigh
379 >     * higher-overhead schemes.
380       */
381      private void removeWaiter(WaitNode node) {
382          if (node != null) {
383              node.thread = null;
384              for (WaitNode pred = null, q = waiters; q != null;) {
385                  WaitNode next = q.next;
386 <                if (q != node) {
386 >                if (q.thread != null) {
387                      pred = q;
388                      q = next;
389                  }
390 <                else if (pred != null) {
391 <                    pred.next = next;
392 <                    break;
393 <                }
394 <                else if (UNSAFE.compareAndSwapObject(this, waitersOffset,
395 <                                                     q, next))
396 <                    break;
394 <                else { // restart on CAS failure
395 <                    pred = null;
390 >                else {
391 >                    if (pred != null)
392 >                        pred.next = next;
393 >                    else
394 >                        UNSAFE.compareAndSwapObject(this, waitersOffset,
395 >                                                    q, next);
396 >                    pred = null; // restart until clean sweep
397                      q = waiters;
398                  }
399              }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines