0N/A/*
2362N/A * Copyright (c) 2005, 2008, Oracle and/or its affiliates. All rights reserved.
0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0N/A *
0N/A * This code is free software; you can redistribute it and/or modify it
0N/A * under the terms of the GNU General Public License version 2 only, as
2362N/A * published by the Free Software Foundation. Oracle designates this
0N/A * particular file as subject to the "Classpath" exception as provided
2362N/A * by Oracle in the LICENSE file that accompanied this code.
0N/A *
0N/A * This code is distributed in the hope that it will be useful, but WITHOUT
0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0N/A * version 2 for more details (a copy is included in the LICENSE file that
0N/A * accompanied this code).
0N/A *
0N/A * You should have received a copy of the GNU General Public License version
0N/A * 2 along with this work; if not, write to the Free Software Foundation,
0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0N/A *
2362N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2362N/A * or visit www.oracle.com if you need additional information or have any
2362N/A * questions.
0N/A */
0N/A
0N/Apackage sun.net.www.http;
0N/A
0N/Aimport java.io.IOException;
1676N/Aimport java.util.LinkedList;
0N/Aimport sun.net.NetProperties;
0N/Aimport java.security.AccessController;
0N/Aimport java.security.PrivilegedAction;
0N/A
0N/A/**
0N/A * This class is used to cleanup any remaining data that may be on a KeepAliveStream
0N/A * so that the connection can be cached in the KeepAliveCache.
0N/A * Instances of this class can be used as a FIFO queue for KeepAliveCleanerEntry objects.
0N/A * Executing this Runnable removes each KeepAliveCleanerEntry from the Queue, reads
0N/A * the reamining bytes on its KeepAliveStream, and if successful puts the connection in
0N/A * the KeepAliveCache.
0N/A *
0N/A * @author Chris Hegarty
0N/A */
0N/A
658N/A@SuppressWarnings("serial") // never serialized
1676N/Aclass KeepAliveStreamCleaner
1676N/A extends LinkedList<KeepAliveCleanerEntry>
1676N/A implements Runnable
0N/A{
0N/A // maximum amount of remaining data that we will try to cleanup
0N/A protected static int MAX_DATA_REMAINING = 512;
0N/A
0N/A // maximum amount of KeepAliveStreams to be queued
0N/A protected static int MAX_CAPACITY = 10;
0N/A
0N/A // timeout for both socket and poll on the queue
0N/A protected static final int TIMEOUT = 5000;
0N/A
0N/A // max retries for skipping data
0N/A private static final int MAX_RETRIES = 5;
0N/A
0N/A static {
0N/A final String maxDataKey = "http.KeepAlive.remainingData";
28N/A int maxData = AccessController.doPrivileged(
28N/A new PrivilegedAction<Integer>() {
28N/A public Integer run() {
28N/A return NetProperties.getInteger(maxDataKey, MAX_DATA_REMAINING);
28N/A }}).intValue() * 1024;
0N/A MAX_DATA_REMAINING = maxData;
0N/A
0N/A final String maxCapacityKey = "http.KeepAlive.queuedConnections";
28N/A int maxCapacity = AccessController.doPrivileged(
28N/A new PrivilegedAction<Integer>() {
28N/A public Integer run() {
28N/A return NetProperties.getInteger(maxCapacityKey, MAX_CAPACITY);
28N/A }}).intValue();
0N/A MAX_CAPACITY = maxCapacity;
0N/A
0N/A }
0N/A
0N/A
1676N/A @Override
1676N/A public boolean offer(KeepAliveCleanerEntry e) {
1676N/A if (size() >= MAX_CAPACITY)
1676N/A return false;
1676N/A
1676N/A return super.offer(e);
0N/A }
0N/A
1676N/A @Override
0N/A public void run()
0N/A {
0N/A KeepAliveCleanerEntry kace = null;
0N/A
0N/A do {
0N/A try {
1676N/A synchronized(this) {
1676N/A long before = System.currentTimeMillis();
1676N/A long timeout = TIMEOUT;
1676N/A while ((kace = poll()) == null) {
1676N/A this.wait(timeout);
1676N/A
1676N/A long after = System.currentTimeMillis();
1676N/A long elapsed = after - before;
1676N/A if (elapsed > timeout) {
1676N/A /* one last try */
1676N/A kace = poll();
1676N/A break;
1676N/A }
1676N/A before = after;
1676N/A timeout -= elapsed;
1676N/A }
1676N/A }
1676N/A
0N/A if(kace == null)
0N/A break;
0N/A
0N/A KeepAliveStream kas = kace.getKeepAliveStream();
0N/A
0N/A if (kas != null) {
0N/A synchronized(kas) {
0N/A HttpClient hc = kace.getHttpClient();
0N/A try {
0N/A if (hc != null && !hc.isInKeepAliveCache()) {
1252N/A int oldTimeout = hc.getReadTimeout();
1252N/A hc.setReadTimeout(TIMEOUT);
0N/A long remainingToRead = kas.remainingToRead();
0N/A if (remainingToRead > 0) {
0N/A long n = 0;
0N/A int retries = 0;
0N/A while (n < remainingToRead && retries < MAX_RETRIES) {
0N/A remainingToRead = remainingToRead - n;
0N/A n = kas.skip(remainingToRead);
0N/A if (n == 0)
0N/A retries++;
0N/A }
0N/A remainingToRead = remainingToRead - n;
0N/A }
0N/A if (remainingToRead == 0) {
1252N/A hc.setReadTimeout(oldTimeout);
0N/A hc.finished();
0N/A } else
0N/A hc.closeServer();
0N/A }
0N/A } catch (IOException ioe) {
0N/A hc.closeServer();
0N/A } finally {
0N/A kas.setClosed();
0N/A }
0N/A }
0N/A }
0N/A } catch (InterruptedException ie) { }
0N/A } while (kace != null);
0N/A }
0N/A}