--- old/src/java.base/share/classes/sun/nio/ch/SocketChannelImpl.java 2018-05-03 16:52:26.325492649 -0700 +++ new/src/java.base/share/classes/sun/nio/ch/SocketChannelImpl.java 2018-05-03 16:52:26.101492664 -0700 @@ -59,68 +59,68 @@ * An implementation of SocketChannels */ -class SocketChannelImpl +public class SocketChannelImpl extends SocketChannel implements SelChImpl { // Used to make native read and write calls - private static NativeDispatcher nd; + protected static NativeDispatcher nd; // Our file descriptor object - private final FileDescriptor fd; - private final int fdVal; + protected FileDescriptor fd; + protected final int fdVal; // Lock held by current reading or connecting thread - private final ReentrantLock readLock = new ReentrantLock(); + protected final ReentrantLock readLock = new ReentrantLock(); // Lock held by current writing or connecting thread - private final ReentrantLock writeLock = new ReentrantLock(); + protected final ReentrantLock writeLock = new ReentrantLock(); // Lock held by any thread that modifies the state fields declared below // DO NOT invoke a blocking I/O operation while holding this lock! - private final Object stateLock = new Object(); + protected final Object stateLock = new Object(); // Input/Output closed - private volatile boolean isInputClosed; - private volatile boolean isOutputClosed; + protected volatile boolean isInputClosed; + protected volatile boolean isOutputClosed; // -- The following fields are protected by stateLock // set true when exclusive binding is on and SO_REUSEADDR is emulated - private boolean isReuseAddress; + protected boolean isReuseAddress; // State, increases monotonically - private static final int ST_UNCONNECTED = 0; - private static final int ST_CONNECTIONPENDING = 1; - private static final int ST_CONNECTED = 2; - private static final int ST_CLOSING = 3; - private static final int ST_KILLPENDING = 4; - private static final int ST_KILLED = 5; - private volatile int state; // need stateLock to change + protected static final int ST_UNCONNECTED = 0; + protected static final int ST_CONNECTIONPENDING = 1; + protected static final int ST_CONNECTED = 2; + protected static final int ST_CLOSING = 3; + protected static final int ST_KILLPENDING = 4; + protected static final int ST_KILLED = 5; + protected volatile int state; // need stateLock to change // IDs of native threads doing reads and writes, for signalling - private long readerThread; - private long writerThread; + protected long readerThread; + protected long writerThread; // Binding - private InetSocketAddress localAddress; - private InetSocketAddress remoteAddress; + protected InetSocketAddress localAddress; + protected InetSocketAddress remoteAddress; // Socket adaptor, created on demand - private Socket socket; + protected Socket socket; // -- End of fields protected by stateLock // Constructor for normal connecting sockets // - SocketChannelImpl(SelectorProvider sp) throws IOException { + protected SocketChannelImpl(SelectorProvider sp) throws IOException { super(sp); - this.fd = Net.socket(true); + this.fd = createFD(); this.fdVal = IOUtil.fdVal(fd); } - SocketChannelImpl(SelectorProvider sp, FileDescriptor fd, boolean bound) + protected SocketChannelImpl(SelectorProvider sp, FileDescriptor fd, boolean bound) throws IOException { super(sp); @@ -128,32 +128,41 @@ this.fdVal = IOUtil.fdVal(fd); if (bound) { synchronized (stateLock) { - this.localAddress = Net.localAddress(fd); + this.localAddress = createLocalAddress(fd); } } } // Constructor for sockets obtained from server sockets // - SocketChannelImpl(SelectorProvider sp, FileDescriptor fd, InetSocketAddress isa) + protected SocketChannelImpl(SelectorProvider sp, FileDescriptor fd, InetSocketAddress isa) throws IOException { super(sp); this.fd = fd; this.fdVal = IOUtil.fdVal(fd); synchronized (stateLock) { - this.localAddress = Net.localAddress(fd); + this.localAddress = createLocalAddress(fd); this.remoteAddress = isa; this.state = ST_CONNECTED; } } + protected FileDescriptor createFD() throws IOException { + return Net.socket(true); + } + + protected InetSocketAddress createLocalAddress(FileDescriptor fd) + throws IOException { + return Net.localAddress(fd); + } + /** * Checks that the channel is open. * * @throws ClosedChannelException if channel is closed (or closing) */ - private void ensureOpen() throws ClosedChannelException { + protected void ensureOpen() throws ClosedChannelException { if (!isOpen()) throw new ClosedChannelException(); } @@ -286,7 +295,7 @@ } @Override - public final Set> supportedOptions() { + public Set> supportedOptions() { return DefaultOptionsHolder.defaultOptions; } @@ -296,7 +305,7 @@ * @throws ClosedChannelException if the channel is closed * @throws NotYetConnectedException if the channel is not yet connected */ - private void beginRead(boolean blocking) throws ClosedChannelException { + protected void beginRead(boolean blocking) throws ClosedChannelException { if (blocking) { // set hook for Thread.interrupt begin(); @@ -317,7 +326,7 @@ * @throws AsynchronousCloseException if the channel was closed due to this * thread being interrupted on a blocking read operation. */ - private void endRead(boolean blocking, boolean completed) + protected void endRead(boolean blocking, boolean completed) throws AsynchronousCloseException { if (blocking) { @@ -407,7 +416,7 @@ * @throws ClosedChannelException if the channel is closed or output shutdown * @throws NotYetConnectedException if the channel is not yet connected */ - private void beginWrite(boolean blocking) throws ClosedChannelException { + protected void beginWrite(boolean blocking) throws ClosedChannelException { if (blocking) { // set hook for Thread.interrupt begin(); @@ -430,7 +439,7 @@ * @throws AsynchronousCloseException if the channel was closed due to this * thread being interrupted on a blocking write operation. */ - private void endWrite(boolean blocking, boolean completed) + protected void endWrite(boolean blocking, boolean completed) throws AsynchronousCloseException { if (blocking) { @@ -507,7 +516,7 @@ /** * Writes a byte of out of band data. */ - int sendOutOfBandData(byte b) throws IOException { + protected int sendOutOfBandData(byte b) throws IOException { writeLock.lock(); try { boolean blocking = isBlocking(); @@ -553,7 +562,7 @@ /** * Returns the local address, or null if not bound */ - InetSocketAddress localAddress() { + protected InetSocketAddress localAddress() { synchronized (stateLock) { return localAddress; } @@ -562,7 +571,7 @@ /** * Returns the remote address, or null if not connected */ - InetSocketAddress remoteAddress() { + protected InetSocketAddress remoteAddress() { synchronized (stateLock) { return remoteAddress; } @@ -618,7 +627,7 @@ * @throws ConnectionPendingException is a connection is pending * @throws IOException if the pre-connect hook fails */ - private void beginConnect(boolean blocking, InetSocketAddress isa) + protected void beginConnect(boolean blocking, InetSocketAddress isa) throws IOException { if (blocking) { @@ -653,7 +662,7 @@ * thread being interrupted on a blocking connect operation. * @throws IOException if completed and unable to obtain the local address */ - private void endConnect(boolean blocking, boolean completed) + protected void endConnect(boolean blocking, boolean completed) throws IOException { endRead(blocking, completed); @@ -715,7 +724,7 @@ * @throws ClosedChannelException if the channel is closed * @throws NoConnectionPendingException if no connection is pending */ - private void beginFinishConnect(boolean blocking) throws ClosedChannelException { + protected void beginFinishConnect(boolean blocking) throws ClosedChannelException { if (blocking) { // set hook for Thread.interrupt begin(); @@ -738,7 +747,7 @@ * thread being interrupted on a blocking connect operation. * @throws IOException if completed and unable to obtain the local address */ - private void endFinishConnect(boolean blocking, boolean completed) + protected void endFinishConnect(boolean blocking, boolean completed) throws IOException { endRead(blocking, completed); @@ -930,11 +939,11 @@ } } - boolean isInputOpen() { + protected boolean isInputOpen() { return !isInputClosed; } - boolean isOutputOpen() { + protected boolean isOutputOpen() { return !isOutputClosed; }