Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/test/java/nio/channels/AsynchronousChannelGroup/Identity.java
38821 views
/*1* Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.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 it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223/* @test24* @bug 4607272 684268725* @summary Unit test for AsynchronousChannelGroup26* @key randomness27*/2829import java.nio.ByteBuffer;30import java.nio.channels.*;31import java.net.*;32import java.util.*;33import java.util.concurrent.*;34import java.util.concurrent.atomic.*;35import java.io.IOException;3637/**38* Tests that the completion handler is invoked by a thread with39* the expected identity.40*/4142public class Identity {43static final Random rand = new Random();44static final CountDownLatch done = new CountDownLatch(1);45static final AtomicBoolean failed = new AtomicBoolean(false);4647static void fail(String msg) {48failed.set(true);49done.countDown();50throw new RuntimeException(msg);51}5253// thread-local identifies the thread54private static final ThreadLocal<Integer> myGroup =55new ThreadLocal<Integer>() {56@Override protected Integer initialValue() {57return Integer.valueOf(-1);58}59};6061// creates a ThreadFactory that constructs groups with the given identity62static final ThreadFactory createThreadFactory(final int groupId) {63return new ThreadFactory() {64@Override65public Thread newThread(final Runnable r) {66Thread t = new Thread(new Runnable() {67public void run() {68myGroup.set(groupId);69r.run();70}});71t.setDaemon(true);72return t;73}74};75}7677public static void main(String[] args) throws Exception {78// create listener to accept connections79final AsynchronousServerSocketChannel listener =80AsynchronousServerSocketChannel.open()81.bind(new InetSocketAddress(0));82listener.accept((Void)null, new CompletionHandler<AsynchronousSocketChannel,Void>() {83public void completed(final AsynchronousSocketChannel ch, Void att) {84listener.accept((Void)null, this);85final ByteBuffer buf = ByteBuffer.allocate(100);86ch.read(buf, ch, new CompletionHandler<Integer,AsynchronousSocketChannel>() {87public void completed(Integer bytesRead, AsynchronousSocketChannel ch) {88if (bytesRead < 0) {89try { ch.close(); } catch (IOException ignore) { }90} else {91buf.clear();92ch.read(buf, ch, this);93}94}95public void failed(Throwable exc, AsynchronousSocketChannel ch) {96try { ch.close(); } catch (IOException ignore) { }97}98});99}100public void failed(Throwable exc, Void att) {101}102});103int port = ((InetSocketAddress)(listener.getLocalAddress())).getPort();104SocketAddress sa = new InetSocketAddress(InetAddress.getLocalHost(), port);105106// create 3-10 channels, each in its own group107final int groupCount = 3 + rand.nextInt(8);108AsynchronousChannelGroup[] groups = new AsynchronousChannelGroup[groupCount];109final AsynchronousSocketChannel[] channels = new AsynchronousSocketChannel[groupCount];110for (int i=0; i<groupCount; i++) {111ThreadFactory factory = createThreadFactory(i);112AsynchronousChannelGroup group;113if (rand.nextBoolean()) {114int nThreads = 1 + rand.nextInt(10);115group = AsynchronousChannelGroup.withFixedThreadPool(nThreads, factory);116} else {117ExecutorService pool = Executors.newCachedThreadPool(factory);118group = AsynchronousChannelGroup.withCachedThreadPool(pool, rand.nextInt(5));119}120groups[i] = group;121122// create channel in group and connect it to the server123AsynchronousSocketChannel ch = AsynchronousSocketChannel.open(group);124ch.connect(sa).get();125channels[i] = ch;126}127128// randomly write to each channel, ensuring that the completion handler129// is always invoked by a thread with the right identity.130final AtomicInteger writeCount = new AtomicInteger(100);131channels[0].write(getBuffer(), 0, new CompletionHandler<Integer,Integer>() {132public void completed(Integer bytesWritten, Integer groupId) {133if (bytesWritten != 1)134fail("Expected 1 byte to be written");135if (!myGroup.get().equals(groupId))136fail("Handler invoked by thread with the wrong identity");137if (writeCount.decrementAndGet() > 0) {138int id = rand.nextInt(groupCount);139channels[id].write(getBuffer(), id, this);140} else {141done.countDown();142}143}144public void failed(Throwable exc, Integer groupId) {145fail(exc.getMessage());146}147});148149// wait until done150done.await();151152// clean-up153for (AsynchronousSocketChannel ch: channels)154ch.close();155for (AsynchronousChannelGroup group: groups)156group.shutdownNow();157listener.close();158159if (failed.get())160throw new RuntimeException("Test failed - see log for details");161}162163static ByteBuffer getBuffer() {164ByteBuffer buf;165if (rand.nextBoolean()) {166buf = ByteBuffer.allocateDirect(1);167} else {168buf = ByteBuffer.allocate(1);169}170buf.put((byte)0);171buf.flip();172return buf;173}174}175176177