Skip to content

Commit db38949

Browse files
author
duke
committed
Backport d350158e060c01acf49759dcbdd1f4d72530111b
1 parent cdbdbdc commit db38949

File tree

2 files changed

+87
-7
lines changed

2 files changed

+87
-7
lines changed

src/java.base/share/classes/java/util/concurrent/LinkedTransferQueue.java

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -588,13 +588,15 @@ final Object xfer(Object e, long ns) {
588588
do {
589589
m = p.item;
590590
q = p.next;
591-
if (p.isData != haveData && haveData != (m != null) &&
592-
p.cmpExItem(m, e) == m) {
593-
Thread w = p.waiter; // matched complementary node
594-
if (p != h && h == cmpExHead(h, (q == null) ? p : q))
595-
h.next = h; // advance head; self-link old
596-
LockSupport.unpark(w);
597-
return m;
591+
if (p.isData != haveData && haveData != (m != null)) {
592+
if (p.cmpExItem(m, e) == m) {
593+
Thread w = p.waiter; // matched complementary node
594+
if (p != h && h == cmpExHead(h, (q == null) ? p : q))
595+
h.next = h; // advance head; self-link old
596+
LockSupport.unpark(w);
597+
return m;
598+
}
599+
continue restart;
598600
} else if (q == null) {
599601
if (ns == 0L) // try to append unless immediate
600602
break restart;
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
/*
2+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
3+
*
4+
* This code is free software; you can redistribute it and/or modify it
5+
* under the terms of the GNU General Public License version 2 only, as
6+
* published by the Free Software Foundation. Oracle designates this
7+
* particular file as subject to the "Classpath" exception as provided
8+
* by Oracle in the LICENSE file that accompanied this code.
9+
*
10+
* This code is distributed in the hope that it will be useful, but WITHOUT
11+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13+
* version 2 for more details (a copy is included in the LICENSE file that
14+
* accompanied this code).
15+
*
16+
* You should have received a copy of the GNU General Public License version
17+
* 2 along with this work; if not, write to the Free Software Foundation,
18+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19+
*
20+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
21+
* or visit www.oracle.com if you need additional information or have any
22+
* questions.
23+
*/
24+
25+
/*
26+
* @test
27+
* @bug 8371740
28+
* @summary Checks for poll() (or peek) returning null when an element must exist.
29+
*/
30+
import java.util.*;
31+
import java.util.concurrent.*;
32+
33+
public class MissedPoll {
34+
public static void main(String... args) throws Throwable {
35+
test(new LinkedTransferQueue<>());
36+
test(new LinkedBlockingQueue<>());
37+
test(new LinkedBlockingDeque<>());
38+
test(new ArrayBlockingQueue<>(10));
39+
}
40+
41+
private static void test(BlockingQueue<Integer> q)
42+
throws ExecutionException, InterruptedException {
43+
System.out.println(q.getClass());
44+
try (var pool = Executors.newCachedThreadPool()) {
45+
var futures = new ArrayList<Future<Integer>>();
46+
var phaser = new Phaser(4) {
47+
@Override
48+
protected boolean onAdvance(int phase, int registeredParties) {
49+
q.clear();
50+
return super.onAdvance(phase, registeredParties);
51+
}
52+
};
53+
for (var i = 0; i < 4; i++) {
54+
futures.add(pool.submit(() -> {
55+
int errors = 0;
56+
for (int k = 0; k < 10; k++) {
57+
for (int j = 0; j < 1000; j++) {
58+
q.offer(j);
59+
if (q.peek() == null)
60+
++errors;
61+
if (q.poll() == null)
62+
++errors;
63+
}
64+
phaser.arriveAndAwaitAdvance();
65+
}
66+
return errors;
67+
}));
68+
}
69+
for (var future : futures) {
70+
Integer res;
71+
if ((res = future.get()) != 0)
72+
throw new AssertionError("Expected 0 but got " + res);
73+
}
74+
}
75+
if (!q.isEmpty())
76+
throw new AssertionError("Queue is not empty: " + q);
77+
}
78+
}

0 commit comments

Comments
 (0)