# HG changeset patch # User alanb # Date 1518087321 0 # Node ID 74c1fa26435af72051f0958f99ee8154a55534f6 # Parent 25725c11c2962b96f7229cfe75700e5bbfbdd2b1 8196956: (ch) More channels cleanup Reviewed-by: rriggs, prappo, bpb diff -r 25725c11c296 -r 74c1fa26435a src/java.base/share/classes/java/nio/channels/SelectableChannel.java --- a/src/java.base/share/classes/java/nio/channels/SelectableChannel.java Thu Feb 08 11:44:21 2018 +0800 +++ b/src/java.base/share/classes/java/nio/channels/SelectableChannel.java Thu Feb 08 10:55:21 2018 +0000 @@ -121,7 +121,7 @@ // keySet, may be empty but is never null, typ. a tiny array // boolean isRegistered, protected by key set // regLock, lock object to prevent duplicate registrations - // boolean isBlocking, protected by regLock + // blocking mode, protected by regLock /** * Tells whether or not this channel is currently registered with any diff -r 25725c11c296 -r 74c1fa26435a src/java.base/share/classes/java/nio/channels/spi/AbstractSelectableChannel.java --- a/src/java.base/share/classes/java/nio/channels/spi/AbstractSelectableChannel.java Thu Feb 08 11:44:21 2018 +0800 +++ b/src/java.base/share/classes/java/nio/channels/spi/AbstractSelectableChannel.java Thu Feb 08 10:55:21 2018 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2018, 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 @@ -26,7 +26,14 @@ package java.nio.channels.spi; import java.io.IOException; -import java.nio.channels.*; +import java.nio.channels.CancelledKeyException; +import java.nio.channels.ClosedChannelException; +import java.nio.channels.ClosedSelectorException; +import java.nio.channels.IllegalBlockingModeException; +import java.nio.channels.IllegalSelectorException; +import java.nio.channels.SelectableChannel; +import java.nio.channels.SelectionKey; +import java.nio.channels.Selector; /** @@ -67,8 +74,8 @@ // Lock for registration and configureBlocking operations private final Object regLock = new Object(); - // Blocking mode, protected by regLock - boolean blocking = true; + // True when non-blocking, need regLock to change; + private volatile boolean nonBlocking; /** * Initializes a new instance of this class. @@ -197,7 +204,7 @@ throw new ClosedChannelException(); if ((ops & ~validOps()) != 0) throw new IllegalArgumentException(); - if (blocking) + if (isBlocking()) throw new IllegalBlockingModeException(); SelectionKey k = findKey(sel); if (k != null) { @@ -264,9 +271,7 @@ // -- Blocking -- public final boolean isBlocking() { - synchronized (regLock) { - return blocking; - } + return !nonBlocking; } public final Object blockingLock() { @@ -287,12 +292,13 @@ synchronized (regLock) { if (!isOpen()) throw new ClosedChannelException(); - if (blocking == block) - return this; - if (block && haveValidKeys()) - throw new IllegalBlockingModeException(); - implConfigureBlocking(block); - blocking = block; + boolean blocking = !nonBlocking; + if (block != blocking) { + if (block && haveValidKeys()) + throw new IllegalBlockingModeException(); + implConfigureBlocking(block); + nonBlocking = !block; + } } return this; } diff -r 25725c11c296 -r 74c1fa26435a src/java.base/share/classes/sun/nio/ch/DatagramChannelImpl.java --- a/src/java.base/share/classes/sun/nio/ch/DatagramChannelImpl.java Thu Feb 08 11:44:21 2018 +0800 +++ b/src/java.base/share/classes/sun/nio/ch/DatagramChannelImpl.java Thu Feb 08 10:55:21 2018 +0000 @@ -70,9 +70,6 @@ // Our file descriptor private final FileDescriptor fd; - - // fd value needed for dev/poll. This value will remain valid - // even after the value in the file descriptor object has been set to -1 private final int fdVal; // The protocol family of the socket @@ -124,7 +121,6 @@ // -- End of fields protected by stateLock - public DatagramChannelImpl(SelectorProvider sp) throws IOException { @@ -159,16 +155,27 @@ throw new UnsupportedOperationException("IPv6 not available"); } } - this.family = family; - this.fd = Net.socket(family, false); - this.fdVal = IOUtil.fdVal(fd); - this.state = ST_UNCONNECTED; + + ResourceManager.beforeUdpCreate(); + try { + this.family = family; + this.fd = Net.socket(family, false); + this.fdVal = IOUtil.fdVal(fd); + this.state = ST_UNCONNECTED; + } catch (IOException ioe) { + ResourceManager.afterUdpClose(); + throw ioe; + } } public DatagramChannelImpl(SelectorProvider sp, FileDescriptor fd) throws IOException { super(sp); + + // increment UDP count to match decrement when closing + ResourceManager.beforeUdpCreate(); + this.family = Net.isIPv6Available() ? StandardProtocolFamily.INET6 : StandardProtocolFamily.INET; this.fd = fd; @@ -790,10 +797,9 @@ localAddress = Net.localAddress(fd); // flush any packets already received. - boolean blocking = false; synchronized (blockingLock()) { + boolean blocking = isBlocking(); try { - blocking = isBlocking(); ByteBuffer tmpBuf = ByteBuffer.allocate(100); if (blocking) { configureBlocking(false); diff -r 25725c11c296 -r 74c1fa26435a src/java.base/share/classes/sun/nio/ch/DatagramSocketAdaptor.java --- a/src/java.base/share/classes/sun/nio/ch/DatagramSocketAdaptor.java Thu Feb 08 11:44:21 2018 +0800 +++ b/src/java.base/share/classes/sun/nio/ch/DatagramSocketAdaptor.java Thu Feb 08 10:55:21 2018 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2018, 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 @@ -25,10 +25,22 @@ package sun.nio.ch; -import java.io.*; -import java.net.*; -import java.nio.*; -import java.nio.channels.*; +import java.io.IOException; +import java.net.DatagramPacket; +import java.net.DatagramSocket; +import java.net.DatagramSocketImpl; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.NetworkInterface; +import java.net.SocketAddress; +import java.net.SocketException; +import java.net.SocketOption; +import java.net.SocketTimeoutException; +import java.net.StandardSocketOptions; +import java.nio.ByteBuffer; +import java.nio.channels.ClosedChannelException; +import java.nio.channels.DatagramChannel; +import java.nio.channels.IllegalBlockingModeException; // Make a datagram-socket channel look like a datagram socket. @@ -178,7 +190,6 @@ dc.configureBlocking(false); try { - int n; SocketAddress sender; if ((sender = dc.receive(bb)) != null) return sender; @@ -188,19 +199,18 @@ throw new ClosedChannelException(); long st = System.currentTimeMillis(); int result = dc.poll(Net.POLLIN, to); - if (result > 0 && - ((result & Net.POLLIN) != 0)) { + if (result > 0 && ((result & Net.POLLIN) != 0)) { if ((sender = dc.receive(bb)) != null) return sender; } to -= System.currentTimeMillis() - st; if (to <= 0) throw new SocketTimeoutException(); - } } finally { - if (dc.isOpen()) + try { dc.configureBlocking(true); + } catch (ClosedChannelException e) { } } } diff -r 25725c11c296 -r 74c1fa26435a src/java.base/share/classes/sun/nio/ch/ServerSocketAdaptor.java --- a/src/java.base/share/classes/sun/nio/ch/ServerSocketAdaptor.java Thu Feb 08 11:44:21 2018 +0800 +++ b/src/java.base/share/classes/sun/nio/ch/ServerSocketAdaptor.java Thu Feb 08 10:55:21 2018 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2018, 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 @@ -25,9 +25,20 @@ package sun.nio.ch; -import java.io.*; -import java.net.*; -import java.nio.channels.*; +import java.io.IOException; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.ServerSocket; +import java.net.Socket; +import java.net.SocketAddress; +import java.net.SocketException; +import java.net.SocketTimeoutException; +import java.net.StandardSocketOptions; +import java.nio.channels.ClosedChannelException; +import java.nio.channels.IllegalBlockingModeException; +import java.nio.channels.NotYetBoundException; +import java.nio.channels.ServerSocketChannel; +import java.nio.channels.SocketChannel; // Make a server-socket channel look like a server socket. @@ -37,7 +48,7 @@ // class. // -public class ServerSocketAdaptor // package-private +class ServerSocketAdaptor // package-private extends ServerSocket { @@ -96,13 +107,18 @@ try { if (!ssc.isBound()) throw new NotYetBoundException(); + if (timeout == 0) { + // for compatibility reasons: accept connection if available + // when configured non-blocking SocketChannel sc = ssc.accept(); if (sc == null && !ssc.isBlocking()) throw new IllegalBlockingModeException(); return sc.socket(); } + if (!ssc.isBlocking()) + throw new IllegalBlockingModeException(); ssc.configureBlocking(false); try { SocketChannel sc; @@ -121,10 +137,10 @@ throw new SocketTimeoutException(); } } finally { - if (ssc.isOpen()) + try { ssc.configureBlocking(true); + } catch (ClosedChannelException e) { } } - } catch (Exception x) { Net.translateException(x); assert false; @@ -178,8 +194,7 @@ if (!isBound()) return "ServerSocket[unbound]"; return "ServerSocket[addr=" + getInetAddress() + - // ",port=" + getPort() + - ",localport=" + getLocalPort() + "]"; + ",localport=" + getLocalPort() + "]"; } public void setReceiveBufferSize(int size) throws SocketException { diff -r 25725c11c296 -r 74c1fa26435a src/java.base/share/classes/sun/nio/ch/ServerSocketChannelImpl.java --- a/src/java.base/share/classes/sun/nio/ch/ServerSocketChannelImpl.java Thu Feb 08 11:44:21 2018 +0800 +++ b/src/java.base/share/classes/sun/nio/ch/ServerSocketChannelImpl.java Thu Feb 08 10:55:21 2018 +0000 @@ -62,10 +62,7 @@ // Our file descriptor private final FileDescriptor fd; - - // fd value needed for dev/poll. This value will remain valid - // even after the value in the file descriptor object has been set to -1 - private int fdVal; + private final int fdVal; // ID of native thread currently blocked in this channel, for signalling private volatile long thread; diff -r 25725c11c296 -r 74c1fa26435a src/java.base/share/classes/sun/nio/ch/SocketAdaptor.java --- a/src/java.base/share/classes/sun/nio/ch/SocketAdaptor.java Thu Feb 08 11:44:21 2018 +0800 +++ b/src/java.base/share/classes/sun/nio/ch/SocketAdaptor.java Thu Feb 08 10:55:21 2018 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2018, 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 @@ -25,10 +25,23 @@ package sun.nio.ch; -import java.io.*; -import java.net.*; -import java.nio.*; -import java.nio.channels.*; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.Socket; +import java.net.SocketAddress; +import java.net.SocketException; +import java.net.SocketImpl; +import java.net.SocketOption; +import java.net.SocketTimeoutException; +import java.net.StandardSocketOptions; +import java.nio.ByteBuffer; +import java.nio.channels.Channels; +import java.nio.channels.ClosedChannelException; +import java.nio.channels.IllegalBlockingModeException; +import java.nio.channels.SocketChannel; import java.security.AccessController; import java.security.PrivilegedExceptionAction; import java.util.concurrent.TimeUnit; @@ -45,7 +58,7 @@ // java.net.Socket so as to simplify tracking future changes to that class. // -public class SocketAdaptor +class SocketAdaptor extends Socket { @@ -89,7 +102,6 @@ throw new IllegalBlockingModeException(); try { - if (timeout == 0) { sc.connect(remote); return; @@ -119,8 +131,9 @@ } } } finally { - if (sc.isOpen()) + try { sc.configureBlocking(true); + } catch (ClosedChannelException e) { } } } catch (Exception x) { @@ -188,10 +201,11 @@ synchronized (sc.blockingLock()) { if (!sc.isBlocking()) throw new IllegalBlockingModeException(); + if (timeout == 0) return sc.read(bb); + sc.configureBlocking(false); - try { int n; if ((n = sc.read(bb)) != 0) @@ -213,10 +227,10 @@ throw new SocketTimeoutException(); } } finally { - if (sc.isOpen()) + try { sc.configureBlocking(true); + } catch (ClosedChannelException e) { } } - } } } diff -r 25725c11c296 -r 74c1fa26435a src/java.base/share/classes/sun/nio/ch/SocketChannelImpl.java --- a/src/java.base/share/classes/sun/nio/ch/SocketChannelImpl.java Thu Feb 08 11:44:21 2018 +0800 +++ b/src/java.base/share/classes/sun/nio/ch/SocketChannelImpl.java Thu Feb 08 10:55:21 2018 +0000 @@ -68,9 +68,6 @@ // Our file descriptor object private final FileDescriptor fd; - - // fd value needed for dev/poll. This value will remain valid - // even after the value in the file descriptor object has been set to -1 private final int fdVal; // IDs of native threads doing reads and writes, for signalling