335 |
|
else if (p == q) |
336 |
|
continue restartFromHead; |
337 |
|
else |
338 |
< |
p = q; |
338 |
> |
// Check for head updates after two hops. |
339 |
> |
p = (p != h && h != (h = head)) ? h : q; |
340 |
|
} |
341 |
|
} |
342 |
|
} |
370 |
|
else if (p == q) |
371 |
|
continue restartFromTail; |
372 |
|
else |
373 |
< |
p = q; |
373 |
> |
// Check for tail updates after two hops. |
374 |
> |
p = (p != t && t != (t = tail)) ? t : q; |
375 |
|
} |
376 |
|
} |
377 |
|
} |
681 |
|
return p; |
682 |
|
else |
683 |
|
continue restartFromHead; |
682 |
– |
} else if (p == q) { |
683 |
– |
continue restartFromHead; |
684 |
– |
} else { |
685 |
– |
p = q; |
684 |
|
} |
685 |
+ |
else if (p == q) |
686 |
+ |
continue restartFromHead; |
687 |
+ |
else |
688 |
+ |
// Check for head updates after two hops. |
689 |
+ |
p = (p != h && h != (h = head)) ? h : q; |
690 |
|
} |
691 |
|
} |
692 |
|
} |
710 |
|
return p; |
711 |
|
else |
712 |
|
continue restartFromTail; |
710 |
– |
} else if (p == q) { |
711 |
– |
continue restartFromTail; |
712 |
– |
} else { |
713 |
– |
p = q; |
713 |
|
} |
714 |
+ |
else if (p == q) |
715 |
+ |
continue restartFromTail; |
716 |
+ |
else |
717 |
+ |
// Check for tail updates after two hops. |
718 |
+ |
p = (p != t && t != (t = tail)) ? t : q; |
719 |
|
} |
720 |
|
} |
721 |
|
} |
1079 |
|
throw new IllegalArgumentException(); |
1080 |
|
|
1081 |
|
// Copy c into a private chain of Nodes |
1082 |
< |
Node<E> splice = null, last = null; |
1082 |
> |
Node<E> beginningOfTheEnd = null, last = null; |
1083 |
|
for (E e : c) { |
1084 |
|
checkNotNull(e); |
1085 |
|
Node<E> newNode = new Node<E>(e); |
1086 |
< |
if (splice == null) |
1087 |
< |
splice = last = newNode; |
1086 |
> |
if (beginningOfTheEnd == null) |
1087 |
> |
beginningOfTheEnd = last = newNode; |
1088 |
|
else { |
1089 |
|
last.lazySetNext(newNode); |
1090 |
|
newNode.lazySetPrev(last); |
1091 |
|
last = newNode; |
1092 |
|
} |
1093 |
|
} |
1094 |
< |
if (splice == null) |
1094 |
> |
if (beginningOfTheEnd == null) |
1095 |
|
return false; |
1096 |
|
|
1097 |
< |
// Atomically splice the chain as the tail of this collection |
1097 |
> |
// Atomically append the chain at the tail of this collection |
1098 |
|
restartFromTail: |
1099 |
|
for (;;) { |
1100 |
|
for (Node<E> t = tail, p = t;;) { |
1103 |
|
if (p.prev == p) // NEXT_TERMINATOR |
1104 |
|
continue restartFromTail; |
1105 |
|
// p is last node |
1106 |
< |
splice.lazySetPrev(p); // CAS piggyback |
1107 |
< |
if (p.casNext(null, splice)) { |
1108 |
< |
if (! casTail(t, last)) { |
1106 |
> |
beginningOfTheEnd.lazySetPrev(p); // CAS piggyback |
1107 |
> |
if (p.casNext(null, beginningOfTheEnd)) { |
1108 |
> |
// Successful CAS is the linearization point |
1109 |
> |
// for all elements to be added to this queue. |
1110 |
> |
if (!casTail(t, last)) { |
1111 |
|
// Try a little harder to update tail, |
1112 |
|
// since we may be adding many elements. |
1113 |
|
t = tail; |
1121 |
|
else if (p == q) |
1122 |
|
continue restartFromTail; |
1123 |
|
else |
1124 |
< |
p = q; |
1124 |
> |
// Check for tail updates after two hops. |
1125 |
> |
p = (p != t && t != (t = tail)) ? t : q; |
1126 |
|
} |
1127 |
|
} |
1128 |
|
} |
1327 |
|
|
1328 |
|
// Write out all elements in the proper order. |
1329 |
|
for (Node<E> p = first(); p != null; p = succ(p)) { |
1330 |
< |
Object item = p.item; |
1330 |
> |
E item = p.item; |
1331 |
|
if (item != null) |
1332 |
|
s.writeObject(item); |
1333 |
|
} |