changeset 49122:74c1fa26435a

8196956: (ch) More channels cleanup Reviewed-by: rriggs, prappo, bpb
author alanb
date Thu, 08 Feb 2018 10:55:21 +0000
parents 25725c11c296
children 85c27aabf312
files src/java.base/share/classes/java/nio/channels/SelectableChannel.java src/java.base/share/classes/java/nio/channels/spi/AbstractSelectableChannel.java src/java.base/share/classes/sun/nio/ch/DatagramChannelImpl.java src/java.base/share/classes/sun/nio/ch/DatagramSocketAdaptor.java src/java.base/share/classes/sun/nio/ch/ServerSocketAdaptor.java src/java.base/share/classes/sun/nio/ch/ServerSocketChannelImpl.java src/java.base/share/classes/sun/nio/ch/SocketAdaptor.java src/java.base/share/classes/sun/nio/ch/SocketChannelImpl.java
diffstat 8 files changed, 107 insertions(+), 62 deletions(-) [+]
line wrap: on
line diff
--- 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
--- 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;
     }
--- 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);
--- 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) { }
         }
     }
 
--- 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 {
--- 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;
--- 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) { }
                 }
-
             }
         }
     }
--- 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