diff --git a/src/share/classes/sun/net/www/http/KeepAliveCache.java b/src/share/classes/sun/net/www/http/KeepAliveCache.java index 4ec0111651a5e4099607c8ae45526ee9366e3396..5e41c33ae1156ec833ce145bfe13a14ede95994a 100644 --- a/src/share/classes/sun/net/www/http/KeepAliveCache.java +++ b/src/share/classes/sun/net/www/http/KeepAliveCache.java @@ -25,12 +25,11 @@ package sun.net.www.http; -import java.io.InputStream; import java.io.IOException; import java.io.NotSerializableException; -import java.util.*; +import java.util.ArrayList; +import java.util.HashMap; import java.net.URL; -import java.util.concurrent.ConcurrentHashMap; /** * A class that implements a cache of idle Http connections for keep-alive @@ -39,7 +38,7 @@ import java.util.concurrent.ConcurrentHashMap; * @author Dave Brown */ public class KeepAliveCache - extends ConcurrentHashMap + extends HashMap implements Runnable { private static final long serialVersionUID = -2937172892064557949L; @@ -163,8 +162,8 @@ public class KeepAliveCache * Errs on the side of caution (leave connections idle for a relatively * short time). */ + @Override public void run() { - int total_cache; do { try { Thread.sleep(LIFETIME); @@ -311,6 +310,7 @@ class KeepAliveKey { /** * Determine whether or not two objects of this type are equal */ + @Override public boolean equals(Object obj) { if ((obj instanceof KeepAliveKey) == false) return false; @@ -325,6 +325,7 @@ class KeepAliveKey { * The hashCode() for this object is the string hashCode() of * concatenation of the protocol, host name and port. */ + @Override public int hashCode() { String str = protocol+host+port; return this.obj == null? str.hashCode() : diff --git a/src/share/classes/sun/net/www/http/KeepAliveStream.java b/src/share/classes/sun/net/www/http/KeepAliveStream.java index 3a64c465e54d3fee2a86e405d112eccbc1155b60..ff5ffada90762a92940dd33555bfc439dfd36fd4 100644 --- a/src/share/classes/sun/net/www/http/KeepAliveStream.java +++ b/src/share/classes/sun/net/www/http/KeepAliveStream.java @@ -25,10 +25,7 @@ package sun.net.www.http; -import java.net.URL; -import java.net.HttpURLConnection; import java.io.*; -import java.util.StringTokenizer; import sun.net.ProgressSource; import sun.net.www.MeteredStream; @@ -50,9 +47,8 @@ class KeepAliveStream extends MeteredStream implements Hurryable { // has this KeepAliveStream been put on the queue for asynchronous cleanup. protected boolean queuedForCleanup = false; - private static KeepAliveStreamCleaner queue = new KeepAliveStreamCleaner(); - private static Thread cleanerThread = null; - private static boolean startCleanupThread; + private static final KeepAliveStreamCleaner queue = new KeepAliveStreamCleaner(); + private static Thread cleanerThread; // null /** * Constructor @@ -155,43 +151,46 @@ class KeepAliveStream extends MeteredStream implements Hurryable { } } - private static synchronized void queueForCleanup(KeepAliveCleanerEntry kace) { - if(queue != null && !kace.getQueuedForCleanup()) { - if (!queue.offer(kace)) { - kace.getHttpClient().closeServer(); - return; - } + private static void queueForCleanup(KeepAliveCleanerEntry kace) { + synchronized(queue) { + if(!kace.getQueuedForCleanup()) { + if (!queue.offer(kace)) { + kace.getHttpClient().closeServer(); + return; + } - kace.setQueuedForCleanup(); - } + kace.setQueuedForCleanup(); + queue.notifyAll(); + } - startCleanupThread = (cleanerThread == null); - if (!startCleanupThread) { - if (!cleanerThread.isAlive()) { - startCleanupThread = true; + boolean startCleanupThread = (cleanerThread == null); + if (!startCleanupThread) { + if (!cleanerThread.isAlive()) { + startCleanupThread = true; + } } - } - if (startCleanupThread) { - java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { - public Void run() { - // We want to create the Keep-Alive-SocketCleaner in the - // system threadgroup - ThreadGroup grp = Thread.currentThread().getThreadGroup(); - ThreadGroup parent = null; - while ((parent = grp.getParent()) != null) { - grp = parent; + if (startCleanupThread) { + java.security.AccessController.doPrivileged( + new java.security.PrivilegedAction() { + public Void run() { + // We want to create the Keep-Alive-SocketCleaner in the + // system threadgroup + ThreadGroup grp = Thread.currentThread().getThreadGroup(); + ThreadGroup parent = null; + while ((parent = grp.getParent()) != null) { + grp = parent; + } + + cleanerThread = new Thread(grp, queue, "Keep-Alive-SocketCleaner"); + cleanerThread.setDaemon(true); + cleanerThread.setPriority(Thread.MAX_PRIORITY - 2); + cleanerThread.start(); + return null; } - - cleanerThread = new Thread(grp, queue, "Keep-Alive-SocketCleaner"); - cleanerThread.setDaemon(true); - cleanerThread.setPriority(Thread.MAX_PRIORITY - 2); - cleanerThread.start(); - return null; - } - }); - } + }); + } + } // queue } protected long remainingToRead() { diff --git a/src/share/classes/sun/net/www/http/KeepAliveStreamCleaner.java b/src/share/classes/sun/net/www/http/KeepAliveStreamCleaner.java index 0b19b6bb88db8839f345c2da36975c3183e3b4a0..6bb28d68d9cb4b2c9539c74548b33a6462feacb2 100644 --- a/src/share/classes/sun/net/www/http/KeepAliveStreamCleaner.java +++ b/src/share/classes/sun/net/www/http/KeepAliveStreamCleaner.java @@ -25,9 +25,8 @@ package sun.net.www.http; -import java.util.concurrent.LinkedBlockingQueue; -import java.util.concurrent.TimeUnit; import java.io.IOException; +import java.util.LinkedList; import sun.net.NetProperties; import java.security.AccessController; import java.security.PrivilegedAction; @@ -44,7 +43,9 @@ import java.security.PrivilegedAction; */ @SuppressWarnings("serial") // never serialized -public class KeepAliveStreamCleaner extends LinkedBlockingQueue implements Runnable +class KeepAliveStreamCleaner + extends LinkedList + implements Runnable { // maximum amount of remaining data that we will try to cleanup protected static int MAX_DATA_REMAINING = 512; @@ -78,23 +79,39 @@ public class KeepAliveStreamCleaner extends LinkedBlockingQueue= MAX_CAPACITY) + return false; - public KeepAliveStreamCleaner(int capacity) - { - super(capacity); + return super.offer(e); } + @Override public void run() { KeepAliveCleanerEntry kace = null; do { try { - kace = poll((long)TIMEOUT, TimeUnit.MILLISECONDS); + synchronized(this) { + long before = System.currentTimeMillis(); + long timeout = TIMEOUT; + while ((kace = poll()) == null) { + this.wait(timeout); + + long after = System.currentTimeMillis(); + long elapsed = after - before; + if (elapsed > timeout) { + /* one last try */ + kace = poll(); + break; + } + before = after; + timeout -= elapsed; + } + } + if(kace == null) break;