8302732: sun/net/www/http/HttpClient/MultiThreadTest.java still failing intermittently
Reviewed-by: dfuchs
This commit is contained in:
parent
db217c9ad6
commit
a2c5a4ac9e
src/java.base/share/classes/sun/net/www/http
test/jdk/sun/net/www/http/HttpClient
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1996, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1996, 2023, 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
|
||||
@ -36,7 +36,6 @@ import java.util.ArrayDeque;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
import jdk.internal.misc.InnocuousThread;
|
||||
@ -51,7 +50,7 @@ import sun.util.logging.PlatformLogger;
|
||||
* @author Dave Brown
|
||||
*/
|
||||
public class KeepAliveCache
|
||||
extends HashMap<KeepAliveKey, ClientVector>
|
||||
extends HashMap<KeepAliveKey, KeepAliveCache.ClientVector>
|
||||
implements Runnable {
|
||||
@java.io.Serial
|
||||
private static final long serialVersionUID = -2937172892064557949L;
|
||||
@ -243,32 +242,32 @@ public class KeepAliveCache
|
||||
// Remove all outdated HttpClients.
|
||||
cacheLock.lock();
|
||||
try {
|
||||
if (isEmpty()) {
|
||||
// cache not used in the last LIFETIME - exit
|
||||
keepAliveTimer = null;
|
||||
break;
|
||||
}
|
||||
long currentTime = System.currentTimeMillis();
|
||||
List<KeepAliveKey> keysToRemove = new ArrayList<>();
|
||||
|
||||
for (KeepAliveKey key : keySet()) {
|
||||
ClientVector v = get(key);
|
||||
v.lock();
|
||||
try {
|
||||
KeepAliveEntry e = v.peekLast();
|
||||
while (e != null) {
|
||||
if ((currentTime - e.idleStartTime) > v.nap) {
|
||||
v.pollLast();
|
||||
if (closeList == null) {
|
||||
closeList = new ArrayList<>();
|
||||
}
|
||||
closeList.add(e.hc);
|
||||
} else {
|
||||
break;
|
||||
KeepAliveEntry e = v.peekLast();
|
||||
while (e != null) {
|
||||
if ((currentTime - e.idleStartTime) > v.nap) {
|
||||
v.pollLast();
|
||||
if (closeList == null) {
|
||||
closeList = new ArrayList<>();
|
||||
}
|
||||
e = v.peekLast();
|
||||
closeList.add(e.hc);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
e = v.peekLast();
|
||||
}
|
||||
|
||||
if (v.isEmpty()) {
|
||||
keysToRemove.add(key);
|
||||
}
|
||||
} finally {
|
||||
v.unlock();
|
||||
if (v.isEmpty()) {
|
||||
keysToRemove.add(key);
|
||||
}
|
||||
}
|
||||
|
||||
@ -284,7 +283,7 @@ public class KeepAliveCache
|
||||
}
|
||||
}
|
||||
}
|
||||
} while (!isEmpty());
|
||||
} while (keepAliveTimer == Thread.currentThread());
|
||||
}
|
||||
|
||||
/*
|
||||
@ -301,27 +300,24 @@ public class KeepAliveCache
|
||||
{
|
||||
throw new NotSerializableException();
|
||||
}
|
||||
}
|
||||
|
||||
/* LIFO order for reusing HttpClients. Most recent entries at the front.
|
||||
* If > maxConns are in use, discard oldest.
|
||||
*/
|
||||
class ClientVector extends ArrayDeque<KeepAliveEntry> {
|
||||
@java.io.Serial
|
||||
private static final long serialVersionUID = -8680532108106489459L;
|
||||
private final ReentrantLock lock = new ReentrantLock();
|
||||
/* LIFO order for reusing HttpClients. Most recent entries at the front.
|
||||
* If > maxConns are in use, discard oldest.
|
||||
*/
|
||||
class ClientVector extends ArrayDeque<KeepAliveEntry> {
|
||||
@java.io.Serial
|
||||
private static final long serialVersionUID = -8680532108106489459L;
|
||||
|
||||
// sleep time in milliseconds, before cache clear
|
||||
int nap;
|
||||
// sleep time in milliseconds, before cache clear
|
||||
int nap;
|
||||
|
||||
ClientVector(int nap) {
|
||||
this.nap = nap;
|
||||
}
|
||||
ClientVector(int nap) {
|
||||
this.nap = nap;
|
||||
}
|
||||
|
||||
/* return a still valid, idle HttpClient */
|
||||
HttpClient get() {
|
||||
lock();
|
||||
try {
|
||||
/* return a still valid, idle HttpClient */
|
||||
HttpClient get() {
|
||||
assert cacheLock.isHeldByCurrentThread();
|
||||
// check the most recent connection, use if still valid
|
||||
KeepAliveEntry e = peekFirst();
|
||||
if (e == null) {
|
||||
@ -339,49 +335,34 @@ class ClientVector extends ArrayDeque<KeepAliveEntry> {
|
||||
}
|
||||
return e.hc;
|
||||
}
|
||||
} finally {
|
||||
unlock();
|
||||
}
|
||||
}
|
||||
|
||||
HttpClient put(HttpClient h) {
|
||||
HttpClient staleClient = null;
|
||||
lock();
|
||||
try {
|
||||
HttpClient put(HttpClient h) {
|
||||
assert cacheLock.isHeldByCurrentThread();
|
||||
HttpClient staleClient = null;
|
||||
assert KeepAliveCache.getMaxConnections() > 0;
|
||||
if (size() >= KeepAliveCache.getMaxConnections()) {
|
||||
// remove oldest connection
|
||||
staleClient = removeLast().hc;
|
||||
}
|
||||
addFirst(new KeepAliveEntry(h, System.currentTimeMillis()));
|
||||
} finally {
|
||||
unlock();
|
||||
// close after releasing the locks
|
||||
return staleClient;
|
||||
}
|
||||
// close after releasing the locks
|
||||
return staleClient;
|
||||
}
|
||||
|
||||
final void lock() {
|
||||
lock.lock();
|
||||
}
|
||||
/*
|
||||
* Do not serialize this class!
|
||||
*/
|
||||
@java.io.Serial
|
||||
private void writeObject(ObjectOutputStream stream) throws IOException {
|
||||
throw new NotSerializableException();
|
||||
}
|
||||
|
||||
final void unlock() {
|
||||
lock.unlock();
|
||||
}
|
||||
|
||||
/*
|
||||
* Do not serialize this class!
|
||||
*/
|
||||
@java.io.Serial
|
||||
private void writeObject(ObjectOutputStream stream) throws IOException {
|
||||
throw new NotSerializableException();
|
||||
}
|
||||
|
||||
@java.io.Serial
|
||||
private void readObject(ObjectInputStream stream)
|
||||
throws IOException, ClassNotFoundException
|
||||
{
|
||||
throw new NotSerializableException();
|
||||
@java.io.Serial
|
||||
private void readObject(ObjectInputStream stream)
|
||||
throws IOException, ClassNotFoundException {
|
||||
throw new NotSerializableException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2022, 2023, 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
|
||||
@ -1230,7 +1230,7 @@ public class KeepAliveTest {
|
||||
System.out.println("ProxyHostUsingSystemProperty:" + System.getProperty("http.proxyHost"));
|
||||
System.out.println("http.keepAlive.time.server=" + System.getProperty("http.keepAlive.time.server"));
|
||||
System.out.println("http.keepAlive.time.proxy=" + System.getProperty("http.keepAlive.time.proxy"));
|
||||
Class clientVectorClass = Class.forName("sun.net.www.http.ClientVector");
|
||||
Class clientVectorClass = Class.forName("sun.net.www.http.KeepAliveCache$ClientVector");
|
||||
// System.out.println("clientVectorClass=" + clientVectorClass);
|
||||
Field napField = clientVectorClass.getDeclaredField("nap");
|
||||
napField.setAccessible(true);
|
||||
|
Loading…
x
Reference in New Issue
Block a user