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} 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 state     the state
106      * @param timeout   the timeout, 0 or negative for no timeout
107      * @param tunit     the unit for the {@code timeout},
108      *                  may be {@code null} only if there is no timeout
109      *
110      * @return  pool entry holding a connection for the route
111      *
112      * @throws ConnectionPoolTimeoutException
113      *         if the timeout expired
114      * @throws InterruptedException
115      *         if the calling thread was interrupted
116      */
117     public final
118         BasicPoolEntry getEntry(
119                 final HttpRoute route,
120                 final Object state,
121                 final long timeout,
122                 final TimeUnit tunit)
123                     throws ConnectionPoolTimeoutException, InterruptedException {
124         return requestPoolEntry(route, state).getPoolEntry(timeout, tunit);
125     }
126 
127     /**
128      * Returns a new {@link PoolEntryRequest}, from which a {@link BasicPoolEntry}
129      * can be obtained, or the request can be aborted.
130      * @param route the route
131      * @param state the state
132      * @return the entry request
133      */
134     public abstract PoolEntryRequest requestPoolEntry(HttpRoute route, Object state);
135 
136 
137     /**
138      * Returns an entry into the pool.
139      * The connection of the entry is expected to be in a suitable state,
140      * either open and re-usable, or closed. The pool will not make any
141      * attempt to determine whether it can be re-used or not.
142      *
143      * @param entry     the entry for the connection to release
144      * @param reusable  {@code true} if the entry is deemed
145      *                  reusable, {@code false} otherwise.
146      * @param validDuration The duration that the entry should remain free and reusable.
147      * @param timeUnit The unit of time the duration is measured in.
148      */
149     public abstract void freeEntry(BasicPoolEntry entry, boolean reusable, long validDuration, TimeUnit timeUnit)
150         ;
151 
152     public void handleReference(final Reference<?> ref) {
153     }
154 
155     protected abstract void handleLostEntry(HttpRoute route);
156 
157     /**
158      * Closes idle connections.
159      *
160      * @param idletime  the time the connections should have been idle
161      *                  in order to be closed now
162      * @param tunit     the unit for the {@code idletime}
163      */
164     public void closeIdleConnections(final long idletime, final TimeUnit tunit) {
165 
166         // idletime can be 0 or negative, no problem there
167         Args.notNull(tunit, "Time unit");
168 
169         poolLock.lock();
170         try {
171             idleConnHandler.closeIdleConnections(tunit.toMillis(idletime));
172         } finally {
173             poolLock.unlock();
174         }
175     }
176 
177     public void closeExpiredConnections() {
178         poolLock.lock();
179         try {
180             idleConnHandler.closeExpiredConnections();
181         } finally {
182             poolLock.unlock();
183         }
184     }
185 
186 
187     /**
188      * Deletes all entries for closed connections.
189      */
190     public abstract void deleteClosedConnections();
191 
192     /**
193      * Shuts down this pool and all associated resources.
194      * Overriding methods MUST call the implementation here!
195      */
196     public void shutdown() {
197 
198         poolLock.lock();
199         try {
200 
201             if (isShutDown) {
202                 return;
203             }
204 
205             // close all connections that are issued to an application
206             final Iterator<BasicPoolEntry> iter = leasedConnections.iterator();
207             while (iter.hasNext()) {
208                 final BasicPoolEntry entry = iter.next();
209                 iter.remove();
210                 closeConnection(entry.getConnection());
211             }
212             idleConnHandler.removeAll();
213 
214             isShutDown = true;
215 
216         } finally {
217             poolLock.unlock();
218         }
219     }
220 
221 
222     /**
223      * Closes a connection from this pool.
224      *
225      * @param conn      the connection to close, or {@code null}
226      */
227     protected void closeConnection(final OperatedClientConnection conn) {
228         if (conn != null) {
229             try {
230                 conn.close();
231             } catch (final IOException ex) {
232                 log.debug("I/O error closing connection", ex);
233             }
234         }
235     }
236 
237 } // class AbstractConnPool
238