001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.commons.pool2.impl;
018
019import org.apache.commons.pool2.ObjectPool;
020import org.apache.commons.pool2.PoolUtils;
021import org.apache.commons.pool2.PooledObject;
022import org.apache.commons.pool2.PooledObjectFactory;
023import org.apache.commons.pool2.PooledObjectState;
024import org.apache.commons.pool2.SwallowedExceptionListener;
025import org.apache.commons.pool2.TrackedUse;
026import org.apache.commons.pool2.UsageTracking;
027
028import java.util.ArrayList;
029import java.util.HashSet;
030import java.util.Iterator;
031import java.util.Map;
032import java.util.NoSuchElementException;
033import java.util.Set;
034import java.util.concurrent.ConcurrentHashMap;
035import java.util.concurrent.TimeUnit;
036import java.util.concurrent.atomic.AtomicLong;
037
038/**
039 * A configurable {@link ObjectPool} implementation.
040 * <p>
041 * When coupled with the appropriate {@link PooledObjectFactory},
042 * <code>GenericObjectPool</code> provides robust pooling functionality for
043 * arbitrary objects.</p>
044 * <p>
045 * Optionally, one may configure the pool to examine and possibly evict objects
046 * as they sit idle in the pool and to ensure that a minimum number of idle
047 * objects are available. This is performed by an "idle object eviction" thread,
048 * which runs asynchronously. Caution should be used when configuring this
049 * optional feature. Eviction runs contend with client threads for access to
050 * objects in the pool, so if they run too frequently performance issues may
051 * result.</p>
052 * <p>
053 * The pool can also be configured to detect and remove "abandoned" objects,
054 * i.e. objects that have been checked out of the pool but neither used nor
055 * returned before the configured
056 * {@link AbandonedConfig#getRemoveAbandonedTimeout() removeAbandonedTimeout}.
057 * Abandoned object removal can be configured to happen when
058 * <code>borrowObject</code> is invoked and the pool is close to starvation, or
059 * it can be executed by the idle object evictor, or both. If pooled objects
060 * implement the {@link TrackedUse} interface, their last use will be queried
061 * using the <code>getLastUsed</code> method on that interface; otherwise
062 * abandonment is determined by how long an object has been checked out from
063 * the pool.</p>
064 * <p>
065 * Implementation note: To prevent possible deadlocks, care has been taken to
066 * ensure that no call to a factory method will occur within a synchronization
067 * block. See POOL-125 and DBCP-44 for more information.</p>
068 * <p>
069 * This class is intended to be thread-safe.</p>
070 *
071 * @see GenericKeyedObjectPool
072 *
073 * @param <T> Type of element pooled in this pool.
074 *
075 * @since 2.0
076 */
077public class GenericObjectPool<T> extends BaseGenericObjectPool<T>
078        implements ObjectPool<T>, GenericObjectPoolMXBean, UsageTracking<T> {
079
080    /**
081     * Creates a new <code>GenericObjectPool</code> using defaults from
082     * {@link GenericObjectPoolConfig}.
083     *
084     * @param factory The object factory to be used to create object instances
085     *                used by this pool
086     */
087    public GenericObjectPool(final PooledObjectFactory<T> factory) {
088        this(factory, new GenericObjectPoolConfig<T>());
089    }
090
091    /**
092     * Creates a new <code>GenericObjectPool</code> using a specific
093     * configuration.
094     *
095     * @param factory   The object factory to be used to create object instances
096     *                  used by this pool
097     * @param config    The configuration to use for this pool instance. The
098     *                  configuration is used by value. Subsequent changes to
099     *                  the configuration object will not be reflected in the
100     *                  pool.
101     */
102    public GenericObjectPool(final PooledObjectFactory<T> factory,
103            final GenericObjectPoolConfig<T> config) {
104
105        super(config, ONAME_BASE, config.getJmxNamePrefix());
106
107        if (factory == null) {
108            jmxUnregister(); // tidy up
109            throw new IllegalArgumentException("factory may not be null");
110        }
111        this.factory = factory;
112
113        idleObjects = new LinkedBlockingDeque<>(config.getFairness());
114
115        setConfig(config);
116    }
117
118    /**
119     * Creates a new <code>GenericObjectPool</code> that tracks and destroys
120     * objects that are checked out, but never returned to the pool.
121     *
122     * @param factory   The object factory to be used to create object instances
123     *                  used by this pool
124     * @param config    The base pool configuration to use for this pool instance.
125     *                  The configuration is used by value. Subsequent changes to
126     *                  the configuration object will not be reflected in the
127     *                  pool.
128     * @param abandonedConfig  Configuration for abandoned object identification
129     *                         and removal.  The configuration is used by value.
130     */
131    public GenericObjectPool(final PooledObjectFactory<T> factory,
132            final GenericObjectPoolConfig<T> config, final AbandonedConfig abandonedConfig) {
133        this(factory, config);
134        setAbandonedConfig(abandonedConfig);
135    }
136
137    /**
138     * Returns the cap on the number of "idle" instances in the pool. If maxIdle
139     * is set too low on heavily loaded systems it is possible you will see
140     * objects being destroyed and almost immediately new objects being created.
141     * This is a result of the active threads momentarily returning objects
142     * faster than they are requesting them, causing the number of idle
143     * objects to rise above maxIdle. The best value for maxIdle for heavily
144     * loaded system will vary but the default is a good starting point.
145     *
146     * @return the maximum number of "idle" instances that can be held in the
147     *         pool or a negative value if there is no limit
148     *
149     * @see #setMaxIdle
150     */
151    @Override
152    public int getMaxIdle() {
153        return maxIdle;
154    }
155
156    /**
157     * Returns the cap on the number of "idle" instances in the pool. If maxIdle
158     * is set too low on heavily loaded systems it is possible you will see
159     * objects being destroyed and almost immediately new objects being created.
160     * This is a result of the active threads momentarily returning objects
161     * faster than they are requesting them, causing the number of idle
162     * objects to rise above maxIdle. The best value for maxIdle for heavily
163     * loaded system will vary but the default is a good starting point.
164     *
165     * @param maxIdle
166     *            The cap on the number of "idle" instances in the pool. Use a
167     *            negative value to indicate an unlimited number of idle
168     *            instances
169     *
170     * @see #getMaxIdle
171     */
172    public void setMaxIdle(final int maxIdle) {
173        this.maxIdle = maxIdle;
174    }
175
176    /**
177     * Sets the target for the minimum number of idle objects to maintain in
178     * the pool. This setting only has an effect if it is positive and
179     * {@link #getTimeBetweenEvictionRunsMillis()} is greater than zero. If this
180     * is the case, an attempt is made to ensure that the pool has the required
181     * minimum number of instances during idle object eviction runs.
182     * <p>
183     * If the configured value of minIdle is greater than the configured value
184     * for maxIdle then the value of maxIdle will be used instead.
185     *
186     * @param minIdle
187     *            The minimum number of objects.
188     *
189     * @see #getMinIdle()
190     * @see #getMaxIdle()
191     * @see #getTimeBetweenEvictionRunsMillis()
192     */
193    public void setMinIdle(final int minIdle) {
194        this.minIdle = minIdle;
195    }
196
197    /**
198     * Returns the target for the minimum number of idle objects to maintain in
199     * the pool. This setting only has an effect if it is positive and
200     * {@link #getTimeBetweenEvictionRunsMillis()} is greater than zero. If this
201     * is the case, an attempt is made to ensure that the pool has the required
202     * minimum number of instances during idle object eviction runs.
203     * <p>
204     * If the configured value of minIdle is greater than the configured value
205     * for maxIdle then the value of maxIdle will be used instead.
206     *
207     * @return The minimum number of objects.
208     *
209     * @see #setMinIdle(int)
210     * @see #setMaxIdle(int)
211     * @see #setTimeBetweenEvictionRunsMillis(long)
212     */
213    @Override
214    public int getMinIdle() {
215        final int maxIdleSave = getMaxIdle();
216        if (this.minIdle > maxIdleSave) {
217            return maxIdleSave;
218        }
219        return minIdle;
220    }
221
222    /**
223     * Gets whether or not abandoned object removal is configured for this pool.
224     *
225     * @return true if this pool is configured to detect and remove
226     * abandoned objects
227     */
228    @Override
229    public boolean isAbandonedConfig() {
230        return abandonedConfig != null;
231    }
232
233    /**
234     * Gets whether this pool identifies and logs any abandoned objects.
235     *
236     * @return {@code true} if abandoned object removal is configured for this
237     *         pool and removal events are to be logged otherwise {@code false}
238     *
239     * @see AbandonedConfig#getLogAbandoned()
240     */
241    @Override
242    public boolean getLogAbandoned() {
243        final AbandonedConfig ac = this.abandonedConfig;
244        return ac != null && ac.getLogAbandoned();
245    }
246
247    /**
248     * Gets whether a check is made for abandoned objects when an object is borrowed
249     * from this pool.
250     *
251     * @return {@code true} if abandoned object removal is configured to be
252     *         activated by borrowObject otherwise {@code false}
253     *
254     * @see AbandonedConfig#getRemoveAbandonedOnBorrow()
255     */
256    @Override
257    public boolean getRemoveAbandonedOnBorrow() {
258        final AbandonedConfig ac = this.abandonedConfig;
259        return ac != null && ac.getRemoveAbandonedOnBorrow();
260    }
261
262    /**
263     * Gets whether a check is made for abandoned objects when the evictor runs.
264     *
265     * @return {@code true} if abandoned object removal is configured to be
266     *         activated when the evictor runs otherwise {@code false}
267     *
268     * @see AbandonedConfig#getRemoveAbandonedOnMaintenance()
269     */
270    @Override
271    public boolean getRemoveAbandonedOnMaintenance() {
272        final AbandonedConfig ac = this.abandonedConfig;
273        return ac != null && ac.getRemoveAbandonedOnMaintenance();
274    }
275
276    /**
277     * Obtains the timeout before which an object will be considered to be
278     * abandoned by this pool.
279     *
280     * @return The abandoned object timeout in seconds if abandoned object
281     *         removal is configured for this pool; Integer.MAX_VALUE otherwise.
282     *
283     * @see AbandonedConfig#getRemoveAbandonedTimeout()
284     */
285    @Override
286    public int getRemoveAbandonedTimeout() {
287        final AbandonedConfig ac = this.abandonedConfig;
288        return ac != null ? ac.getRemoveAbandonedTimeout() : Integer.MAX_VALUE;
289    }
290
291
292    /**
293     * Sets the base pool configuration.
294     *
295     * @param conf the new configuration to use. This is used by value.
296     *
297     * @see GenericObjectPoolConfig
298     */
299    public void setConfig(final GenericObjectPoolConfig<T> conf) {
300        setLifo(conf.getLifo());
301        setMaxIdle(conf.getMaxIdle());
302        setMinIdle(conf.getMinIdle());
303        setMaxTotal(conf.getMaxTotal());
304        setMaxWaitMillis(conf.getMaxWaitMillis());
305        setBlockWhenExhausted(conf.getBlockWhenExhausted());
306        setTestOnCreate(conf.getTestOnCreate());
307        setTestOnBorrow(conf.getTestOnBorrow());
308        setTestOnReturn(conf.getTestOnReturn());
309        setTestWhileIdle(conf.getTestWhileIdle());
310        setNumTestsPerEvictionRun(conf.getNumTestsPerEvictionRun());
311        setMinEvictableIdleTimeMillis(conf.getMinEvictableIdleTimeMillis());
312        setTimeBetweenEvictionRunsMillis(conf.getTimeBetweenEvictionRunsMillis());
313        setSoftMinEvictableIdleTimeMillis(conf.getSoftMinEvictableIdleTimeMillis());
314        final EvictionPolicy<T> policy = conf.getEvictionPolicy();
315        if (policy == null) {
316            // Use the class name (pre-2.6.0 compatible)
317            setEvictionPolicyClassName(conf.getEvictionPolicyClassName());
318        } else {
319            // Otherwise, use the class (2.6.0 feature)
320            setEvictionPolicy(policy);
321        }
322        setEvictorShutdownTimeoutMillis(conf.getEvictorShutdownTimeoutMillis());
323    }
324
325    /**
326     * Sets the abandoned object removal configuration.
327     *
328     * @param abandonedConfig the new configuration to use. This is used by value.
329     *
330     * @see AbandonedConfig
331     */
332    public void setAbandonedConfig(final AbandonedConfig abandonedConfig) {
333        if (abandonedConfig == null) {
334            this.abandonedConfig = null;
335        } else {
336            this.abandonedConfig = new AbandonedConfig();
337            this.abandonedConfig.setLogAbandoned(abandonedConfig.getLogAbandoned());
338            this.abandonedConfig.setLogWriter(abandonedConfig.getLogWriter());
339            this.abandonedConfig.setRemoveAbandonedOnBorrow(abandonedConfig.getRemoveAbandonedOnBorrow());
340            this.abandonedConfig.setRemoveAbandonedOnMaintenance(abandonedConfig.getRemoveAbandonedOnMaintenance());
341            this.abandonedConfig.setRemoveAbandonedTimeout(abandonedConfig.getRemoveAbandonedTimeout());
342            this.abandonedConfig.setUseUsageTracking(abandonedConfig.getUseUsageTracking());
343            this.abandonedConfig.setRequireFullStackTrace(abandonedConfig.getRequireFullStackTrace());
344        }
345    }
346
347    /**
348     * Obtains a reference to the factory used to create, destroy and validate
349     * the objects used by this pool.
350     *
351     * @return the factory
352     */
353    public PooledObjectFactory<T> getFactory() {
354        return factory;
355    }
356
357    /**
358     * Equivalent to <code>{@link #borrowObject(long)
359     * borrowObject}({@link #getMaxWaitMillis()})</code>.
360     * <p>
361     * {@inheritDoc}
362     */
363    @Override
364    public T borrowObject() throws Exception {
365        return borrowObject(getMaxWaitMillis());
366    }
367
368    /**
369     * Borrows an object from the pool using the specific waiting time which only
370     * applies if {@link #getBlockWhenExhausted()} is true.
371     * <p>
372     * If there is one or more idle instance available in the pool, then an
373     * idle instance will be selected based on the value of {@link #getLifo()},
374     * activated and returned. If activation fails, or {@link #getTestOnBorrow()
375     * testOnBorrow} is set to <code>true</code> and validation fails, the
376     * instance is destroyed and the next available instance is examined. This
377     * continues until either a valid instance is returned or there are no more
378     * idle instances available.
379     * <p>
380     * If there are no idle instances available in the pool, behavior depends on
381     * the {@link #getMaxTotal() maxTotal}, (if applicable)
382     * {@link #getBlockWhenExhausted()} and the value passed in to the
383     * <code>borrowMaxWaitMillis</code> parameter. If the number of instances
384     * checked out from the pool is less than <code>maxTotal,</code> a new
385     * instance is created, activated and (if applicable) validated and returned
386     * to the caller. If validation fails, a <code>NoSuchElementException</code>
387     * is thrown.
388     * <p>
389     * If the pool is exhausted (no available idle instances and no capacity to
390     * create new ones), this method will either block (if
391     * {@link #getBlockWhenExhausted()} is true) or throw a
392     * <code>NoSuchElementException</code> (if
393     * {@link #getBlockWhenExhausted()} is false). The length of time that this
394     * method will block when {@link #getBlockWhenExhausted()} is true is
395     * determined by the value passed in to the <code>borrowMaxWaitMillis</code>
396     * parameter.
397     * <p>
398     * When the pool is exhausted, multiple calling threads may be
399     * simultaneously blocked waiting for instances to become available. A
400     * "fairness" algorithm has been implemented to ensure that threads receive
401     * available instances in request arrival order.
402     *
403     * @param borrowMaxWaitMillis The time to wait in milliseconds for an object
404     *                            to become available
405     *
406     * @return object instance from the pool
407     *
408     * @throws NoSuchElementException if an instance cannot be returned
409     *
410     * @throws Exception if an object instance cannot be returned due to an
411     *                   error
412     */
413    public T borrowObject(final long borrowMaxWaitMillis) throws Exception {
414        assertOpen();
415
416        final AbandonedConfig ac = this.abandonedConfig;
417        if (ac != null && ac.getRemoveAbandonedOnBorrow() &&
418                (getNumIdle() < 2) &&
419                (getNumActive() > getMaxTotal() - 3) ) {
420            removeAbandoned(ac);
421        }
422
423        PooledObject<T> p = null;
424
425        // Get local copy of current config so it is consistent for entire
426        // method execution
427        final boolean blockWhenExhausted = getBlockWhenExhausted();
428
429        boolean create;
430        final long waitTime = System.currentTimeMillis();
431
432        while (p == null) {
433            create = false;
434            p = idleObjects.pollFirst();
435            if (p == null) {
436                p = create();
437                if (p != null) {
438                    create = true;
439                }
440            }
441            if (blockWhenExhausted) {
442                if (p == null) {
443                    if (borrowMaxWaitMillis < 0) {
444                        p = idleObjects.takeFirst();
445                    } else {
446                        p = idleObjects.pollFirst(borrowMaxWaitMillis,
447                                TimeUnit.MILLISECONDS);
448                    }
449                }
450                if (p == null) {
451                    throw new NoSuchElementException(
452                            "Timeout waiting for idle object");
453                }
454            } else {
455                if (p == null) {
456                    throw new NoSuchElementException("Pool exhausted");
457                }
458            }
459            if (!p.allocate()) {
460                p = null;
461            }
462
463            if (p != null) {
464                try {
465                    factory.activateObject(p);
466                } catch (final Exception e) {
467                    try {
468                        destroy(p);
469                    } catch (final Exception e1) {
470                        // Ignore - activation failure is more important
471                    }
472                    p = null;
473                    if (create) {
474                        final NoSuchElementException nsee = new NoSuchElementException(
475                                "Unable to activate object");
476                        nsee.initCause(e);
477                        throw nsee;
478                    }
479                }
480                if (p != null && (getTestOnBorrow() || create && getTestOnCreate())) {
481                    boolean validate = false;
482                    Throwable validationThrowable = null;
483                    try {
484                        validate = factory.validateObject(p);
485                    } catch (final Throwable t) {
486                        PoolUtils.checkRethrow(t);
487                        validationThrowable = t;
488                    }
489                    if (!validate) {
490                        try {
491                            destroy(p);
492                            destroyedByBorrowValidationCount.incrementAndGet();
493                        } catch (final Exception e) {
494                            // Ignore - validation failure is more important
495                        }
496                        p = null;
497                        if (create) {
498                            final NoSuchElementException nsee = new NoSuchElementException(
499                                    "Unable to validate object");
500                            nsee.initCause(validationThrowable);
501                            throw nsee;
502                        }
503                    }
504                }
505            }
506        }
507
508        updateStatsBorrow(p, System.currentTimeMillis() - waitTime);
509
510        return p.getObject();
511    }
512
513    /**
514     * {@inheritDoc}
515     * <p>
516     * If {@link #getMaxIdle() maxIdle} is set to a positive value and the
517     * number of idle instances has reached this value, the returning instance
518     * is destroyed.
519     * <p>
520     * If {@link #getTestOnReturn() testOnReturn} == true, the returning
521     * instance is validated before being returned to the idle instance pool. In
522     * this case, if validation fails, the instance is destroyed.
523     * <p>
524     * Exceptions encountered destroying objects for any reason are swallowed
525     * but notified via a {@link SwallowedExceptionListener}.
526     */
527    @Override
528    public void returnObject(final T obj) {
529        final PooledObject<T> p = allObjects.get(new IdentityWrapper<>(obj));
530
531        if (p == null) {
532            if (!isAbandonedConfig()) {
533                throw new IllegalStateException(
534                        "Returned object not currently part of this pool");
535            }
536            return; // Object was abandoned and removed
537        }
538
539        markReturningState(p);
540
541        final long activeTime = p.getActiveTimeMillis();
542
543        if (getTestOnReturn() && !factory.validateObject(p)) {
544            try {
545                destroy(p);
546            } catch (final Exception e) {
547                swallowException(e);
548            }
549            try {
550                ensureIdle(1, false);
551            } catch (final Exception e) {
552                swallowException(e);
553            }
554            updateStatsReturn(activeTime);
555            return;
556        }
557
558        try {
559            factory.passivateObject(p);
560        } catch (final Exception e1) {
561            swallowException(e1);
562            try {
563                destroy(p);
564            } catch (final Exception e) {
565                swallowException(e);
566            }
567            try {
568                ensureIdle(1, false);
569            } catch (final Exception e) {
570                swallowException(e);
571            }
572            updateStatsReturn(activeTime);
573            return;
574        }
575
576        if (!p.deallocate()) {
577            throw new IllegalStateException(
578                    "Object has already been returned to this pool or is invalid");
579        }
580
581        final int maxIdleSave = getMaxIdle();
582        if (isClosed() || maxIdleSave > -1 && maxIdleSave <= idleObjects.size()) {
583            try {
584                destroy(p);
585            } catch (final Exception e) {
586                swallowException(e);
587            }
588        } else {
589            if (getLifo()) {
590                idleObjects.addFirst(p);
591            } else {
592                idleObjects.addLast(p);
593            }
594            if (isClosed()) {
595                // Pool closed while object was being added to idle objects.
596                // Make sure the returned object is destroyed rather than left
597                // in the idle object pool (which would effectively be a leak)
598                clear();
599            }
600        }
601        updateStatsReturn(activeTime);
602    }
603
604    /**
605     * {@inheritDoc}
606     * <p>
607     * Activation of this method decrements the active count and attempts to
608     * destroy the instance.
609     *
610     * @throws Exception             if an exception occurs destroying the
611     *                               object
612     * @throws IllegalStateException if obj does not belong to this pool
613     */
614    @Override
615    public void invalidateObject(final T obj) throws Exception {
616        final PooledObject<T> p = allObjects.get(new IdentityWrapper<>(obj));
617        if (p == null) {
618            if (isAbandonedConfig()) {
619                return;
620            }
621            throw new IllegalStateException(
622                    "Invalidated object not currently part of this pool");
623        }
624        synchronized (p) {
625            if (p.getState() != PooledObjectState.INVALID) {
626                destroy(p);
627            }
628        }
629        ensureIdle(1, false);
630    }
631
632    /**
633     * Clears any objects sitting idle in the pool by removing them from the
634     * idle instance pool and then invoking the configured
635     * {@link PooledObjectFactory#destroyObject(PooledObject)} method on each
636     * idle instance.
637     * <p>
638     * Implementation notes:
639     * <ul>
640     * <li>This method does not destroy or effect in any way instances that are
641     * checked out of the pool when it is invoked.</li>
642     * <li>Invoking this method does not prevent objects being returned to the
643     * idle instance pool, even during its execution. Additional instances may
644     * be returned while removed items are being destroyed.</li>
645     * <li>Exceptions encountered destroying idle instances are swallowed
646     * but notified via a {@link SwallowedExceptionListener}.</li>
647     * </ul>
648     */
649    @Override
650    public void clear() {
651        PooledObject<T> p = idleObjects.poll();
652
653        while (p != null) {
654            try {
655                destroy(p);
656            } catch (final Exception e) {
657                swallowException(e);
658            }
659            p = idleObjects.poll();
660        }
661    }
662
663    @Override
664    public int getNumActive() {
665        return allObjects.size() - idleObjects.size();
666    }
667
668    @Override
669    public int getNumIdle() {
670        return idleObjects.size();
671    }
672
673    /**
674     * Closes the pool. Once the pool is closed, {@link #borrowObject()} will
675     * fail with IllegalStateException, but {@link #returnObject(Object)} and
676     * {@link #invalidateObject(Object)} will continue to work, with returned
677     * objects destroyed on return.
678     * <p>
679     * Destroys idle instances in the pool by invoking {@link #clear()}.
680     */
681    @Override
682    public void close() {
683        if (isClosed()) {
684            return;
685        }
686
687        synchronized (closeLock) {
688            if (isClosed()) {
689                return;
690            }
691
692            // Stop the evictor before the pool is closed since evict() calls
693            // assertOpen()
694            startEvictor(-1L);
695
696            closed = true;
697            // This clear removes any idle objects
698            clear();
699
700            jmxUnregister();
701
702            // Release any threads that were waiting for an object
703            idleObjects.interuptTakeWaiters();
704        }
705    }
706
707    /**
708     * {@inheritDoc}
709     * <p>
710     * Successive activations of this method examine objects in sequence,
711     * cycling through objects in oldest-to-youngest order.
712     */
713    @Override
714    public void evict() throws Exception {
715        assertOpen();
716
717        if (idleObjects.size() > 0) {
718
719            PooledObject<T> underTest = null;
720            final EvictionPolicy<T> evictionPolicy = getEvictionPolicy();
721
722            synchronized (evictionLock) {
723                final EvictionConfig evictionConfig = new EvictionConfig(
724                        getMinEvictableIdleTimeMillis(),
725                        getSoftMinEvictableIdleTimeMillis(),
726                        getMinIdle());
727
728                final boolean testWhileIdle = getTestWhileIdle();
729
730                for (int i = 0, m = getNumTests(); i < m; i++) {
731                    if (evictionIterator == null || !evictionIterator.hasNext()) {
732                        evictionIterator = new EvictionIterator(idleObjects);
733                    }
734                    if (!evictionIterator.hasNext()) {
735                        // Pool exhausted, nothing to do here
736                        return;
737                    }
738
739                    try {
740                        underTest = evictionIterator.next();
741                    } catch (final NoSuchElementException nsee) {
742                        // Object was borrowed in another thread
743                        // Don't count this as an eviction test so reduce i;
744                        i--;
745                        evictionIterator = null;
746                        continue;
747                    }
748
749                    if (!underTest.startEvictionTest()) {
750                        // Object was borrowed in another thread
751                        // Don't count this as an eviction test so reduce i;
752                        i--;
753                        continue;
754                    }
755
756                    // User provided eviction policy could throw all sorts of
757                    // crazy exceptions. Protect against such an exception
758                    // killing the eviction thread.
759                    boolean evict;
760                    try {
761                        evict = evictionPolicy.evict(evictionConfig, underTest,
762                                idleObjects.size());
763                    } catch (final Throwable t) {
764                        // Slightly convoluted as SwallowedExceptionListener
765                        // uses Exception rather than Throwable
766                        PoolUtils.checkRethrow(t);
767                        swallowException(new Exception(t));
768                        // Don't evict on error conditions
769                        evict = false;
770                    }
771
772                    if (evict) {
773                        destroy(underTest);
774                        destroyedByEvictorCount.incrementAndGet();
775                    } else {
776                        if (testWhileIdle) {
777                            boolean active = false;
778                            try {
779                                factory.activateObject(underTest);
780                                active = true;
781                            } catch (final Exception e) {
782                                destroy(underTest);
783                                destroyedByEvictorCount.incrementAndGet();
784                            }
785                            if (active) {
786                                if (!factory.validateObject(underTest)) {
787                                    destroy(underTest);
788                                    destroyedByEvictorCount.incrementAndGet();
789                                } else {
790                                    try {
791                                        factory.passivateObject(underTest);
792                                    } catch (final Exception e) {
793                                        destroy(underTest);
794                                        destroyedByEvictorCount.incrementAndGet();
795                                    }
796                                }
797                            }
798                        }
799                        if (!underTest.endEvictionTest(idleObjects)) {
800                            // TODO - May need to add code here once additional
801                            // states are used
802                        }
803                    }
804                }
805            }
806        }
807        final AbandonedConfig ac = this.abandonedConfig;
808        if (ac != null && ac.getRemoveAbandonedOnMaintenance()) {
809            removeAbandoned(ac);
810        }
811    }
812
813    /**
814     * Tries to ensure that {@link #getMinIdle()} idle instances are available
815     * in the pool.
816     *
817     * @throws Exception If the associated factory throws an exception
818     * @since 2.4
819     */
820    public void preparePool() throws Exception {
821        if (getMinIdle() < 1) {
822            return;
823        }
824        ensureMinIdle();
825    }
826
827    /**
828     * Attempts to create a new wrapped pooled object.
829     * <p>
830     * If there are {@link #getMaxTotal()} objects already in circulation
831     * or in process of being created, this method returns null.
832     *
833     * @return The new wrapped pooled object
834     *
835     * @throws Exception if the object factory's {@code makeObject} fails
836     */
837    private PooledObject<T> create() throws Exception {
838        int localMaxTotal = getMaxTotal();
839        // This simplifies the code later in this method
840        if (localMaxTotal < 0) {
841            localMaxTotal = Integer.MAX_VALUE;
842        }
843
844        // Flag that indicates if create should:
845        // - TRUE:  call the factory to create an object
846        // - FALSE: return null
847        // - null:  loop and re-test the condition that determines whether to
848        //          call the factory
849        Boolean create = null;
850        while (create == null) {
851            synchronized (makeObjectCountLock) {
852                final long newCreateCount = createCount.incrementAndGet();
853                if (newCreateCount > localMaxTotal) {
854                    // The pool is currently at capacity or in the process of
855                    // making enough new objects to take it to capacity.
856                    createCount.decrementAndGet();
857                    if (makeObjectCount == 0) {
858                        // There are no makeObject() calls in progress so the
859                        // pool is at capacity. Do not attempt to create a new
860                        // object. Return and wait for an object to be returned
861                        create = Boolean.FALSE;
862                    } else {
863                        // There are makeObject() calls in progress that might
864                        // bring the pool to capacity. Those calls might also
865                        // fail so wait until they complete and then re-test if
866                        // the pool is at capacity or not.
867                        makeObjectCountLock.wait();
868                    }
869                } else {
870                    // The pool is not at capacity. Create a new object.
871                    makeObjectCount++;
872                    create = Boolean.TRUE;
873                }
874            }
875        }
876
877        if (!create.booleanValue()) {
878            return null;
879        }
880
881        final PooledObject<T> p;
882        try {
883            p = factory.makeObject();
884        } catch (final Throwable e) {
885            createCount.decrementAndGet();
886            throw e;
887        } finally {
888            synchronized (makeObjectCountLock) {
889                makeObjectCount--;
890                makeObjectCountLock.notifyAll();
891            }
892        }
893
894        final AbandonedConfig ac = this.abandonedConfig;
895        if (ac != null && ac.getLogAbandoned()) {
896            p.setLogAbandoned(true);
897            // TODO: in 3.0, this can use the method defined on PooledObject
898            if (p instanceof DefaultPooledObject<?>) {
899                ((DefaultPooledObject<T>) p).setRequireFullStackTrace(ac.getRequireFullStackTrace());
900            }
901        }
902
903        createdCount.incrementAndGet();
904        allObjects.put(new IdentityWrapper<>(p.getObject()), p);
905        return p;
906    }
907
908    /**
909     * Destroys a wrapped pooled object.
910     *
911     * @param toDestroy The wrapped pooled object to destroy
912     *
913     * @throws Exception If the factory fails to destroy the pooled object
914     *                   cleanly
915     */
916    private void destroy(final PooledObject<T> toDestroy) throws Exception {
917        toDestroy.invalidate();
918        idleObjects.remove(toDestroy);
919        allObjects.remove(new IdentityWrapper<>(toDestroy.getObject()));
920        try {
921            factory.destroyObject(toDestroy);
922        } finally {
923            destroyedCount.incrementAndGet();
924            createCount.decrementAndGet();
925        }
926    }
927
928    @Override
929    void ensureMinIdle() throws Exception {
930        ensureIdle(getMinIdle(), true);
931    }
932
933    /**
934     * Tries to ensure that {@code idleCount} idle instances exist in the pool.
935     * <p>
936     * Creates and adds idle instances until either {@link #getNumIdle()} reaches {@code idleCount}
937     * or the total number of objects (idle, checked out, or being created) reaches
938     * {@link #getMaxTotal()}. If {@code always} is false, no instances are created unless
939     * there are threads waiting to check out instances from the pool.
940     *
941     * @param idleCount the number of idle instances desired
942     * @param always true means create instances even if the pool has no threads waiting
943     * @throws Exception if the factory's makeObject throws
944     */
945    private void ensureIdle(final int idleCount, final boolean always) throws Exception {
946        if (idleCount < 1 || isClosed() || (!always && !idleObjects.hasTakeWaiters())) {
947            return;
948        }
949
950        while (idleObjects.size() < idleCount) {
951            final PooledObject<T> p = create();
952            if (p == null) {
953                // Can't create objects, no reason to think another call to
954                // create will work. Give up.
955                break;
956            }
957            if (getLifo()) {
958                idleObjects.addFirst(p);
959            } else {
960                idleObjects.addLast(p);
961            }
962        }
963        if (isClosed()) {
964            // Pool closed while object was being added to idle objects.
965            // Make sure the returned object is destroyed rather than left
966            // in the idle object pool (which would effectively be a leak)
967            clear();
968        }
969    }
970
971    /**
972     * Creates an object, and place it into the pool. addObject() is useful for
973     * "pre-loading" a pool with idle objects.
974     * <p>
975     * If there is no capacity available to add to the pool, this is a no-op
976     * (no exception, no impact to the pool). </p>
977     */
978    @Override
979    public void addObject() throws Exception {
980        assertOpen();
981        if (factory == null) {
982            throw new IllegalStateException(
983                    "Cannot add objects without a factory.");
984        }
985        final PooledObject<T> p = create();
986        addIdleObject(p);
987    }
988
989    /**
990     * Adds the provided wrapped pooled object to the set of idle objects for
991     * this pool. The object must already be part of the pool.  If {@code p}
992     * is null, this is a no-op (no exception, but no impact on the pool).
993     *
994     * @param p The object to make idle
995     *
996     * @throws Exception If the factory fails to passivate the object
997     */
998    private void addIdleObject(final PooledObject<T> p) throws Exception {
999        if (p != null) {
1000            factory.passivateObject(p);
1001            if (getLifo()) {
1002                idleObjects.addFirst(p);
1003            } else {
1004                idleObjects.addLast(p);
1005            }
1006        }
1007    }
1008
1009    /**
1010     * Calculates the number of objects to test in a run of the idle object
1011     * evictor.
1012     *
1013     * @return The number of objects to test for validity
1014     */
1015    private int getNumTests() {
1016        final int numTestsPerEvictionRun = getNumTestsPerEvictionRun();
1017        if (numTestsPerEvictionRun >= 0) {
1018            return Math.min(numTestsPerEvictionRun, idleObjects.size());
1019        }
1020        return (int) (Math.ceil(idleObjects.size() /
1021                Math.abs((double) numTestsPerEvictionRun)));
1022    }
1023
1024    /**
1025     * Recovers abandoned objects which have been checked out but
1026     * not used since longer than the removeAbandonedTimeout.
1027     *
1028     * @param ac The configuration to use to identify abandoned objects
1029     */
1030    private void removeAbandoned(final AbandonedConfig ac) {
1031        // Generate a list of abandoned objects to remove
1032        final long now = System.currentTimeMillis();
1033        final long timeout =
1034                now - (ac.getRemoveAbandonedTimeout() * 1000L);
1035        final ArrayList<PooledObject<T>> remove = new ArrayList<>();
1036        final Iterator<PooledObject<T>> it = allObjects.values().iterator();
1037        while (it.hasNext()) {
1038            final PooledObject<T> pooledObject = it.next();
1039            synchronized (pooledObject) {
1040                if (pooledObject.getState() == PooledObjectState.ALLOCATED &&
1041                        pooledObject.getLastUsedTime() <= timeout) {
1042                    pooledObject.markAbandoned();
1043                    remove.add(pooledObject);
1044                }
1045            }
1046        }
1047
1048        // Now remove the abandoned objects
1049        final Iterator<PooledObject<T>> itr = remove.iterator();
1050        while (itr.hasNext()) {
1051            final PooledObject<T> pooledObject = itr.next();
1052            if (ac.getLogAbandoned()) {
1053                pooledObject.printStackTrace(ac.getLogWriter());
1054            }
1055            try {
1056                invalidateObject(pooledObject.getObject());
1057            } catch (final Exception e) {
1058                e.printStackTrace();
1059            }
1060        }
1061    }
1062
1063
1064    //--- Usage tracking support -----------------------------------------------
1065
1066    @Override
1067    public void use(final T pooledObject) {
1068        final AbandonedConfig ac = this.abandonedConfig;
1069        if (ac != null && ac.getUseUsageTracking()) {
1070            final PooledObject<T> wrapper = allObjects.get(new IdentityWrapper<>(pooledObject));
1071            wrapper.use();
1072        }
1073    }
1074
1075
1076    //--- JMX support ----------------------------------------------------------
1077
1078    private volatile String factoryType = null;
1079
1080    /**
1081     * Returns an estimate of the number of threads currently blocked waiting for
1082     * an object from the pool. This is intended for monitoring only, not for
1083     * synchronization control.
1084     *
1085     * @return The estimate of the number of threads currently blocked waiting
1086     *         for an object from the pool
1087     */
1088    @Override
1089    public int getNumWaiters() {
1090        if (getBlockWhenExhausted()) {
1091            return idleObjects.getTakeQueueLength();
1092        }
1093        return 0;
1094    }
1095
1096    /**
1097     * Returns the type - including the specific type rather than the generic -
1098     * of the factory.
1099     *
1100     * @return A string representation of the factory type
1101     */
1102    @Override
1103    public String getFactoryType() {
1104        // Not thread safe. Accept that there may be multiple evaluations.
1105        if (factoryType == null) {
1106            final StringBuilder result = new StringBuilder();
1107            result.append(factory.getClass().getName());
1108            result.append('<');
1109            final Class<?> pooledObjectType =
1110                    PoolImplUtils.getFactoryType(factory.getClass());
1111            result.append(pooledObjectType.getName());
1112            result.append('>');
1113            factoryType = result.toString();
1114        }
1115        return factoryType;
1116    }
1117
1118    /**
1119     * Provides information on all the objects in the pool, both idle (waiting
1120     * to be borrowed) and active (currently borrowed).
1121     * <p>
1122     * Note: This is named listAllObjects so it is presented as an operation via
1123     * JMX. That means it won't be invoked unless the explicitly requested
1124     * whereas all attributes will be automatically requested when viewing the
1125     * attributes for an object in a tool like JConsole.
1126     *
1127     * @return Information grouped on all the objects in the pool
1128     */
1129    @Override
1130    public Set<DefaultPooledObjectInfo> listAllObjects() {
1131        final Set<DefaultPooledObjectInfo> result =
1132                new HashSet<>(allObjects.size());
1133        for (final PooledObject<T> p : allObjects.values()) {
1134            result.add(new DefaultPooledObjectInfo(p));
1135        }
1136        return result;
1137    }
1138
1139    // --- configuration attributes --------------------------------------------
1140
1141    private volatile int maxIdle = GenericObjectPoolConfig.DEFAULT_MAX_IDLE;
1142    private volatile int minIdle = GenericObjectPoolConfig.DEFAULT_MIN_IDLE;
1143    private final PooledObjectFactory<T> factory;
1144
1145
1146    // --- internal attributes -------------------------------------------------
1147
1148    /*
1149     * All of the objects currently associated with this pool in any state. It
1150     * excludes objects that have been destroyed. The size of
1151     * {@link #allObjects} will always be less than or equal to {@link
1152     * #_maxActive}. Map keys are pooled objects, values are the PooledObject
1153     * wrappers used internally by the pool.
1154     */
1155    private final Map<IdentityWrapper<T>, PooledObject<T>> allObjects =
1156        new ConcurrentHashMap<>();
1157    /*
1158     * The combined count of the currently created objects and those in the
1159     * process of being created. Under load, it may exceed {@link #_maxActive}
1160     * if multiple threads try and create a new object at the same time but
1161     * {@link #create()} will ensure that there are never more than
1162     * {@link #_maxActive} objects created at any one time.
1163     */
1164    private final AtomicLong createCount = new AtomicLong(0);
1165    private long makeObjectCount = 0;
1166    private final Object makeObjectCountLock = new Object();
1167    private final LinkedBlockingDeque<PooledObject<T>> idleObjects;
1168
1169    // JMX specific attributes
1170    private static final String ONAME_BASE =
1171        "org.apache.commons.pool2:type=GenericObjectPool,name=";
1172
1173    // Additional configuration properties for abandoned object tracking
1174    private volatile AbandonedConfig abandonedConfig = null;
1175
1176    @Override
1177    protected void toStringAppendFields(final StringBuilder builder) {
1178        super.toStringAppendFields(builder);
1179        builder.append(", factoryType=");
1180        builder.append(factoryType);
1181        builder.append(", maxIdle=");
1182        builder.append(maxIdle);
1183        builder.append(", minIdle=");
1184        builder.append(minIdle);
1185        builder.append(", factory=");
1186        builder.append(factory);
1187        builder.append(", allObjects=");
1188        builder.append(allObjects);
1189        builder.append(", createCount=");
1190        builder.append(createCount);
1191        builder.append(", idleObjects=");
1192        builder.append(idleObjects);
1193        builder.append(", abandonedConfig=");
1194        builder.append(abandonedConfig);
1195    }
1196
1197}