View Javadoc
1   /*
2    * ====================================================================
3    * Licensed to the Apache Software Foundation (ASF) under one
4    * or more contributor license agreements.  See the NOTICE file
5    * distributed with this work for additional information
6    * regarding copyright ownership.  The ASF licenses this file
7    * to you under the Apache License, Version 2.0 (the
8    * "License"); you may not use this file except in compliance
9    * with the License.  You may obtain a copy of the License at
10   *
11   *   http://www.apache.org/licenses/LICENSE-2.0
12   *
13   * Unless required by applicable law or agreed to in writing,
14   * software distributed under the License is distributed on an
15   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16   * KIND, either express or implied.  See the License for the
17   * specific language governing permissions and limitations
18   * under the License.
19   * ====================================================================
20   *
21   * This software consists of voluntary contributions made by many
22   * individuals on behalf of the Apache Software Foundation.  For more
23   * information on the Apache Software Foundation, please see
24   * <http://www.apache.org/>.
25   *
26   */
27  package org.apache.http.impl.conn.tsccm;
28  
29  import java.io.IOException;
30  import java.lang.ref.Reference;
31  import java.lang.ref.ReferenceQueue;
32  import java.util.HashSet;
33  import java.util.Iterator;
34  import java.util.Set;
35  import java.util.concurrent.TimeUnit;
36  import java.util.concurrent.locks.Lock;
37  import java.util.concurrent.locks.ReentrantLock;
38  
39  import org.apache.commons.logging.Log;
40  import org.apache.commons.logging.LogFactory;
41  import org.apache.http.conn.ConnectionPoolTimeoutException;
42  import org.apache.http.conn.OperatedClientConnection;
43  import org.apache.http.conn.routing.HttpRoute;
44  import org.apache.http.impl.conn.IdleConnectionHandler;
45  import org.apache.http.util.Args;
46  
47  /**
48   * An abstract connection pool.
49   * It is used by the {@link ThreadSafeClientConnManager}.
50   * The abstract pool includes a {@link #poolLock}, which is used to
51   * synchronize access to the internal pool datastructures.
52   * Don't use {@code synchronized} for that purpose!
53   *
54   * @since 4.0
55   *
56   * @deprecated (4.2) use {@link org.apache.http.pool.AbstractConnPool}
57   */
58  @Deprecated
59  public abstract class AbstractConnPool {
60  
61      private final Log log;
62  
63      /**
64       * The global lock for this pool.
65       */
66      protected final Lock poolLock;
67  
68      protected Set<BasicPoolEntry> leasedConnections;
69  
70      protected int numConnections;
71  
72      /** Indicates whether this pool is shut down. */
73      protected volatile boolean isShutDown;
74  
75      protected Set<BasicPoolEntryRef> issuedConnections;
76  
77      protected ReferenceQueue<Object> refQueue;
78  
79      protected IdleConnectionHandler idleConnHandler;
80  
81      /**
82       * Creates a new connection pool.
83       */
84      protected AbstractConnPool() {
85          super();
86          this.log = LogFactory.getLog(getClass());
87          this.leasedConnections = new HashSet<BasicPoolEntry>();
88          this.idleConnHandler = new IdleConnectionHandler();
89          this.poolLock = new ReentrantLock();
90      }
91  
92      public void enableConnectionGC()
93          throws IllegalStateException {
94      }
95  
96      /**
97       * Obtains a pool entry with a connection within the given timeout.
98       *
99       * @param route     the route for which to get the connection
100      * @param state     the state
101      * @param timeout   the timeout, 0 or negative for no timeout
102      * @param timeUnit     the unit for the {@code timeout},
103      *                  may be {@code null} only if there is no timeout
104      *
105      * @return  pool entry holding a connection for the route
106      *
107      * @throws ConnectionPoolTimeoutException
108      *         if the timeout expired
109      * @throws InterruptedException
110      *         if the calling thread was interrupted
111      */
112     public final
113         BasicPoolEntry getEntry(
114                 final HttpRoute route,
115                 final Object state,
116                 final long timeout,
117                 final TimeUnit timeUnit)
118                     throws ConnectionPoolTimeoutException, InterruptedException {
119         return requestPoolEntry(route, state).getPoolEntry(timeout, timeUnit);
120     }
121 
122     /**
123      * Returns a new {@link PoolEntryRequest}, from which a {@link BasicPoolEntry}
124      * can be obtained, or the request can be aborted.
125      * @param route the route
126      * @param state the state
127      * @return the entry request
128      */
129     public abstract PoolEntryRequest requestPoolEntry(HttpRoute route, Object state);
130 
131 
132     /**
133      * Returns an entry into the pool.
134      * The connection of the entry is expected to be in a suitable state,
135      * either open and re-usable, or closed. The pool will not make any
136      * attempt to determine whether it can be re-used or not.
137      *
138      * @param entry     the entry for the connection to release
139      * @param reusable  {@code true} if the entry is deemed
140      *                  reusable, {@code false} otherwise.
141      * @param validDuration The duration that the entry should remain free and reusable.
142      * @param timeUnit The unit of time the duration is measured in.
143      */
144     public abstract void freeEntry(BasicPoolEntry entry, boolean reusable, long validDuration, TimeUnit timeUnit)
145         ;
146 
147     public void handleReference(final Reference<?> ref) {
148     }
149 
150     protected abstract void handleLostEntry(HttpRoute route);
151 
152     /**
153      * Closes idle connections.
154      *
155      * @param idletime  the time the connections should have been idle
156      *                  in order to be closed now
157      * @param timeUnit     the unit for the {@code idletime}
158      */
159     public void closeIdleConnections(final long idletime, final TimeUnit timeUnit) {
160 
161         // idletime can be 0 or negative, no problem there
162         Args.notNull(timeUnit, "Time unit");
163 
164         poolLock.lock();
165         try {
166             idleConnHandler.closeIdleConnections(timeUnit.toMillis(idletime));
167         } finally {
168             poolLock.unlock();
169         }
170     }
171 
172     public void closeExpiredConnections() {
173         poolLock.lock();
174         try {
175             idleConnHandler.closeExpiredConnections();
176         } finally {
177             poolLock.unlock();
178         }
179     }
180 
181 
182     /**
183      * Deletes all entries for closed connections.
184      */
185     public abstract void deleteClosedConnections();
186 
187     /**
188      * Shuts down this pool and all associated resources.
189      * Overriding methods MUST call the implementation here!
190      */
191     public void shutdown() {
192 
193         poolLock.lock();
194         try {
195 
196             if (isShutDown) {
197                 return;
198             }
199 
200             // close all connections that are issued to an application
201             final Iterator<BasicPoolEntry> iter = leasedConnections.iterator();
202             while (iter.hasNext()) {
203                 final BasicPoolEntry entry = iter.next();
204                 iter.remove();
205                 closeConnection(entry.getConnection());
206             }
207             idleConnHandler.removeAll();
208 
209             isShutDown = true;
210 
211         } finally {
212             poolLock.unlock();
213         }
214     }
215 
216 
217     /**
218      * Closes a connection from this pool.
219      *
220      * @param conn      the connection to close, or {@code null}
221      */
222     protected void closeConnection(final OperatedClientConnection conn) {
223         if (conn != null) {
224             try {
225                 conn.close();
226             } catch (final IOException ex) {
227                 log.debug("I/O error closing connection", ex);
228             }
229         }
230     }
231 
232 } // class AbstractConnPool
233