View Javadoc

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