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