# HG changeset patch # User alanb # Date 1517933086 0 # Node ID ffbb784a88732b7c45ab22aaf2d9bd415c01d70e # Parent fd40b0b3d8492de471af98fb1b46f5efaa61fc00 8196787: (ch) Moving network channels to use j.u.c locks Reviewed-by: prappo, rriggs diff -r fd40b0b3d849 -r ffbb784a8873 src/java.base/share/classes/sun/nio/ch/DatagramChannelImpl.java --- a/src/java.base/share/classes/sun/nio/ch/DatagramChannelImpl.java Tue Feb 06 23:49:10 2018 +0530 +++ b/src/java.base/share/classes/sun/nio/ch/DatagramChannelImpl.java Tue Feb 06 16:04:46 2018 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2017, 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 @@ -27,11 +27,32 @@ import java.io.FileDescriptor; import java.io.IOException; -import java.net.*; +import java.net.DatagramSocket; +import java.net.Inet4Address; +import java.net.Inet6Address; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.NetworkInterface; +import java.net.PortUnreachableException; +import java.net.ProtocolFamily; +import java.net.SocketAddress; +import java.net.SocketOption; +import java.net.StandardProtocolFamily; +import java.net.StandardSocketOptions; import java.nio.ByteBuffer; -import java.nio.channels.*; -import java.nio.channels.spi.*; -import java.util.*; +import java.nio.channels.AlreadyBoundException; +import java.nio.channels.ClosedChannelException; +import java.nio.channels.DatagramChannel; +import java.nio.channels.MembershipKey; +import java.nio.channels.NotYetConnectedException; +import java.nio.channels.SelectionKey; +import java.nio.channels.UnsupportedAddressTypeException; +import java.nio.channels.spi.SelectorProvider; +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; +import java.util.concurrent.locks.ReentrantLock; + import sun.net.ResourceManager; import sun.net.ext.ExtendedSocketOptions; @@ -67,10 +88,10 @@ private int cachedSenderPort; // Lock held by current reading or connecting thread - private final Object readLock = new Object(); + private final ReentrantLock readLock = new ReentrantLock(); // Lock held by current writing or connecting thread - private final Object writeLock = new Object(); + private 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! @@ -328,7 +349,8 @@ public SocketAddress receive(ByteBuffer dst) throws IOException { if (dst.isReadOnly()) throw new IllegalArgumentException("Read-only buffer"); - synchronized (readLock) { + readLock.lock(); + try { ensureOpen(); // Socket was not bound before attempting receive if (localAddress() == null) @@ -348,6 +370,8 @@ if (n == IOStatus.UNAVAILABLE) return null; } else { + // Cannot receive into user's buffer when running with a + // security manager and not connected bb = Util.getTemporaryDirectBuffer(dst.remaining()); for (;;) { do { @@ -379,6 +403,8 @@ end((n > 0) || (n == IOStatus.UNAVAILABLE)); assert IOStatus.check(n); } + } finally { + readLock.unlock(); } } @@ -425,7 +451,8 @@ if (src == null) throw new NullPointerException(); - synchronized (writeLock) { + writeLock.lock(); + try { ensureOpen(); InetSocketAddress isa = Net.checkAddress(target); InetAddress ia = isa.getAddress(); @@ -474,6 +501,8 @@ end((n > 0) || (n == IOStatus.UNAVAILABLE)); assert IOStatus.check(n); } + } finally { + writeLock.unlock(); } } @@ -534,7 +563,8 @@ public int read(ByteBuffer buf) throws IOException { if (buf == null) throw new NullPointerException(); - synchronized (readLock) { + readLock.lock(); + try { synchronized (stateLock) { ensureOpen(); if (!isConnected()) @@ -555,6 +585,8 @@ end((n > 0) || (n == IOStatus.UNAVAILABLE)); assert IOStatus.check(n); } + } finally { + readLock.unlock(); } } @@ -563,7 +595,8 @@ { if ((offset < 0) || (length < 0) || (offset > dsts.length - length)) throw new IndexOutOfBoundsException(); - synchronized (readLock) { + readLock.lock(); + try { synchronized (stateLock) { ensureOpen(); if (!isConnected()) @@ -584,13 +617,16 @@ end((n > 0) || (n == IOStatus.UNAVAILABLE)); assert IOStatus.check(n); } + } finally { + readLock.unlock(); } } public int write(ByteBuffer buf) throws IOException { if (buf == null) throw new NullPointerException(); - synchronized (writeLock) { + writeLock.lock(); + try { synchronized (stateLock) { ensureOpen(); if (!isConnected()) @@ -611,6 +647,8 @@ end((n > 0) || (n == IOStatus.UNAVAILABLE)); assert IOStatus.check(n); } + } finally { + writeLock.unlock(); } } @@ -619,7 +657,8 @@ { if ((offset < 0) || (length < 0) || (offset > srcs.length - length)) throw new IndexOutOfBoundsException(); - synchronized (writeLock) { + writeLock.lock(); + try { synchronized (stateLock) { ensureOpen(); if (!isConnected()) @@ -640,6 +679,8 @@ end((n > 0) || (n == IOStatus.UNAVAILABLE)); assert IOStatus.check(n); } + } finally { + writeLock.unlock(); } } @@ -661,8 +702,10 @@ @Override public DatagramChannel bind(SocketAddress local) throws IOException { - synchronized (readLock) { - synchronized (writeLock) { + readLock.lock(); + try { + writeLock.lock(); + try { synchronized (stateLock) { ensureOpen(); if (localAddress != null) @@ -692,7 +735,11 @@ Net.bind(family, fd, isa.getAddress(), isa.getPort()); localAddress = Net.localAddress(fd); } + } finally { + writeLock.unlock(); } + } finally { + readLock.unlock(); } return this; } @@ -714,8 +761,10 @@ @Override public DatagramChannel connect(SocketAddress sa) throws IOException { - synchronized(readLock) { - synchronized(writeLock) { + readLock.lock(); + try { + writeLock.lock(); + try { synchronized (stateLock) { ensureOpenAndUnconnected(); InetSocketAddress isa = Net.checkAddress(sa); @@ -759,14 +808,20 @@ } } } + } finally { + writeLock.unlock(); } + } finally { + readLock.unlock(); } return this; } public DatagramChannel disconnect() throws IOException { - synchronized(readLock) { - synchronized(writeLock) { + readLock.lock(); + try { + writeLock.lock(); + try { synchronized (stateLock) { if (!isConnected() || !isOpen()) return this; @@ -783,7 +838,11 @@ // refresh local address localAddress = Net.localAddress(fd); } + } finally { + writeLock.unlock(); } + } finally { + readLock.unlock(); } return this; } @@ -1087,7 +1146,8 @@ int poll(int events, long timeout) throws IOException { assert Thread.holdsLock(blockingLock()) && !isBlocking(); - synchronized (readLock) { + readLock.lock(); + try { int n = 0; try { begin(); @@ -1102,6 +1162,8 @@ end(n > 0); } return n; + } finally { + readLock.unlock(); } } diff -r fd40b0b3d849 -r ffbb784a8873 src/java.base/share/classes/sun/nio/ch/IOUtil.java --- a/src/java.base/share/classes/sun/nio/ch/IOUtil.java Tue Feb 06 23:49:10 2018 +0530 +++ b/src/java.base/share/classes/sun/nio/ch/IOUtil.java Tue Feb 06 16:04:46 2018 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2017, 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 @@ -78,7 +78,7 @@ src.position(pos); int n = writeFromNativeBuffer(fd, bb, position, - directIO, alignment, nd); + directIO, alignment, nd); if (n > 0) { // now update src src.position(pos + n); @@ -161,8 +161,7 @@ if (!(buf instanceof DirectBuffer)) { ByteBuffer shadow; if (directIO) - shadow = Util.getTemporaryAlignedDirectBuffer(rem, - alignment); + shadow = Util.getTemporaryAlignedDirectBuffer(rem, alignment); else shadow = Util.getTemporaryDirectBuffer(rem); shadow.put(buf); @@ -241,8 +240,7 @@ int rem = dst.remaining(); if (directIO) { Util.checkRemainingBufferSizeAligned(rem, alignment); - bb = Util.getTemporaryAlignedDirectBuffer(rem, - alignment); + bb = Util.getTemporaryAlignedDirectBuffer(rem, alignment); } else { bb = Util.getTemporaryDirectBuffer(rem); } @@ -277,8 +275,7 @@ return 0; int n = 0; if (position != -1) { - n = nd.pread(fd, ((DirectBuffer)bb).address() + pos, - rem, position); + n = nd.pread(fd, ((DirectBuffer)bb).address() + pos, rem, position); } else { n = nd.read(fd, ((DirectBuffer)bb).address() + pos, rem); } @@ -332,8 +329,7 @@ if (!(buf instanceof DirectBuffer)) { ByteBuffer shadow; if (directIO) { - shadow = Util.getTemporaryAlignedDirectBuffer(rem, - alignment); + shadow = Util.getTemporaryAlignedDirectBuffer(rem, alignment); } else { shadow = Util.getTemporaryDirectBuffer(rem); } diff -r fd40b0b3d849 -r ffbb784a8873 src/java.base/share/classes/sun/nio/ch/ServerSocketChannelImpl.java --- a/src/java.base/share/classes/sun/nio/ch/ServerSocketChannelImpl.java Tue Feb 06 23:49:10 2018 +0530 +++ b/src/java.base/share/classes/sun/nio/ch/ServerSocketChannelImpl.java Tue Feb 06 16:04:46 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 @@ -27,10 +27,25 @@ import java.io.FileDescriptor; import java.io.IOException; -import java.net.*; -import java.nio.channels.*; -import java.nio.channels.spi.*; -import java.util.*; +import java.net.InetSocketAddress; +import java.net.ProtocolFamily; +import java.net.ServerSocket; +import java.net.SocketAddress; +import java.net.SocketOption; +import java.net.StandardProtocolFamily; +import java.net.StandardSocketOptions; +import java.nio.channels.AlreadyBoundException; +import java.nio.channels.ClosedChannelException; +import java.nio.channels.NotYetBoundException; +import java.nio.channels.SelectionKey; +import java.nio.channels.ServerSocketChannel; +import java.nio.channels.SocketChannel; +import java.nio.channels.spi.SelectorProvider; +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; +import java.util.concurrent.locks.ReentrantLock; + import sun.net.NetHooks; /** @@ -56,7 +71,7 @@ private volatile long thread; // Lock held by thread currently blocked in this channel - private final Object lock = new Object(); + private final ReentrantLock acceptLock = 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! @@ -77,7 +92,7 @@ private boolean isReuseAddress; // Our socket adaptor, if any - ServerSocket socket; + private ServerSocket socket; // -- End of fields protected by stateLock @@ -211,7 +226,8 @@ @Override public ServerSocketChannel bind(SocketAddress local, int backlog) throws IOException { - synchronized (lock) { + acceptLock.lock(); + try { if (!isOpen()) throw new ClosedChannelException(); if (isBound()) @@ -227,12 +243,15 @@ synchronized (stateLock) { localAddress = Net.localAddress(fd); } + } finally { + acceptLock.unlock(); } return this; } public SocketChannel accept() throws IOException { - synchronized (lock) { + acceptLock.lock(); + try { if (!isOpen()) throw new ClosedChannelException(); if (!isBound()) @@ -278,6 +297,8 @@ } return sc; + } finally { + acceptLock.unlock(); } } @@ -353,7 +374,8 @@ int poll(int events, long timeout) throws IOException { assert Thread.holdsLock(blockingLock()) && !isBlocking(); - synchronized (lock) { + acceptLock.lock(); + try { int n = 0; try { begin(); @@ -368,6 +390,8 @@ end(n > 0); } return n; + } finally { + acceptLock.unlock(); } } diff -r fd40b0b3d849 -r ffbb784a8873 src/java.base/share/classes/sun/nio/ch/SocketChannelImpl.java --- a/src/java.base/share/classes/sun/nio/ch/SocketChannelImpl.java Tue Feb 06 23:49:10 2018 +0530 +++ b/src/java.base/share/classes/sun/nio/ch/SocketChannelImpl.java Tue Feb 06 16:04:46 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 @@ -27,11 +27,30 @@ import java.io.FileDescriptor; import java.io.IOException; -import java.net.*; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.ProtocolFamily; +import java.net.Socket; +import java.net.SocketAddress; +import java.net.SocketOption; +import java.net.StandardProtocolFamily; +import java.net.StandardSocketOptions; import java.nio.ByteBuffer; -import java.nio.channels.*; -import java.nio.channels.spi.*; -import java.util.*; +import java.nio.channels.AlreadyBoundException; +import java.nio.channels.AlreadyConnectedException; +import java.nio.channels.AsynchronousCloseException; +import java.nio.channels.ClosedChannelException; +import java.nio.channels.ConnectionPendingException; +import java.nio.channels.NoConnectionPendingException; +import java.nio.channels.NotYetConnectedException; +import java.nio.channels.SelectionKey; +import java.nio.channels.SocketChannel; +import java.nio.channels.spi.SelectorProvider; +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; +import java.util.concurrent.locks.ReentrantLock; + import sun.net.NetHooks; import sun.net.ext.ExtendedSocketOptions; @@ -59,10 +78,10 @@ private volatile long writerThread; // Lock held by current reading or connecting thread - private final Object readLock = new Object(); + private final ReentrantLock readLock = new ReentrantLock(); // Lock held by current writing or connecting thread - private final Object writeLock = new Object(); + private 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! @@ -89,7 +108,6 @@ // Input/Output open private boolean isInputOpen = true; private boolean isOutputOpen = true; - private boolean readyToConnect = false; // Socket adaptor, created on demand private Socket socket; @@ -298,7 +316,8 @@ if (buf == null) throw new NullPointerException(); - synchronized (readLock) { + readLock.lock(); + try { if (!ensureReadOpen()) return -1; int n = 0; @@ -418,6 +437,8 @@ assert IOStatus.check(n); } + } finally { + readLock.unlock(); } } @@ -426,7 +447,8 @@ { if ((offset < 0) || (length < 0) || (offset > dsts.length - length)) throw new IndexOutOfBoundsException(); - synchronized (readLock) { + readLock.lock(); + try { if (!ensureReadOpen()) return -1; long n = 0; @@ -453,13 +475,16 @@ } assert IOStatus.check(n); } + } finally { + readLock.unlock(); } } public int write(ByteBuffer buf) throws IOException { if (buf == null) throw new NullPointerException(); - synchronized (writeLock) { + writeLock.lock(); + try { ensureWriteOpen(); int n = 0; try { @@ -484,6 +509,8 @@ } assert IOStatus.check(n); } + } finally { + writeLock.unlock(); } } @@ -492,7 +519,8 @@ { if ((offset < 0) || (length < 0) || (offset > srcs.length - length)) throw new IndexOutOfBoundsException(); - synchronized (writeLock) { + writeLock.lock(); + try { ensureWriteOpen(); long n = 0; try { @@ -517,12 +545,15 @@ } assert IOStatus.check(n); } + } finally { + writeLock.unlock(); } } // package-private int sendOutOfBandData(byte b) throws IOException { - synchronized (writeLock) { + writeLock.lock(); + try { ensureWriteOpen(); int n = 0; try { @@ -547,6 +578,8 @@ } assert IOStatus.check(n); } + } finally { + writeLock.unlock(); } } @@ -568,8 +601,10 @@ @Override public SocketChannel bind(SocketAddress local) throws IOException { - synchronized (readLock) { - synchronized (writeLock) { + readLock.lock(); + try { + writeLock.lock(); + try { synchronized (stateLock) { if (!isOpen()) throw new ClosedChannelException(); @@ -587,7 +622,11 @@ Net.bind(fd, isa.getAddress(), isa.getPort()); localAddress = Net.localAddress(fd); } + } finally { + writeLock.unlock(); } + } finally { + readLock.unlock(); } return this; } @@ -616,14 +655,16 @@ } public boolean connect(SocketAddress sa) throws IOException { - synchronized (readLock) { - synchronized (writeLock) { + readLock.lock(); + try { + writeLock.lock(); + try { ensureOpenAndUnconnected(); InetSocketAddress isa = Net.checkAddress(sa); SecurityManager sm = System.getSecurityManager(); if (sm != null) sm.checkConnect(isa.getAddress().getHostAddress(), - isa.getPort()); + isa.getPort()); synchronized (blockingLock()) { int n = 0; try { @@ -636,8 +677,8 @@ // notify hook only if unbound if (localAddress == null) { NetHooks.beforeTcpConnect(fd, - isa.getAddress(), - isa.getPort()); + isa.getAddress(), + isa.getPort()); } readerThread = NativeThread.current(); } @@ -646,10 +687,9 @@ if (ia.isAnyLocalAddress()) ia = InetAddress.getLocalHost(); n = Net.connect(fd, - ia, - isa.getPort()); - if ( (n == IOStatus.INTERRUPTED) - && isOpen()) + ia, + isa.getPort()); + if ((n == IOStatus.INTERRUPTED) && isOpen()) continue; break; } @@ -686,13 +726,19 @@ } } return false; + } finally { + writeLock.unlock(); } + } finally { + readLock.unlock(); } } public boolean finishConnect() throws IOException { - synchronized (readLock) { - synchronized (writeLock) { + readLock.lock(); + try { + writeLock.lock(); + try { synchronized (stateLock) { if (!isOpen()) throw new ClosedChannelException(); @@ -714,24 +760,20 @@ } if (!isBlocking()) { for (;;) { - n = checkConnect(fd, false, - readyToConnect); - if ( (n == IOStatus.INTERRUPTED) - && isOpen()) + n = checkConnect(fd, false); + if ((n == IOStatus.INTERRUPTED) && isOpen()) continue; break; } } else { for (;;) { - n = checkConnect(fd, true, - readyToConnect); + n = checkConnect(fd, true); if (n == 0) { // Loop in case of // spurious notifications continue; } - if ( (n == IOStatus.INTERRUPTED) - && isOpen()) + if ((n == IOStatus.INTERRUPTED) && isOpen()) continue; break; } @@ -769,7 +811,11 @@ return true; } return false; + } finally { + writeLock.unlock(); } + } finally { + readLock.unlock(); } } @@ -903,9 +949,6 @@ if ((ops & (Net.POLLERR | Net.POLLHUP)) != 0) { newOps = intOps; sk.nioReadyOps(newOps); - // No need to poll again in checkConnect, - // the error will be detected there - readyToConnect = true; return (newOps & ~oldOps) != 0; } @@ -918,7 +961,6 @@ ((intOps & SelectionKey.OP_CONNECT) != 0) && ((state == ST_UNCONNECTED) || (state == ST_PENDING))) { newOps |= SelectionKey.OP_CONNECT; - readyToConnect = true; } if (((ops & Net.POLLOUT) != 0) && @@ -942,7 +984,8 @@ int poll(int events, long timeout) throws IOException { assert Thread.holdsLock(blockingLock()) && !isBlocking(); - synchronized (readLock) { + readLock.lock(); + try { int n = 0; try { begin(); @@ -957,6 +1000,8 @@ end(n > 0); } return n; + } finally { + readLock.unlock(); } } @@ -1024,8 +1069,7 @@ // -- Native methods -- - private static native int checkConnect(FileDescriptor fd, - boolean block, boolean ready) + private static native int checkConnect(FileDescriptor fd, boolean block) throws IOException; private static native int sendOutOfBandData(FileDescriptor fd, byte data) diff -r fd40b0b3d849 -r ffbb784a8873 src/java.base/unix/classes/sun/nio/ch/SinkChannelImpl.java --- a/src/java.base/unix/classes/sun/nio/ch/SinkChannelImpl.java Tue Feb 06 23:49:10 2018 +0530 +++ b/src/java.base/unix/classes/sun/nio/ch/SinkChannelImpl.java Tue Feb 06 16:04:46 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,10 +25,14 @@ package sun.nio.ch; -import java.io.*; +import java.io.FileDescriptor; +import java.io.IOException; import java.nio.ByteBuffer; -import java.nio.channels.*; -import java.nio.channels.spi.*; +import java.nio.channels.ClosedChannelException; +import java.nio.channels.Pipe; +import java.nio.channels.SelectionKey; +import java.nio.channels.spi.SelectorProvider; +import java.util.concurrent.locks.ReentrantLock; class SinkChannelImpl @@ -40,17 +44,17 @@ private static final NativeDispatcher nd = new FileDispatcherImpl(); // The file descriptor associated with this channel - FileDescriptor fd; + 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 - int fdVal; + private final int fdVal; // ID of native thread doing write, for signalling private volatile long thread; - // Lock held by current reading thread - private final Object lock = new Object(); + // Lock held by current writing thread + private 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! @@ -155,8 +159,9 @@ } public int write(ByteBuffer src) throws IOException { - ensureOpen(); - synchronized (lock) { + writeLock.lock(); + try { + ensureOpen(); int n = 0; try { begin(); @@ -172,14 +177,18 @@ end((n > 0) || (n == IOStatus.UNAVAILABLE)); assert IOStatus.check(n); } + } finally { + writeLock.unlock(); } } public long write(ByteBuffer[] srcs) throws IOException { if (srcs == null) throw new NullPointerException(); - ensureOpen(); - synchronized (lock) { + + writeLock.lock(); + try { + ensureOpen(); long n = 0; try { begin(); @@ -195,6 +204,8 @@ end((n > 0) || (n == IOStatus.UNAVAILABLE)); assert IOStatus.check(n); } + } finally { + writeLock.unlock(); } } diff -r fd40b0b3d849 -r ffbb784a8873 src/java.base/unix/classes/sun/nio/ch/SourceChannelImpl.java --- a/src/java.base/unix/classes/sun/nio/ch/SourceChannelImpl.java Tue Feb 06 23:49:10 2018 +0530 +++ b/src/java.base/unix/classes/sun/nio/ch/SourceChannelImpl.java Tue Feb 06 16:04:46 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,10 +25,14 @@ package sun.nio.ch; -import java.io.*; +import java.io.FileDescriptor; +import java.io.IOException; import java.nio.ByteBuffer; -import java.nio.channels.*; -import java.nio.channels.spi.*; +import java.nio.channels.ClosedChannelException; +import java.nio.channels.Pipe; +import java.nio.channels.SelectionKey; +import java.nio.channels.spi.SelectorProvider; +import java.util.concurrent.locks.ReentrantLock; class SourceChannelImpl @@ -40,17 +44,17 @@ private static final NativeDispatcher nd = new FileDispatcherImpl(); // The file descriptor associated with this channel - FileDescriptor fd; + 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 - int fdVal; + private final int fdVal; // ID of native thread doing read, for signalling private volatile long thread; // Lock held by current reading thread - private final Object lock = new Object(); + private final ReentrantLock readLock = 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! @@ -155,8 +159,10 @@ } public int read(ByteBuffer dst) throws IOException { - ensureOpen(); - synchronized (lock) { + + readLock.lock(); + try { + ensureOpen(); int n = 0; try { begin(); @@ -172,6 +178,8 @@ end((n > 0) || (n == IOStatus.UNAVAILABLE)); assert IOStatus.check(n); } + } finally { + readLock.unlock(); } } @@ -186,8 +194,10 @@ public long read(ByteBuffer[] dsts) throws IOException { if (dsts == null) throw new NullPointerException(); - ensureOpen(); - synchronized (lock) { + + readLock.lock(); + try { + ensureOpen(); long n = 0; try { begin(); @@ -203,6 +213,8 @@ end((n > 0) || (n == IOStatus.UNAVAILABLE)); assert IOStatus.check(n); } + } finally { + readLock.unlock(); } } } diff -r fd40b0b3d849 -r ffbb784a8873 src/java.base/unix/native/libnio/ch/SocketChannelImpl.c --- a/src/java.base/unix/native/libnio/ch/SocketChannelImpl.c Tue Feb 06 23:49:10 2018 +0530 +++ b/src/java.base/unix/native/libnio/ch/SocketChannelImpl.c Tue Feb 06 16:04:46 2018 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2010, 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 @@ -47,8 +47,7 @@ JNIEXPORT jint JNICALL Java_sun_nio_ch_SocketChannelImpl_checkConnect(JNIEnv *env, jobject this, - jobject fdo, jboolean block, - jboolean ready) + jobject fdo, jboolean block) { int error = 0; socklen_t n = sizeof(int); @@ -56,19 +55,16 @@ int result = 0; struct pollfd poller; - poller.revents = 1; - if (!ready) { - poller.fd = fd; - poller.events = POLLOUT; - poller.revents = 0; - result = poll(&poller, 1, block ? -1 : 0); - if (result < 0) { - JNU_ThrowIOExceptionWithLastError(env, "Poll failed"); - return IOS_THROWN; - } - if (!block && (result == 0)) - return IOS_UNAVAILABLE; + poller.fd = fd; + poller.events = POLLOUT; + poller.revents = 0; + result = poll(&poller, 1, block ? -1 : 0); + if (result < 0) { + JNU_ThrowIOExceptionWithLastError(env, "Poll failed"); + return IOS_THROWN; } + if (!block && (result == 0)) + return IOS_UNAVAILABLE; if (poller.revents) { errno = 0; diff -r fd40b0b3d849 -r ffbb784a8873 src/java.base/windows/classes/sun/nio/ch/SinkChannelImpl.java --- a/src/java.base/windows/classes/sun/nio/ch/SinkChannelImpl.java Tue Feb 06 23:49:10 2018 +0530 +++ b/src/java.base/windows/classes/sun/nio/ch/SinkChannelImpl.java Tue Feb 06 16:04:46 2018 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 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 @@ -44,7 +44,7 @@ implements SelChImpl { // The SocketChannel assoicated with this pipe - SocketChannel sc; + final SocketChannel sc; public FileDescriptor getFD() { return ((SocketChannelImpl)sc).getFD(); diff -r fd40b0b3d849 -r ffbb784a8873 src/java.base/windows/classes/sun/nio/ch/SourceChannelImpl.java --- a/src/java.base/windows/classes/sun/nio/ch/SourceChannelImpl.java Tue Feb 06 23:49:10 2018 +0530 +++ b/src/java.base/windows/classes/sun/nio/ch/SourceChannelImpl.java Tue Feb 06 16:04:46 2018 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 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 @@ -43,7 +43,7 @@ implements SelChImpl { // The SocketChannel assoicated with this pipe - SocketChannel sc; + private final SocketChannel sc; public FileDescriptor getFD() { return ((SocketChannelImpl) sc).getFD(); diff -r fd40b0b3d849 -r ffbb784a8873 src/java.base/windows/native/libnio/ch/SocketChannelImpl.c --- a/src/java.base/windows/native/libnio/ch/SocketChannelImpl.c Tue Feb 06 23:49:10 2018 +0530 +++ b/src/java.base/windows/native/libnio/ch/SocketChannelImpl.c Tue Feb 06 16:04:46 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 @@ -55,8 +55,7 @@ JNIEXPORT jint JNICALL Java_sun_nio_ch_SocketChannelImpl_checkConnect(JNIEnv *env, jobject this, - jobject fdo, jboolean block, - jboolean ready) + jobject fdo, jboolean block) { int optError = 0; int lastError = 0;