< prev index next >

src/java.base/share/classes/sun/net/www/http/KeepAliveCache.java

Print this page




  32 import java.net.URL;
  33 import java.security.AccessController;
  34 import java.security.PrivilegedAction;
  35 import java.util.ArrayDeque;
  36 import java.util.ArrayList;
  37 import java.util.HashMap;
  38 import java.util.List;
  39 
  40 import jdk.internal.misc.InnocuousThread;
  41 import sun.security.action.GetIntegerAction;
  42 
  43 /**
  44  * A class that implements a cache of idle Http connections for keep-alive
  45  *
  46  * @author Stephen R. Pietrowicz (NCSA)
  47  * @author Dave Brown
  48  */
  49 public class KeepAliveCache
  50     extends HashMap<KeepAliveKey, ClientVector>
  51     implements Runnable {

  52     private static final long serialVersionUID = -2937172892064557949L;
  53 
  54     /* maximum # keep-alive connections to maintain at once
  55      * This should be 2 by the HTTP spec, but because we don't support pipe-lining
  56      * a larger value is more appropriate. So we now set a default of 5, and the value
  57      * refers to the number of idle connections per destination (in the cache) only.
  58      * It can be reset by setting system property "http.maxConnections".
  59      */
  60     static final int MAX_CONNECTIONS = 5;
  61     static int result = -1;
  62     static int getMaxConnections() {
  63         if (result == -1) {
  64             result = AccessController.doPrivileged(
  65                 new GetIntegerAction("http.maxConnections", MAX_CONNECTIONS))
  66                 .intValue();
  67             if (result <= 0) {
  68                 result = MAX_CONNECTIONS;
  69             }
  70         }
  71         return result;


 186                             }
 187                             e = v.peek();
 188                         }
 189 
 190                         if (v.isEmpty()) {
 191                             keysToRemove.add(key);
 192                         }
 193                     }
 194                 }
 195 
 196                 for (KeepAliveKey key : keysToRemove) {
 197                     removeVector(key);
 198                 }
 199             }
 200         } while (!isEmpty());
 201     }
 202 
 203     /*
 204      * Do not serialize this class!
 205      */

 206     private void writeObject(ObjectOutputStream stream) throws IOException {
 207         throw new NotSerializableException();
 208     }
 209 

 210     private void readObject(ObjectInputStream stream)
 211         throws IOException, ClassNotFoundException
 212     {
 213         throw new NotSerializableException();
 214     }
 215 }
 216 
 217 /* FILO order for recycling HttpClients, should run in a thread
 218  * to time them out.  If > maxConns are in use, block.
 219  */
 220 class ClientVector extends ArrayDeque<KeepAliveEntry> {

 221     private static final long serialVersionUID = -8680532108106489459L;
 222 
 223     // sleep time in milliseconds, before cache clear
 224     int nap;
 225 
 226     ClientVector(int nap) {
 227         this.nap = nap;
 228     }
 229 
 230     synchronized HttpClient get() {
 231         if (isEmpty()) {
 232             return null;
 233         }
 234 
 235         // Loop until we find a connection that has not timed out
 236         HttpClient hc = null;
 237         long currentTime = System.currentTimeMillis();
 238         do {
 239             KeepAliveEntry e = pop();
 240             if ((currentTime - e.idleStartTime) > nap) {


 251         if (size() >= KeepAliveCache.getMaxConnections()) {
 252             h.closeServer(); // otherwise the connection remains in limbo
 253         } else {
 254             push(new KeepAliveEntry(h, System.currentTimeMillis()));
 255         }
 256     }
 257 
 258     /* remove an HttpClient */
 259     synchronized boolean remove(HttpClient h) {
 260         for (KeepAliveEntry curr : this) {
 261             if (curr.hc == h) {
 262                 return super.remove(curr);
 263             }
 264         }
 265         return false;
 266     }
 267 
 268     /*
 269      * Do not serialize this class!
 270      */

 271     private void writeObject(ObjectOutputStream stream) throws IOException {
 272         throw new NotSerializableException();
 273     }
 274 

 275     private void readObject(ObjectInputStream stream)
 276         throws IOException, ClassNotFoundException
 277     {
 278         throw new NotSerializableException();
 279     }
 280 }
 281 
 282 class KeepAliveKey {
 283     private String      protocol = null;
 284     private String      host = null;
 285     private int         port = 0;
 286     private Object      obj = null; // additional key, such as socketfactory
 287 
 288     /**
 289      * Constructor
 290      *
 291      * @param url the URL containing the protocol, host and port information
 292      */
 293     public KeepAliveKey(URL url, Object obj) {
 294         this.protocol = url.getProtocol();




  32 import java.net.URL;
  33 import java.security.AccessController;
  34 import java.security.PrivilegedAction;
  35 import java.util.ArrayDeque;
  36 import java.util.ArrayList;
  37 import java.util.HashMap;
  38 import java.util.List;
  39 
  40 import jdk.internal.misc.InnocuousThread;
  41 import sun.security.action.GetIntegerAction;
  42 
  43 /**
  44  * A class that implements a cache of idle Http connections for keep-alive
  45  *
  46  * @author Stephen R. Pietrowicz (NCSA)
  47  * @author Dave Brown
  48  */
  49 public class KeepAliveCache
  50     extends HashMap<KeepAliveKey, ClientVector>
  51     implements Runnable {
  52     @java.io.Serial
  53     private static final long serialVersionUID = -2937172892064557949L;
  54 
  55     /* maximum # keep-alive connections to maintain at once
  56      * This should be 2 by the HTTP spec, but because we don't support pipe-lining
  57      * a larger value is more appropriate. So we now set a default of 5, and the value
  58      * refers to the number of idle connections per destination (in the cache) only.
  59      * It can be reset by setting system property "http.maxConnections".
  60      */
  61     static final int MAX_CONNECTIONS = 5;
  62     static int result = -1;
  63     static int getMaxConnections() {
  64         if (result == -1) {
  65             result = AccessController.doPrivileged(
  66                 new GetIntegerAction("http.maxConnections", MAX_CONNECTIONS))
  67                 .intValue();
  68             if (result <= 0) {
  69                 result = MAX_CONNECTIONS;
  70             }
  71         }
  72         return result;


 187                             }
 188                             e = v.peek();
 189                         }
 190 
 191                         if (v.isEmpty()) {
 192                             keysToRemove.add(key);
 193                         }
 194                     }
 195                 }
 196 
 197                 for (KeepAliveKey key : keysToRemove) {
 198                     removeVector(key);
 199                 }
 200             }
 201         } while (!isEmpty());
 202     }
 203 
 204     /*
 205      * Do not serialize this class!
 206      */
 207     @java.io.Serial
 208     private void writeObject(ObjectOutputStream stream) throws IOException {
 209         throw new NotSerializableException();
 210     }
 211 
 212     @java.io.Serial
 213     private void readObject(ObjectInputStream stream)
 214         throws IOException, ClassNotFoundException
 215     {
 216         throw new NotSerializableException();
 217     }
 218 }
 219 
 220 /* FILO order for recycling HttpClients, should run in a thread
 221  * to time them out.  If > maxConns are in use, block.
 222  */
 223 class ClientVector extends ArrayDeque<KeepAliveEntry> {
 224     @java.io.Serial
 225     private static final long serialVersionUID = -8680532108106489459L;
 226 
 227     // sleep time in milliseconds, before cache clear
 228     int nap;
 229 
 230     ClientVector(int nap) {
 231         this.nap = nap;
 232     }
 233 
 234     synchronized HttpClient get() {
 235         if (isEmpty()) {
 236             return null;
 237         }
 238 
 239         // Loop until we find a connection that has not timed out
 240         HttpClient hc = null;
 241         long currentTime = System.currentTimeMillis();
 242         do {
 243             KeepAliveEntry e = pop();
 244             if ((currentTime - e.idleStartTime) > nap) {


 255         if (size() >= KeepAliveCache.getMaxConnections()) {
 256             h.closeServer(); // otherwise the connection remains in limbo
 257         } else {
 258             push(new KeepAliveEntry(h, System.currentTimeMillis()));
 259         }
 260     }
 261 
 262     /* remove an HttpClient */
 263     synchronized boolean remove(HttpClient h) {
 264         for (KeepAliveEntry curr : this) {
 265             if (curr.hc == h) {
 266                 return super.remove(curr);
 267             }
 268         }
 269         return false;
 270     }
 271 
 272     /*
 273      * Do not serialize this class!
 274      */
 275     @java.io.Serial
 276     private void writeObject(ObjectOutputStream stream) throws IOException {
 277         throw new NotSerializableException();
 278     }
 279 
 280     @java.io.Serial
 281     private void readObject(ObjectInputStream stream)
 282         throws IOException, ClassNotFoundException
 283     {
 284         throw new NotSerializableException();
 285     }
 286 }
 287 
 288 class KeepAliveKey {
 289     private String      protocol = null;
 290     private String      host = null;
 291     private int         port = 0;
 292     private Object      obj = null; // additional key, such as socketfactory
 293 
 294     /**
 295      * Constructor
 296      *
 297      * @param url the URL containing the protocol, host and port information
 298      */
 299     public KeepAliveKey(URL url, Object obj) {
 300         this.protocol = url.getProtocol();


< prev index next >