Path: blob/master/test/jdk/java/nio/channels/Selector/RacyDeregister.java
51568 views
/*1* Copyright (c) 2013, 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/*24* Portions Copyright (c) 2012 IBM Corporation25*/2627import java.net.InetAddress;28import java.net.InetSocketAddress;29import java.nio.channels.SelectionKey;30import java.nio.channels.Selector;31import java.nio.channels.ServerSocketChannel;32import java.nio.channels.SocketChannel;3334/*35* @test36* @bug 6429204 8203766 820564137* @summary SelectionKey.interestOps does not update interest set on Windows.38* @author Frank Ding39* @run main/timeout=1200 RacyDeregister40*/4142/* @test43* @requires (os.family == "windows")44* @run main/othervm/timeout=1200 -Djava.nio.channels.spi.SelectorProvider=sun.nio.ch.WindowsSelectorProvider RacyDeregister45*/4647public class RacyDeregister {4849// 90% of 1200 second timeout as milliseconds50static final int TIMEOUT_THRESHOLD_MILLIS = 1200*900;5152// Time at start of main().53static long t0;5455static boolean notified;56static final Object selectorLock = new Object();57static final Object notifyLock = new Object();58/**59* null: not terminated60* true: passed61* false: failed62*/63static volatile Boolean succTermination = null;6465public static void main(String[] args) throws Exception {66t0 = System.currentTimeMillis();6768InetAddress addr = InetAddress.getByName(null);69ServerSocketChannel sc = ServerSocketChannel.open();70sc.socket().bind(new InetSocketAddress(addr, 0));7172SocketChannel.open(new InetSocketAddress(addr,73sc.socket().getLocalPort()));7475SocketChannel accepted = sc.accept();76accepted.configureBlocking(false);7778SocketChannel.open(new InetSocketAddress(addr,79sc.socket().getLocalPort()));80SocketChannel accepted2 = sc.accept();81accepted2.configureBlocking(false);8283final Selector sel = Selector.open();84SelectionKey key2 = accepted2.register(sel, SelectionKey.OP_READ);85final SelectionKey[] key = new SelectionKey[]{86accepted.register(sel, SelectionKey.OP_READ)};8788// thread that will be changing key[0].interestOps to OP_READ | OP_WRITE89new Thread() {9091public void run() {92try {93for (int k = 0; k < 15; k++) {94System.out.format("outer loop %3d at %7d ms%n", k,95System.currentTimeMillis() - t0);96System.out.flush();97for (int i = 0; i < 10000; i++) {98synchronized (notifyLock) {99synchronized (selectorLock) {100sel.wakeup();101key[0].interestOps(SelectionKey.OP_READ102| SelectionKey.OP_WRITE);103}104notified = false;105long beginTime = System.currentTimeMillis();106while (true) {107notifyLock.wait(5000);108if (notified) {109break;110}111long endTime = System.currentTimeMillis();112if (endTime - beginTime > 5000) {113for (int j = 0; j < 60; j++) {114Thread.sleep(1000);115if (notified) {116long t =117System.currentTimeMillis();118System.err.printf119("Notified after %d ms%n",120t - beginTime);121System.err.flush();122break;123}124}125succTermination = false;126// wake up main thread doing select()127sel.wakeup();128return;129}130}131}132}133long t = System.currentTimeMillis();134if (t - t0 > TIMEOUT_THRESHOLD_MILLIS) {135System.err.format136("Timeout after %d outer loop iterations%n", k);137System.err.flush();138succTermination = false;139// wake up main thread doing select()140sel.wakeup();141return;142}143}144succTermination = true;145// wake up main thread doing select()146sel.wakeup();147} catch (Exception e) {148System.out.println(e);149System.out.flush();150succTermination = true;151// wake up main thread doing select()152sel.wakeup();153}154}155}.start();156157// main thread will be doing registering/deregistering with the sel158while (true) {159sel.select();160if (Boolean.TRUE.equals(succTermination)) {161System.out.println("Test passed");162System.out.flush();163sel.close();164sc.close();165break;166} else if (Boolean.FALSE.equals(succTermination)) {167System.err.println("Failed to pass the test");168System.err.flush();169sel.close();170sc.close();171throw new RuntimeException("Failed to pass the test");172}173synchronized (selectorLock) {174}175if (sel.selectedKeys().contains(key[0]) && key[0].isWritable()) {176synchronized (notifyLock) {177notified = true;178notifyLock.notify();179key[0].cancel();180sel.selectNow();181key2 = accepted2.register(sel, SelectionKey.OP_READ);182key[0] = accepted.register(sel, SelectionKey.OP_READ);183}184}185key2.cancel();186sel.selectedKeys().clear();187}188}189}190191192