src/java.base/share/classes/sun/nio/ch/DatagramChannelImpl.java
changeset 48750 ffbb784a8873
parent 47216 71c04702a3d5
child 48761 74c1fa26435a
--- 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();
         }
     }