diff options
author | Matt A. Tobin <mattatobin@localhost.localdomain> | 2018-02-02 04:16:08 -0500 |
---|---|---|
committer | Matt A. Tobin <mattatobin@localhost.localdomain> | 2018-02-02 04:16:08 -0500 |
commit | 5f8de423f190bbb79a62f804151bc24824fa32d8 (patch) | |
tree | 10027f336435511475e392454359edea8e25895d /mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/conn/SingleClientConnManager.java | |
parent | 49ee0794b5d912db1f95dce6eb52d781dc210db5 (diff) | |
download | UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.gz UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.lz UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.xz UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.zip |
Add m-esr52 at 52.6.0
Diffstat (limited to 'mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/conn/SingleClientConnManager.java')
-rw-r--r-- | mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/conn/SingleClientConnManager.java | 427 |
1 files changed, 427 insertions, 0 deletions
diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/conn/SingleClientConnManager.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/conn/SingleClientConnManager.java new file mode 100644 index 000000000..c2b6c8799 --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/conn/SingleClientConnManager.java @@ -0,0 +1,427 @@ +/* + * ==================================================================== + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * <http://www.apache.org/>. + * + */ + +package ch.boye.httpclientandroidlib.impl.conn; + +import java.io.IOException; +import java.util.concurrent.TimeUnit; + +import ch.boye.httpclientandroidlib.androidextra.HttpClientAndroidLog; +/* LogFactory removed by HttpClient for Android script. */ +import ch.boye.httpclientandroidlib.annotation.GuardedBy; +import ch.boye.httpclientandroidlib.annotation.ThreadSafe; +import ch.boye.httpclientandroidlib.conn.ClientConnectionManager; +import ch.boye.httpclientandroidlib.conn.ClientConnectionOperator; +import ch.boye.httpclientandroidlib.conn.ClientConnectionRequest; +import ch.boye.httpclientandroidlib.conn.ManagedClientConnection; +import ch.boye.httpclientandroidlib.conn.routing.HttpRoute; +import ch.boye.httpclientandroidlib.conn.routing.RouteTracker; +import ch.boye.httpclientandroidlib.conn.scheme.SchemeRegistry; +import ch.boye.httpclientandroidlib.params.HttpParams; +import ch.boye.httpclientandroidlib.util.Args; +import ch.boye.httpclientandroidlib.util.Asserts; + +/** + * A connection manager for a single connection. This connection manager + * maintains only one active connection at a time. Even though this class + * is thread-safe it ought to be used by one execution thread only. + * <p> + * SingleClientConnManager will make an effort to reuse the connection + * for subsequent requests with the same {@link HttpRoute route}. + * It will, however, close the existing connection and open it + * for the given route, if the route of the persistent connection does + * not match that of the connection request. If the connection has been + * already been allocated {@link IllegalStateException} is thrown. + * + * @since 4.0 + * + * @deprecated (4.2) use {@link BasicClientConnectionManager} + */ +@ThreadSafe +@Deprecated +public class SingleClientConnManager implements ClientConnectionManager { + + public HttpClientAndroidLog log = new HttpClientAndroidLog(getClass()); + + /** The message to be logged on multiple allocation. */ + public final static String MISUSE_MESSAGE = + "Invalid use of SingleClientConnManager: connection still allocated.\n" + + "Make sure to release the connection before allocating another one."; + + /** The schemes supported by this connection manager. */ + protected final SchemeRegistry schemeRegistry; + + /** The operator for opening and updating connections. */ + protected final ClientConnectionOperator connOperator; + + /** Whether the connection should be shut down on release. */ + protected final boolean alwaysShutDown; + + /** The one and only entry in this pool. */ + @GuardedBy("this") + protected volatile PoolEntry uniquePoolEntry; + + /** The currently issued managed connection, if any. */ + @GuardedBy("this") + protected volatile ConnAdapter managedConn; + + /** The time of the last connection release, or -1. */ + @GuardedBy("this") + protected volatile long lastReleaseTime; + + /** The time the last released connection expires and shouldn't be reused. */ + @GuardedBy("this") + protected volatile long connectionExpiresTime; + + /** Indicates whether this connection manager is shut down. */ + protected volatile boolean isShutDown; + + /** + * Creates a new simple connection manager. + * + * @param params the parameters for this manager + * @param schreg the scheme registry + * + * @deprecated (4.1) use {@link SingleClientConnManager#SingleClientConnManager(SchemeRegistry)} + */ + @Deprecated + public SingleClientConnManager(final HttpParams params, + final SchemeRegistry schreg) { + this(schreg); + } + /** + * Creates a new simple connection manager. + * + * @param schreg the scheme registry + */ + public SingleClientConnManager(final SchemeRegistry schreg) { + Args.notNull(schreg, "Scheme registry"); + this.schemeRegistry = schreg; + this.connOperator = createConnectionOperator(schreg); + this.uniquePoolEntry = new PoolEntry(); + this.managedConn = null; + this.lastReleaseTime = -1L; + this.alwaysShutDown = false; //@@@ from params? as argument? + this.isShutDown = false; + } + + /** + * @since 4.1 + */ + public SingleClientConnManager() { + this(SchemeRegistryFactory.createDefault()); + } + + @Override + protected void finalize() throws Throwable { + try { + shutdown(); + } finally { // Make sure we call overridden method even if shutdown barfs + super.finalize(); + } + } + + public SchemeRegistry getSchemeRegistry() { + return this.schemeRegistry; + } + + /** + * Hook for creating the connection operator. + * It is called by the constructor. + * Derived classes can override this method to change the + * instantiation of the operator. + * The default implementation here instantiates + * {@link DefaultClientConnectionOperator DefaultClientConnectionOperator}. + * + * @param schreg the scheme registry to use, or <code>null</code> + * + * @return the connection operator to use + */ + protected ClientConnectionOperator + createConnectionOperator(final SchemeRegistry schreg) { + return new DefaultClientConnectionOperator(schreg); + } + + /** + * Asserts that this manager is not shut down. + * + * @throws IllegalStateException if this manager is shut down + */ + protected final void assertStillUp() throws IllegalStateException { + Asserts.check(!this.isShutDown, "Manager is shut down"); + } + + public final ClientConnectionRequest requestConnection( + final HttpRoute route, + final Object state) { + + return new ClientConnectionRequest() { + + public void abortRequest() { + // Nothing to abort, since requests are immediate. + } + + public ManagedClientConnection getConnection( + final long timeout, final TimeUnit tunit) { + return SingleClientConnManager.this.getConnection( + route, state); + } + + }; + } + + /** + * Obtains a connection. + * + * @param route where the connection should point to + * + * @return a connection that can be used to communicate + * along the given route + */ + public ManagedClientConnection getConnection(final HttpRoute route, final Object state) { + Args.notNull(route, "Route"); + assertStillUp(); + + if (log.isDebugEnabled()) { + log.debug("Get connection for route " + route); + } + + synchronized (this) { + + Asserts.check(managedConn == null, MISUSE_MESSAGE); + + // check re-usability of the connection + boolean recreate = false; + boolean shutdown = false; + + // Kill the connection if it expired. + closeExpiredConnections(); + + if (uniquePoolEntry.connection.isOpen()) { + final RouteTracker tracker = uniquePoolEntry.tracker; + shutdown = (tracker == null || // can happen if method is aborted + !tracker.toRoute().equals(route)); + } else { + // If the connection is not open, create a new PoolEntry, + // as the connection may have been marked not reusable, + // due to aborts -- and the PoolEntry should not be reused + // either. There's no harm in recreating an entry if + // the connection is closed. + recreate = true; + } + + if (shutdown) { + recreate = true; + try { + uniquePoolEntry.shutdown(); + } catch (final IOException iox) { + log.debug("Problem shutting down connection.", iox); + } + } + + if (recreate) { + uniquePoolEntry = new PoolEntry(); + } + + managedConn = new ConnAdapter(uniquePoolEntry, route); + + return managedConn; + } + } + + public void releaseConnection( + final ManagedClientConnection conn, + final long validDuration, final TimeUnit timeUnit) { + Args.check(conn instanceof ConnAdapter, "Connection class mismatch, " + + "connection not obtained from this manager"); + assertStillUp(); + + if (log.isDebugEnabled()) { + log.debug("Releasing connection " + conn); + } + + final ConnAdapter sca = (ConnAdapter) conn; + synchronized (sca) { + if (sca.poolEntry == null) + { + return; // already released + } + final ClientConnectionManager manager = sca.getManager(); + Asserts.check(manager == this, "Connection not obtained from this manager"); + try { + // make sure that the response has been read completely + if (sca.isOpen() && (this.alwaysShutDown || + !sca.isMarkedReusable()) + ) { + if (log.isDebugEnabled()) { + log.debug + ("Released connection open but not reusable."); + } + + // make sure this connection will not be re-used + // we might have gotten here because of a shutdown trigger + // shutdown of the adapter also clears the tracked route + sca.shutdown(); + } + } catch (final IOException iox) { + if (log.isDebugEnabled()) { + log.debug("Exception shutting down released connection.", + iox); + } + } finally { + sca.detach(); + synchronized (this) { + managedConn = null; + lastReleaseTime = System.currentTimeMillis(); + if(validDuration > 0) { + connectionExpiresTime = timeUnit.toMillis(validDuration) + lastReleaseTime; + } else { + connectionExpiresTime = Long.MAX_VALUE; + } + } + } + } + } + + public void closeExpiredConnections() { + final long time = connectionExpiresTime; + if (System.currentTimeMillis() >= time) { + closeIdleConnections(0, TimeUnit.MILLISECONDS); + } + } + + public void closeIdleConnections(final long idletime, final TimeUnit tunit) { + assertStillUp(); + + // idletime can be 0 or negative, no problem there + Args.notNull(tunit, "Time unit"); + + synchronized (this) { + if ((managedConn == null) && uniquePoolEntry.connection.isOpen()) { + final long cutoff = + System.currentTimeMillis() - tunit.toMillis(idletime); + if (lastReleaseTime <= cutoff) { + try { + uniquePoolEntry.close(); + } catch (final IOException iox) { + // ignore + log.debug("Problem closing idle connection.", iox); + } + } + } + } + } + + public void shutdown() { + this.isShutDown = true; + synchronized (this) { + try { + if (uniquePoolEntry != null) { + uniquePoolEntry.shutdown(); + } + } catch (final IOException iox) { + // ignore + log.debug("Problem while shutting down manager.", iox); + } finally { + uniquePoolEntry = null; + managedConn = null; + } + } + } + + protected void revokeConnection() { + final ConnAdapter conn = managedConn; + if (conn == null) { + return; + } + conn.detach(); + + synchronized (this) { + try { + uniquePoolEntry.shutdown(); + } catch (final IOException iox) { + // ignore + log.debug("Problem while shutting down connection.", iox); + } + } + } + + /** + * The pool entry for this connection manager. + */ + protected class PoolEntry extends AbstractPoolEntry { + + /** + * Creates a new pool entry. + * + */ + protected PoolEntry() { + super(SingleClientConnManager.this.connOperator, null); + } + + /** + * Closes the connection in this pool entry. + */ + protected void close() throws IOException { + shutdownEntry(); + if (connection.isOpen()) { + connection.close(); + } + } + + /** + * Shuts down the connection in this pool entry. + */ + protected void shutdown() throws IOException { + shutdownEntry(); + if (connection.isOpen()) { + connection.shutdown(); + } + } + + } + + /** + * The connection adapter used by this manager. + */ + protected class ConnAdapter extends AbstractPooledConnAdapter { + + /** + * Creates a new connection adapter. + * + * @param entry the pool entry for the connection being wrapped + * @param route the planned route for this connection + */ + protected ConnAdapter(final PoolEntry entry, final HttpRoute route) { + super(SingleClientConnManager.this, entry); + markReusable(); + entry.route = route; + } + + } + +} |