332 |
|
return t; |
333 |
|
} |
334 |
|
} |
335 |
< |
} |
335 |
> |
} |
336 |
|
|
337 |
|
/** |
338 |
|
* Gets rid of cancelled node s with original predecessor pred. |
359 |
|
QNode t = getValidatedTail(); |
360 |
|
if (s != t) { // If not tail, try to unsplice |
361 |
|
QNode sn = s.next; // s.next == s means s already off list |
362 |
< |
if (sn == s || pred.casNext(s, sn)) |
362 |
> |
if (sn == s || pred.casNext(s, sn)) |
363 |
|
break; |
364 |
|
} |
365 |
|
else if (oldpred == pred || // Already saved |
374 |
|
* @return current cleanMe node (or null) |
375 |
|
*/ |
376 |
|
private QNode reclean() { |
377 |
< |
/* |
377 |
> |
/* |
378 |
|
* cleanMe is, or at one time was, predecessor of cancelled |
379 |
|
* node s that was the tail so could not be unspliced. If s |
380 |
|
* is no longer the tail, try to unsplice if necessary and |
383 |
|
* points to a cancelled node that must be unspliced -- if |
384 |
|
* not, we can (must) clear cleanMe without unsplicing. |
385 |
|
* This can loop only due to contention on casNext or |
386 |
< |
* clearing cleanMe. |
386 |
> |
* clearing cleanMe. |
387 |
|
*/ |
388 |
|
QNode pred; |
389 |
|
while ((pred = cleanMe.get()) != null) { |
390 |
|
QNode t = getValidatedTail(); |
391 |
|
QNode s = pred.next; |
392 |
< |
if (s != t) { |
392 |
> |
if (s != t) { |
393 |
|
QNode sn; |
394 |
|
if (s == null || s == pred || s.get() != s || |
395 |
|
(sn = s.next) == s || pred.casNext(s, sn)) |
758 |
|
|
759 |
|
private void resetHeadAndTail() { |
760 |
|
QNode dummy = new QNode(null, false); |
761 |
< |
_unsafe.putObjectVolatile(this, headOffset, |
761 |
> |
_unsafe.putObjectVolatile(this, headOffset, |
762 |
|
new PaddedAtomicReference<QNode>(dummy)); |
763 |
< |
_unsafe.putObjectVolatile(this, tailOffset, |
763 |
> |
_unsafe.putObjectVolatile(this, tailOffset, |
764 |
|
new PaddedAtomicReference<QNode>(dummy)); |
765 |
|
_unsafe.putObjectVolatile(this, cleanMeOffset, |
766 |
|
new PaddedAtomicReference<QNode>(null)); |