< prev index next >

src/java.base/share/classes/sun/nio/ch/SocketChannelImpl.java

Print this page
rev 55750 : UDS support, temporary commit

@@ -35,10 +35,11 @@
 import java.net.SocketException;
 import java.net.SocketOption;
 import java.net.SocketTimeoutException;
 import java.net.StandardProtocolFamily;
 import java.net.StandardSocketOptions;
+import java.net.UnixSocketAddress;
 import java.nio.ByteBuffer;
 import java.nio.channels.AlreadyBoundException;
 import java.nio.channels.AlreadyConnectedException;
 import java.nio.channels.AsynchronousCloseException;
 import java.nio.channels.ClosedChannelException;

@@ -108,18 +109,23 @@
     // IDs of native threads doing reads and writes, for signalling
     private long readerThread;
     private long writerThread;
 
     // Binding
-    private InetSocketAddress localAddress;
-    private InetSocketAddress remoteAddress;
+    private SocketAddress localAddress;
+    private SocketAddress remoteAddress;
 
     // Socket adaptor, created on demand
     private Socket socket;
 
     // -- End of fields protected by stateLock
 
+    SocketChannelImpl(SelectorProvider sp, ProtocolFamily family) throws IOException {
+        super(sp);
+        this.fd = Net.socket(family, true);
+        this.fdVal = IOUtil.fdVal(fd);
+    }
 
     // Constructor for normal connecting sockets
     //
     SocketChannelImpl(SelectorProvider sp) throws IOException {
         super(sp);

@@ -140,18 +146,18 @@
         }
     }
 
     // Constructor for sockets obtained from server sockets
     //
-    SocketChannelImpl(SelectorProvider sp, FileDescriptor fd, InetSocketAddress isa)
+    SocketChannelImpl(SelectorProvider sp, FileDescriptor fd, SocketAddress isa)
         throws IOException
     {
         super(sp);
         this.fd = fd;
         this.fdVal = IOUtil.fdVal(fd);
         synchronized (stateLock) {
-            this.localAddress = Net.localAddress(fd);
+            this.localAddress = Net.localSocketAddress(fd);
             this.remoteAddress = isa;
             this.state = ST_CONNECTED;
         }
     }
 

@@ -197,11 +203,11 @@
 
     @Override
     public SocketAddress getLocalAddress() throws IOException {
         synchronized (stateLock) {
             ensureOpen();
-            return Net.getRevealedLocalAddress(localAddress);
+            return localAddress instanceof InetSocketAddress ? Net.getRevealedLocalAddress((InetSocketAddress) localAddress) : localAddress;
         }
     }
 
     @Override
     public SocketAddress getRemoteAddress() throws IOException {

@@ -586,20 +592,20 @@
     /**
      * Returns the local address, or null if not bound
      */
     InetSocketAddress localAddress() {
         synchronized (stateLock) {
-            return localAddress;
+            return localAddress instanceof InetSocketAddress ? (InetSocketAddress) localAddress : null;
         }
     }
 
     /**
      * Returns the remote address, or null if not connected
      */
     InetSocketAddress remoteAddress() {
         synchronized (stateLock) {
-            return remoteAddress;
+            return remoteAddress instanceof InetSocketAddress ? (InetSocketAddress) remoteAddress : null;
         }
     }
 
     @Override
     public SocketChannel bind(SocketAddress local) throws IOException {

@@ -678,10 +684,43 @@
             }
         }
     }
 
     /**
+     * TODO: refactoring, combine with InetSocketAddress method?
+     * 
+     * @param blocking
+     * @param usa
+     * @throws IOException 
+     */
+    private void beginConnect(boolean blocking, UnixSocketAddress usa)
+        throws IOException
+    {
+        if (blocking) {
+            // set hook for Thread.interrupt
+            begin();
+        }
+        synchronized (stateLock) {
+            ensureOpen();
+            int state = this.state;
+            if (state == ST_CONNECTED)
+                throw new AlreadyConnectedException();
+            if (state == ST_CONNECTIONPENDING)
+                throw new ConnectionPendingException();
+            assert state == ST_UNCONNECTED;
+            this.state = ST_CONNECTIONPENDING;
+
+            remoteAddress = usa;
+
+            if (blocking) {
+                // record thread so it can be signalled if needed
+                readerThread = NativeThread.current();
+            }
+        }
+    }
+
+    /**
      * Marks the end of a connect operation that may have blocked.
      *
      * @throws AsynchronousCloseException if the channel was closed due to this
      * thread being interrupted on a blocking connect operation.
      * @throws IOException if completed and unable to obtain the local address

@@ -703,10 +742,15 @@
 
     /**
      * Checks the remote address to which this channel is to be connected.
      */
     private InetSocketAddress checkRemote(SocketAddress sa) throws IOException {
+        if (sa instanceof UnixSocketAddress) {
+            // TODO: SecurityManager, refactor null
+            return null;
+        }
+        
         InetSocketAddress isa = Net.checkAddress(sa);
         SecurityManager sm = System.getSecurityManager();
         if (sm != null) {
             sm.checkConnect(isa.getAddress().getHostAddress(), isa.getPort());
         }

@@ -726,12 +770,19 @@
                 writeLock.lock();
                 try {
                     boolean blocking = isBlocking();
                     boolean connected = false;
                     try {
+                        int n;
+                        if (remote instanceof UnixSocketAddress) {
+                            UnixSocketAddress usa = (UnixSocketAddress)remote;
+                            beginConnect(blocking, usa);
+                            n = Net.connect(fd, usa);
+                        } else {
                         beginConnect(blocking, isa);
-                        int n = Net.connect(fd, isa.getAddress(), isa.getPort());
+                            n = Net.connect(fd, isa.getAddress(), isa.getPort());
+                        }
                         if (n > 0) {
                             connected = true;
                         } else if (blocking) {
                             assert IOStatus.okayToRetry(n);
                             boolean polled = false;

@@ -752,11 +803,11 @@
                 readLock.unlock();
             }
         } catch (IOException ioe) {
             // connect failed, close the channel
             close();
-            throw SocketExceptions.of(ioe, isa);
+            throw SocketExceptions.of(ioe, remote);
         }
     }
 
     /**
      * Marks the beginning of a finishConnect operation that might block.

@@ -1042,15 +1093,25 @@
                 try {
                     if (!isBlocking())
                         throw new IllegalBlockingModeException();
                     boolean connected = false;
                     try {
+                        if (remote instanceof UnixSocketAddress) {
+                            UnixSocketAddress usa = (UnixSocketAddress)remote;
+                            beginConnect(true, usa);
+                        } else {
                         beginConnect(true, isa);
+                        }
                         // change socket to non-blocking
                         lockedConfigureBlocking(false);
                         try {
-                            int n = Net.connect(fd, isa.getAddress(), isa.getPort());
+                            int n;
+                            if (remote instanceof UnixSocketAddress) {
+                                n = Net.connect(fd, (UnixSocketAddress) remote); // TODO: refactor null/remote/isa
+                            } else {
+                                n = Net.connect(fd, isa.getAddress(), isa.getPort());
+                            }
                             connected = (n > 0) ? true : finishTimedConnect(nanos);
                         } finally {
                             // restore socket to blocking mode
                             lockedConfigureBlocking(true);
                         }
< prev index next >