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.annotation.GuardedBy;
42  import org.apache.http.conn.ConnectionPoolTimeoutException;
43  import org.apache.http.conn.OperatedClientConnection;
44  import org.apache.http.conn.routing.HttpRoute;
45  import org.apache.http.impl.conn.IdleConnectionHandler;
46  import org.apache.http.util.Args;
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                 final HttpRoute route,
119                 final Object state,
120                 final long timeout,
121                 final 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(final 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(final long idletime, final TimeUnit tunit) {
161 
162         // idletime can be 0 or negative, no problem there
163         Args.notNull(tunit, "Time unit");
164 
165         poolLock.lock();
166         try {
167             idleConnHandler.closeIdleConnections(tunit.toMillis(idletime));
168         } finally {
169             poolLock.unlock();
170         }
171     }
172 
173     public void closeExpiredConnections() {
174         poolLock.lock();
175         try {
176             idleConnHandler.closeExpiredConnections();
177         } finally {
178             poolLock.unlock();
179         }
180     }
181 
182 
183     /**
184      * Deletes all entries for closed connections.
185      */
186     public abstract void deleteClosedConnections();
187 
188     /**
189      * Shuts down this pool and all associated resources.
190      * Overriding methods MUST call the implementation here!
191      */
192     public void shutdown() {
193 
194         poolLock.lock();
195         try {
196 
197             if (isShutDown) {
198                 return;
199             }
200 
201             // close all connections that are issued to an application
202             final Iterator<BasicPoolEntry> iter = leasedConnections.iterator();
203             while (iter.hasNext()) {
204                 final BasicPoolEntry entry = iter.next();
205                 iter.remove();
206                 closeConnection(entry.getConnection());
207             }
208             idleConnHandler.removeAll();
209 
210             isShutDown = true;
211 
212         } finally {
213             poolLock.unlock();
214         }
215     }
216 
217 
218     /**
219      * Closes a connection from this pool.
220      *
221      * @param conn      the connection to close, or <code>null</code>
222      */
223     protected void closeConnection(final OperatedClientConnection conn) {
224         if (conn != null) {
225             try {
226                 conn.close();
227             } catch (final IOException ex) {
228                 log.debug("I/O error closing connection", ex);
229             }
230         }
231     }
232 
233 } // class AbstractConnPool
234