1 /* 2 * Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 /* @test 25 * @bug 4607272 6842687 26 * @summary Unit test for AsynchronousChannelGroup 27 */ 28 29 import java.nio.ByteBuffer; 30 import java.nio.channels.*; 31 import java.net.*; 32 import java.util.*; 33 import java.util.concurrent.*; 34 import java.io.IOException; 35 36 /** 37 * This test verifies that a channel or channel group can be closed from a 38 * completion handler when there are no threads available to handle I/O events. 39 */ 40 41 public class GroupOfOne { 42 main(String[] args)43 public static void main(String[] args) throws Exception { 44 final List<AsynchronousSocketChannel> accepted = new ArrayList<>(); 45 46 // create listener to accept connections 47 try (final AsynchronousServerSocketChannel listener = 48 AsynchronousServerSocketChannel.open()) { 49 50 listener.bind(new InetSocketAddress(0)); 51 listener.accept((Void)null, new CompletionHandler<AsynchronousSocketChannel,Void>() { 52 public void completed(AsynchronousSocketChannel ch, Void att) { 53 synchronized (accepted) { 54 accepted.add(ch); 55 } 56 listener.accept((Void)null, this); 57 } 58 public void failed(Throwable exc, Void att) { 59 } 60 }); 61 62 int port = ((InetSocketAddress)(listener.getLocalAddress())).getPort(); 63 SocketAddress sa = new InetSocketAddress(InetAddress.getLocalHost(), port); 64 65 test(sa, true, false); 66 test(sa, false, true); 67 test(sa, true, true); 68 } finally { 69 // clean-up 70 synchronized (accepted) { 71 for (AsynchronousSocketChannel ch: accepted) { 72 ch.close(); 73 } 74 } 75 } 76 } 77 test(SocketAddress sa, final boolean closeChannel, final boolean shutdownGroup)78 static void test(SocketAddress sa, 79 final boolean closeChannel, 80 final boolean shutdownGroup) 81 throws Exception 82 { 83 // group with 1 thread 84 final AsynchronousChannelGroup group = AsynchronousChannelGroup 85 .withFixedThreadPool(1, new ThreadFactory() { 86 @Override 87 public Thread newThread(final Runnable r) { 88 return new Thread(r); 89 }}); 90 final AsynchronousSocketChannel ch = AsynchronousSocketChannel.open(group); 91 try { 92 // the latch counts down when: 93 // 1. The read operation fails (expected) 94 // 2. the close/shutdown completes 95 final CountDownLatch latch = new CountDownLatch(2); 96 97 ch.connect(sa, (Void)null, new CompletionHandler<Void,Void>() { 98 public void completed(Void result, Void att) { 99 System.out.println("Connected"); 100 101 // initiate I/O operation that does not complete (successfully) 102 ByteBuffer buf = ByteBuffer.allocate(100); 103 ch.read(buf, (Void)null, new CompletionHandler<Integer,Void>() { 104 public void completed(Integer bytesRead, Void att) { 105 throw new RuntimeException(); 106 } 107 public void failed(Throwable exc, Void att) { 108 if (!(exc instanceof AsynchronousCloseException)) 109 throw new RuntimeException(exc); 110 System.out.println("Read failed (expected)"); 111 latch.countDown(); 112 } 113 }); 114 115 // close channel or shutdown group 116 try { 117 if (closeChannel) { 118 System.out.print("Close channel ..."); 119 ch.close(); 120 System.out.println(" done."); 121 } 122 if (shutdownGroup) { 123 System.out.print("Shutdown group ..."); 124 group.shutdownNow(); 125 System.out.println(" done."); 126 } 127 latch.countDown(); 128 } catch (IOException e) { 129 throw new RuntimeException(); 130 } 131 } 132 public void failed(Throwable exc, Void att) { 133 throw new RuntimeException(exc); 134 } 135 }); 136 137 latch.await(); 138 } finally { 139 // clean-up 140 group.shutdown(); 141 boolean terminated = group.awaitTermination(20, TimeUnit.SECONDS); 142 if (!terminated) 143 throw new RuntimeException("Group did not terminate"); 144 } 145 System.out.println("TEST OKAY"); 146 } 147 } 148