Path: blob/master/test/jdk/java/nio/channels/Selector/ChangingInterests.java
41153 views
/*1* Copyright (c) 2012, 2021, 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 720074225* @key intermittent26* @summary Test that Selector doesn't spin when changing interest ops27*/2829/* @test30* @requires (os.family == "windows")31* @run main/othervm -Djava.nio.channels.spi.SelectorProvider=sun.nio.ch.WindowsSelectorProvider ChangingInterests32*/3334import java.net.*;35import java.nio.ByteBuffer;36import java.nio.channels.*;37import static java.nio.channels.SelectionKey.*;38import java.io.IOException;3940public class ChangingInterests {4142static int OPS[] = { 0, OP_WRITE, OP_READ, (OP_WRITE|OP_READ) };4344static String toOpsString(int ops) {45String s = "";46if ((ops & OP_READ) > 0)47s += "POLLIN";48if ((ops & OP_WRITE) > 0) {49if (s.length() > 0)50s += "|";51s += "POLLOUT";52}53if (s.length() == 0)54s = "0";55return "(" + s + ")";56}5758/**59* Writes two bytes to 'out' and reads one byte from 'in' so60* as to make 'in' readable.61*/62static void makeReadable(SocketChannel out, SocketChannel in) throws IOException {63out.write(ByteBuffer.wrap(new byte[2]));64ByteBuffer oneByte = ByteBuffer.wrap(new byte[1]);65do {66int n = in.read(oneByte);67if (n == 1) {68break;69} else if (n == 0) {70try {71Thread.sleep(50);72} catch (InterruptedException ignore) { }73} else {74throw new RuntimeException75("Expected to read 0 or 1 byte; actual number was " + n);76}77} while (true);78}7980static void drain(SocketChannel sc) throws IOException {81ByteBuffer buf = ByteBuffer.allocate(100);82int n;83while ((n = sc.read(buf)) > 0) {84buf.rewind();85}86}8788/**89* Changes the given key's interest set from one set to another and then90* checks the selected key set and the key's channel.91*/92static void testChange(SelectionKey key, int from, int to) throws IOException {93Selector sel = key.selector();94assertTrue(sel.keys().size() == 1, "Only one channel should be registered");9596// ensure that channel is registered with the "from" interest set97key.interestOps(from);98sel.selectNow();99sel.selectedKeys().clear();100101// change to the "to" interest set102key.interestOps(to);103System.out.println("select...");104int selected = sel.selectNow();105System.out.println("" + selected + " channel(s) selected");106107int expected = (to == 0) ? 0 : 1;108assertTrue(selected == expected, "Expected " + expected);109110// check selected keys111for (SelectionKey k: sel.selectedKeys()) {112assertTrue(k == key, "Unexpected key selected");113114boolean readable = k.isReadable();115boolean writable = k.isWritable();116117System.out.println("key readable: " + readable);118System.out.println("key writable: " + writable);119120if ((to & OP_READ) == 0) {121assertTrue(!readable, "Not expected to be readable");122} else {123assertTrue(readable, "Expected to be readable");124}125126if ((to & OP_WRITE) == 0) {127assertTrue(!writable, "Not expected to be writable");128} else {129assertTrue(writable, "Expected to be writable");130}131132sel.selectedKeys().clear();133}134}135136/**137* Tests that given Selector's select method blocks.138*/139static void testForSpin(Selector sel) throws IOException {140System.out.println("Test for spin...");141long start = System.currentTimeMillis();142int count = 3;143while (count-- > 0) {144int selected = sel.select(1000);145System.out.println("" + selected + " channel(s) selected");146assertTrue(selected == 0, "Channel should not be selected");147}148long dur = System.currentTimeMillis() - start;149assertTrue(dur > 1000, "select was too short");150}151152public static void main(String[] args) throws IOException {153InetAddress lh = InetAddress.getLocalHost();154155// create loopback connection156ServerSocketChannel ssc =157ServerSocketChannel.open().bind(new InetSocketAddress(0));158159final SocketChannel sc = SocketChannel.open();160sc.setOption(StandardSocketOptions.TCP_NODELAY, true);161sc.connect(new InetSocketAddress(lh, ssc.socket().getLocalPort()));162SocketChannel peer = ssc.accept();163peer.setOption(StandardSocketOptions.TCP_NODELAY, true);164165sc.configureBlocking(false);166167// ensure that channel "sc" is readable168makeReadable(peer, sc);169170try (Selector sel = Selector.open()) {171SelectionKey key = sc.register(sel, 0);172sel.selectNow();173174// test all transitions175for (int from: OPS) {176for (int to: OPS) {177178System.out.println(toOpsString(from) + " -> " + toOpsString(to));179180testChange(key, from, to);181182// if the interst ops is now 0 then Selector should not spin183if (to == 0)184testForSpin(sel);185186// if interest ops is now OP_READ then make non-readable187// and test that Selector does not spin.188if (to == OP_READ) {189System.out.println("Drain channel...");190drain(sc);191testForSpin(sel);192System.out.println("Make channel readable again");193makeReadable(peer, sc);194}195196System.out.println();197}198}199200} finally {201sc.close();202peer.close();203ssc.close();204}205}206207static void assertTrue(boolean v, String msg) {208if (!v) throw new RuntimeException(msg);209}210211}212213214