544 |
|
return SWEEPVOTES.compareAndSet(this, cmp, val); |
545 |
|
} |
546 |
|
|
547 |
+ |
/** |
548 |
+ |
* Tries to CAS pred.next (or head, if pred is null) from c to p. |
549 |
+ |
*/ |
550 |
+ |
private boolean tryCasSuccessor(Node pred, Node c, Node p) { |
551 |
+ |
// assert c != p; |
552 |
+ |
if (pred != null) |
553 |
+ |
return pred.casNext(c, p); |
554 |
+ |
if (casHead(c, p)) { |
555 |
+ |
c.forgetNext(); |
556 |
+ |
return true; |
557 |
+ |
} |
558 |
+ |
return false; |
559 |
+ |
} |
560 |
+ |
|
561 |
|
/* |
562 |
|
* Possible values for "how" argument in xfer method. |
563 |
|
*/ |
1440 |
|
if (o == null) |
1441 |
|
return false; |
1442 |
|
restartFromHead: for (;;) { |
1443 |
< |
for (Node pred = null, p = head; p != null; ) { |
1444 |
< |
Object item = p.item; |
1445 |
< |
if (p.isData) { |
1446 |
< |
if (item != null |
1447 |
< |
&& o.equals(item) |
1448 |
< |
&& p.tryMatchData()) { |
1435 |
< |
unsplice(pred, p); |
1443 |
> |
for (Node p = head, c = p, pred = null, q; p != null; ) { |
1444 |
> |
final Object item; boolean pAlive; |
1445 |
> |
if (pAlive = (((item = p.item) != null) && p.isData)) { |
1446 |
> |
if (o.equals(item) && p.tryMatchData()) { |
1447 |
> |
if ((q = p.next) == null) q = p; |
1448 |
> |
if (c != q) tryCasSuccessor(pred, c, q); |
1449 |
|
return true; |
1450 |
|
} |
1451 |
|
} |
1452 |
< |
else if (item == null) |
1452 |
> |
else if (!p.isData && item == null) |
1453 |
|
break; |
1454 |
< |
if ((pred = p) == (p = p.next)) |
1454 |
> |
if (c != p && tryCasSuccessor(pred, c, p)) |
1455 |
> |
c = p; |
1456 |
> |
q = p.next; |
1457 |
> |
if (pAlive || c != p) { |
1458 |
> |
pred = p; |
1459 |
> |
p = c = q; |
1460 |
> |
} |
1461 |
> |
else if (p == (p = q)) |
1462 |
|
continue restartFromHead; |
1463 |
|
} |
1464 |
|
return false; |
1474 |
|
* @return {@code true} if this queue contains the specified element |
1475 |
|
*/ |
1476 |
|
public boolean contains(Object o) { |
1477 |
< |
if (o != null) { |
1478 |
< |
for (Node p = head; p != null; ) { |
1479 |
< |
Object item = p.item; |
1480 |
< |
if (p.isData) { |
1481 |
< |
if (item != null && o.equals(item)) |
1477 |
> |
if (o == null) |
1478 |
> |
return false; |
1479 |
> |
restartFromHead: for (;;) { |
1480 |
> |
for (Node p = head, c = p, pred = null, q; p != null; ) { |
1481 |
> |
final Object item; final boolean pAlive; |
1482 |
> |
if (pAlive = (((item = p.item) != null) && p.isData)) { |
1483 |
> |
if (o.equals(item)) |
1484 |
|
return true; |
1485 |
|
} |
1486 |
< |
else if (item == null) |
1486 |
> |
else if (!p.isData && item == null) |
1487 |
|
break; |
1488 |
< |
if (p == (p = p.next)) |
1489 |
< |
p = head; |
1488 |
> |
if (c != p && tryCasSuccessor(pred, c, p)) |
1489 |
> |
c = p; |
1490 |
> |
q = p.next; |
1491 |
> |
if (pAlive || c != p) { |
1492 |
> |
pred = p; |
1493 |
> |
p = c = q; |
1494 |
> |
} |
1495 |
> |
else if (p == (p = q)) |
1496 |
> |
continue restartFromHead; |
1497 |
|
} |
1498 |
+ |
return false; |
1499 |
|
} |
1470 |
– |
return false; |
1500 |
|
} |
1501 |
|
|
1502 |
|
/** |
1604 |
|
*/ |
1605 |
|
@SuppressWarnings("unchecked") |
1606 |
|
void forEachFrom(Consumer<? super E> action, Node p) { |
1607 |
< |
while (p != null) { |
1608 |
< |
final Object item = p.item; |
1609 |
< |
if (p.isData) { |
1610 |
< |
if (item != null) |
1611 |
< |
action.accept((E) item); |
1583 |
< |
} |
1584 |
< |
else if (item == null) |
1607 |
> |
for (Node c = p, pred = null, q; p != null; ) { |
1608 |
> |
final Object item; final boolean pAlive; |
1609 |
> |
if (pAlive = (((item = p.item) != null) && p.isData)) |
1610 |
> |
action.accept((E) item); |
1611 |
> |
else if (!p.isData && item == null) |
1612 |
|
break; |
1613 |
< |
if (p == (p = p.next)) |
1614 |
< |
p = head; |
1613 |
> |
if (c != p && tryCasSuccessor(pred, c, p)) |
1614 |
> |
c = p; |
1615 |
> |
q = p.next; |
1616 |
> |
if (pAlive || c != p) { |
1617 |
> |
pred = p; |
1618 |
> |
p = c = q; |
1619 |
> |
} |
1620 |
> |
else if (p == (p = q)) { |
1621 |
> |
pred = null; |
1622 |
> |
c = p = head; |
1623 |
> |
} |
1624 |
|
} |
1625 |
|
} |
1626 |
|
|