8196787: (ch) Moving network channels to use j.u.c locks
Reviewed-by: prappo, rriggs
--- 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();
}
}
--- 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);
}
--- 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();
}
}
--- 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)
--- 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();
}
}
--- 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();
}
}
}
--- 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;
--- 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();
--- 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();
--- 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;