502 |
|
if (isData == haveData) // can't match |
503 |
|
break; |
504 |
|
if (p.casItem(item, e)) { // match |
505 |
< |
Thread w = p.waiter; |
506 |
< |
while (p != h) { // update head |
507 |
< |
Node n = p.next; // by 2 unless singleton |
508 |
< |
if (n != null) |
509 |
< |
p = n; |
510 |
< |
if (head == h && casHead(h, p)) { |
505 |
> |
for (Node q = p; q != h;) { |
506 |
> |
Node n = q.next; // update head by 2 |
507 |
> |
if (n != null) // unless singleton |
508 |
> |
q = n; |
509 |
> |
if (head == h && casHead(h, q)) { |
510 |
|
h.forgetNext(); |
511 |
|
break; |
512 |
|
} // advance and retry |
513 |
|
if ((h = head) == null || |
514 |
< |
(p = h.next) == null || !p.isMatched()) |
514 |
> |
(q = h.next) == null || !q.isMatched()) |
515 |
|
break; // unless slack < 2 |
516 |
|
} |
517 |
< |
LockSupport.unpark(w); |
517 |
> |
LockSupport.unpark(p.waiter); |
518 |
|
return item; |
519 |
|
} |
520 |
|
} |
612 |
|
Thread.yield(); // occasionally yield |
613 |
|
} |
614 |
|
else if (s.waiter == null) { |
615 |
< |
s.waiter = w; // request unpark |
615 |
> |
s.waiter = w; // request unpark then recheck |
616 |
|
} |
617 |
|
else if (how == TIMEOUT) { |
618 |
|
long now = System.nanoTime(); |
622 |
|
} |
623 |
|
else { |
624 |
|
LockSupport.park(this); |
625 |
+ |
s.waiter = null; |
626 |
|
spins = -1; // spin if front upon wakeup |
627 |
|
} |
628 |
|
} |
1192 |
|
} |
1193 |
|
} |
1194 |
|
|
1195 |
– |
|
1195 |
|
// Unsafe mechanics |
1196 |
|
|
1197 |
|
private static final sun.misc.Unsafe UNSAFE = getUnsafe(); |
1214 |
|
} |
1215 |
|
} |
1216 |
|
|
1217 |
+ |
/** |
1218 |
+ |
* Returns a sun.misc.Unsafe. Suitable for use in a 3rd party package. |
1219 |
+ |
* Replace with a simple call to Unsafe.getUnsafe when integrating |
1220 |
+ |
* into a jdk. |
1221 |
+ |
* |
1222 |
+ |
* @return a sun.misc.Unsafe |
1223 |
+ |
*/ |
1224 |
|
private static sun.misc.Unsafe getUnsafe() { |
1225 |
|
try { |
1226 |
|
return sun.misc.Unsafe.getUnsafe(); |