--- a/src/java.base/share/classes/sun/net/www/protocol/http/AuthenticationInfo.java Fri Aug 30 13:11:16 2019 +0100
+++ b/src/java.base/share/classes/sun/net/www/protocol/http/AuthenticationInfo.java Fri Aug 30 15:42:27 2019 +0100
@@ -31,6 +31,8 @@
import java.net.URL;
import java.util.HashMap;
import java.util.Objects;
+import java.util.concurrent.locks.Condition;
+import java.util.concurrent.locks.ReentrantLock;
import java.util.function.Function;
import sun.net.www.HeaderParser;
@@ -126,7 +128,8 @@
* the first completes its authentication.
*/
private static HashMap<String,Thread> requests = new HashMap<>();
-
+ private static final ReentrantLock requestLock = new ReentrantLock();
+ private static final Condition requestFinished = requestLock.newCondition();
/*
* check if AuthenticationInfo is available in the cache.
* If not, check if a request for this destination is in progress
@@ -142,8 +145,9 @@
// and we can revert to concurrent requests
return cached;
}
- synchronized (requests) {
- // check again after synchronizing, and if available
+ requestLock.lock();
+ try {
+ // check again after locking, and if available
// just return the cached value.
cached = cache.apply(key);
if (cached != null) return cached;
@@ -164,10 +168,10 @@
// Otherwise, an other thread is currently performing authentication:
// wait until it finishes.
while (requests.containsKey(key)) {
- try {
- requests.wait ();
- } catch (InterruptedException e) {}
+ requestFinished.awaitUninterruptibly();
}
+ } finally {
+ requestLock.unlock();
}
/* entry may be in cache now. */
return cache.apply(key);
@@ -177,13 +181,16 @@
* so that other threads can continue.
*/
private static void requestCompleted (String key) {
- synchronized (requests) {
+ requestLock.lock();
+ try {
Thread thread = requests.get(key);
if (thread != null && thread == Thread.currentThread()) {
boolean waspresent = requests.remove(key) != null;
assert waspresent;
}
- requests.notifyAll();
+ requestFinished.signalAll();
+ } finally {
+ requestLock.unlock();
}
}
@@ -414,9 +421,7 @@
if (!serializeAuth) {
return;
}
- synchronized (requests) {
- requestCompleted(key);
- }
+ requestCompleted(key);
}
/**
@@ -500,6 +505,7 @@
String s1, s2; /* used for serialization of pw */
@java.io.Serial
+ // should be safe to keep synchronized here
private synchronized void readObject(ObjectInputStream s)
throws IOException, ClassNotFoundException
{
@@ -512,6 +518,7 @@
}
@java.io.Serial
+ // should be safe to keep synchronized here
private synchronized void writeObject(java.io.ObjectOutputStream s)
throws IOException
{