8180279: java/net/httpclient/whitebox/Driver.java failed due to timeout
Fixed a race condition in RawChannelTest.java Reviewed-by: prappo, michaelm
This commit is contained in:
parent
51272f395a
commit
aea187fdd2
@ -62,12 +62,14 @@ public class RawChannelTest {
|
|||||||
* once (socket's send buffer filled up).
|
* once (socket's send buffer filled up).
|
||||||
*/
|
*/
|
||||||
private final CountDownLatch writeStall = new CountDownLatch(1);
|
private final CountDownLatch writeStall = new CountDownLatch(1);
|
||||||
|
private final CountDownLatch initialWriteStall = new CountDownLatch(1);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This one works similarly by providing means to ensure a read from the
|
* This one works similarly by providing means to ensure a read from the
|
||||||
* channel will stall at least once (no more data available on the socket).
|
* channel will stall at least once (no more data available on the socket).
|
||||||
*/
|
*/
|
||||||
private final CountDownLatch readStall = new CountDownLatch(1);
|
private final CountDownLatch readStall = new CountDownLatch(1);
|
||||||
|
private final CountDownLatch initialReadStall = new CountDownLatch(1);
|
||||||
|
|
||||||
private final AtomicInteger writeHandles = new AtomicInteger();
|
private final AtomicInteger writeHandles = new AtomicInteger();
|
||||||
private final AtomicInteger readHandles = new AtomicInteger();
|
private final AtomicInteger readHandles = new AtomicInteger();
|
||||||
@ -79,7 +81,9 @@ public class RawChannelTest {
|
|||||||
try (ServerSocket server = new ServerSocket(0)) {
|
try (ServerSocket server = new ServerSocket(0)) {
|
||||||
int port = server.getLocalPort();
|
int port = server.getLocalPort();
|
||||||
new TestServer(server).start();
|
new TestServer(server).start();
|
||||||
|
|
||||||
final RawChannel chan = channelOf(port);
|
final RawChannel chan = channelOf(port);
|
||||||
|
initialWriteStall.await();
|
||||||
|
|
||||||
// It's very important not to forget the initial bytes, possibly
|
// It's very important not to forget the initial bytes, possibly
|
||||||
// left from the HTTP thingy
|
// left from the HTTP thingy
|
||||||
@ -87,6 +91,12 @@ public class RawChannelTest {
|
|||||||
print("RawChannel has %s initial bytes", initialBytes);
|
print("RawChannel has %s initial bytes", initialBytes);
|
||||||
clientRead.addAndGet(initialBytes);
|
clientRead.addAndGet(initialBytes);
|
||||||
|
|
||||||
|
// tell the server we have read the initial bytes, so
|
||||||
|
// that it makes sure there is something for us to
|
||||||
|
// read next in case the initialBytes have already drained the
|
||||||
|
// channel dry.
|
||||||
|
initialReadStall.countDown();
|
||||||
|
|
||||||
chan.registerEvent(new RawChannel.RawEvent() {
|
chan.registerEvent(new RawChannel.RawEvent() {
|
||||||
|
|
||||||
private final ByteBuffer reusableBuffer = ByteBuffer.allocate(32768);
|
private final ByteBuffer reusableBuffer = ByteBuffer.allocate(32768);
|
||||||
@ -162,7 +172,7 @@ public class RawChannelTest {
|
|||||||
total += r;
|
total += r;
|
||||||
clientRead.addAndGet(r);
|
clientRead.addAndGet(r);
|
||||||
}
|
}
|
||||||
print("OP_READ read %s bytes", total);
|
print("OP_READ read %s bytes (%s total)", total, clientRead.get());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
exit.await(); // All done, we need to compare results:
|
exit.await(); // All done, we need to compare results:
|
||||||
@ -234,6 +244,14 @@ public class RawChannelTest {
|
|||||||
throws IOException
|
throws IOException
|
||||||
{
|
{
|
||||||
os.write("HTTP/1.1 200 OK\r\nContent-length: 0\r\n\r\n".getBytes());
|
os.write("HTTP/1.1 200 OK\r\nContent-length: 0\r\n\r\n".getBytes());
|
||||||
|
|
||||||
|
// write some initial bytes
|
||||||
|
byte[] initial = byteArrayOfSize(1024);
|
||||||
|
os.write(initial);
|
||||||
|
os.flush();
|
||||||
|
serverWritten.addAndGet(initial.length);
|
||||||
|
initialWriteStall.countDown();
|
||||||
|
|
||||||
byte[] buf = new byte[1024];
|
byte[] buf = new byte[1024];
|
||||||
String s = "";
|
String s = "";
|
||||||
while (true) {
|
while (true) {
|
||||||
@ -252,12 +270,25 @@ public class RawChannelTest {
|
|||||||
byte[] first = byteArrayOfSize(1024);
|
byte[] first = byteArrayOfSize(1024);
|
||||||
long total = first.length;
|
long total = first.length;
|
||||||
os.write(first);
|
os.write(first);
|
||||||
|
os.flush();
|
||||||
|
|
||||||
|
// wait until initial bytes were read
|
||||||
|
initialReadStall.await();
|
||||||
|
|
||||||
|
// make sure there is something to read, otherwise readStall
|
||||||
|
// will never be counted down.
|
||||||
|
first = byteArrayOfSize(1024);
|
||||||
|
os.write(first);
|
||||||
|
os.flush();
|
||||||
|
total += first.length;
|
||||||
|
|
||||||
// Let's wait for the signal from the raw channel that its read has
|
// Let's wait for the signal from the raw channel that its read has
|
||||||
// stalled, and then continue sending a bit more stuff
|
// stalled, and then continue sending a bit more stuff
|
||||||
readStall.await();
|
readStall.await();
|
||||||
for (int i = 0; i < 32; i++) {
|
for (int i = 0; i < 32; i++) {
|
||||||
byte[] b = byteArrayOfSize(1024);
|
byte[] b = byteArrayOfSize(1024);
|
||||||
os.write(b);
|
os.write(b);
|
||||||
|
os.flush();
|
||||||
total += b.length;
|
total += b.length;
|
||||||
TimeUnit.MILLISECONDS.sleep(1);
|
TimeUnit.MILLISECONDS.sleep(1);
|
||||||
}
|
}
|
||||||
@ -265,7 +296,7 @@ public class RawChannelTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private long readSlowly(InputStream is) throws Exception {
|
private long readSlowly(InputStream is) throws Exception {
|
||||||
// Wait for the raw channel to fill up the its send buffer
|
// Wait for the raw channel to fill up its send buffer
|
||||||
writeStall.await();
|
writeStall.await();
|
||||||
long overall = 0;
|
long overall = 0;
|
||||||
byte[] array = new byte[1024];
|
byte[] array = new byte[1024];
|
||||||
|
Loading…
Reference in New Issue
Block a user