From 13f5b93e8cf12ea1ebae177fbb39a572ef57ca0e Mon Sep 17 00:00:00 2001 From: Brian Burkhalter Date: Wed, 8 Mar 2017 09:49:46 -0800 Subject: [PATCH] 8175209: Account for race condition in java/nio/channels/AsynchronousSocketChannel/Basic.java Pause until the channel reaches a pended state instead of for a fixed time. Reviewed-by: prappo, mli, alanb --- .../AsynchronousSocketChannel/Basic.java | 64 ++++++++++++------- 1 file changed, 40 insertions(+), 24 deletions(-) diff --git a/jdk/test/java/nio/channels/AsynchronousSocketChannel/Basic.java b/jdk/test/java/nio/channels/AsynchronousSocketChannel/Basic.java index f98fca05391..3202551c6d2 100644 --- a/jdk/test/java/nio/channels/AsynchronousSocketChannel/Basic.java +++ b/jdk/test/java/nio/channels/AsynchronousSocketChannel/Basic.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,24 +23,27 @@ /* @test * @bug 4607272 6842687 6878369 6944810 7023403 - * @summary Unit test for AsynchronousSocketChannel + * @summary Unit test for AsynchronousSocketChannel(use -Dseed=X to set PRNG seed) + * @library /lib/testlibrary/ + * @build jdk.testlibrary.* * @run main Basic -skipSlowConnectTest * @key randomness intermittent */ -import java.nio.ByteBuffer; -import java.nio.channels.*; -import static java.net.StandardSocketOptions.*; -import java.net.*; -import java.util.Random; -import java.util.concurrent.*; -import java.util.concurrent.atomic.*; import java.io.Closeable; import java.io.IOException; +import java.net.*; +import static java.net.StandardSocketOptions.*; +import java.nio.ByteBuffer; +import java.nio.channels.*; +import java.util.Random; import java.util.Set; +import java.util.concurrent.*; +import java.util.concurrent.atomic.*; +import jdk.testlibrary.RandomFactory; public class Basic { - static final Random rand = new Random(); + private static final Random RAND = RandomFactory.getRandom(); static boolean skipSlowConnectTest = false; @@ -327,8 +330,10 @@ public class Basic { new AtomicReference(); // write bytes to fill socket buffer + final AtomicInteger numCompleted = new AtomicInteger(); ch.write(genBuffer(), ch, new CompletionHandler() { public void completed(Integer result, AsynchronousSocketChannel ch) { + numCompleted.incrementAndGet(); ch.write(genBuffer(), ch, this); } public void failed(Throwable x, AsynchronousSocketChannel ch) { @@ -336,10 +341,21 @@ public class Basic { } }); - // give time for socket buffer to fill up. - Thread.sleep(5*1000); + // give time for socket buffer to fill up - + // take pauses until the handler is no longer being invoked + // because all writes are being pended which guarantees that + // the internal channel state indicates it is writing + int prevNumCompleted = numCompleted.get(); + do { + Thread.sleep(1000); + if (numCompleted.get() == prevNumCompleted) { + break; + } + prevNumCompleted = numCompleted.get(); + } while (true); - // attempt a concurrent write - should fail with WritePendingException + // attempt a concurrent write - + // should fail with WritePendingException try { ch.write(genBuffer()); throw new RuntimeException("WritePendingException expected"); @@ -497,12 +513,12 @@ public class Basic { // trickle the writing do { int rem = src.remaining(); - int size = (rem <= 100) ? rem : 50 + rand.nextInt(rem - 100); + int size = (rem <= 100) ? rem : 50 + RAND.nextInt(rem - 100); ByteBuffer buf = ByteBuffer.allocate(size); for (int i=0; i 1) - len += rand.nextInt(max); + len += RAND.nextInt(max); ByteBuffer[] bufs = new ByteBuffer[len]; for (int i=0; i