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        super.setConfig(conf);
301        setMaxIdle(conf.getMaxIdle());
302        setMinIdle(conf.getMinIdle());
303        setMaxTotal(conf.getMaxTotal());
304    }
305
306    /**
307     * Sets the abandoned object removal configuration.
308     *
309     * @param abandonedConfig the new configuration to use. This is used by value.
310     *
311     * @see AbandonedConfig
312     */
313    public void setAbandonedConfig(final AbandonedConfig abandonedConfig) {
314        if (abandonedConfig == null) {
315            this.abandonedConfig = null;
316        } else {
317            this.abandonedConfig = new AbandonedConfig();
318            this.abandonedConfig.setLogAbandoned(abandonedConfig.getLogAbandoned());
319            this.abandonedConfig.setLogWriter(abandonedConfig.getLogWriter());
320            this.abandonedConfig.setRemoveAbandonedOnBorrow(abandonedConfig.getRemoveAbandonedOnBorrow());
321            this.abandonedConfig.setRemoveAbandonedOnMaintenance(abandonedConfig.getRemoveAbandonedOnMaintenance());
322            this.abandonedConfig.setRemoveAbandonedTimeout(abandonedConfig.getRemoveAbandonedTimeout());
323            this.abandonedConfig.setUseUsageTracking(abandonedConfig.getUseUsageTracking());
324            this.abandonedConfig.setRequireFullStackTrace(abandonedConfig.getRequireFullStackTrace());
325        }
326    }
327
328    /**
329     * Obtains a reference to the factory used to create, destroy and validate
330     * the objects used by this pool.
331     *
332     * @return the factory
333     */
334    public PooledObjectFactory<T> getFactory() {
335        return factory;
336    }
337
338    /**
339     * Equivalent to <code>{@link #borrowObject(long)
340     * borrowObject}({@link #getMaxWaitMillis()})</code>.
341     * <p>
342     * {@inheritDoc}
343     */
344    @Override
345    public T borrowObject() throws Exception {
346        return borrowObject(getMaxWaitMillis());
347    }
348
349    /**
350     * Borrows an object from the pool using the specific waiting time which only
351     * applies if {@link #getBlockWhenExhausted()} is true.
352     * <p>
353     * If there is one or more idle instance available in the pool, then an
354     * idle instance will be selected based on the value of {@link #getLifo()},
355     * activated and returned. If activation fails, or {@link #getTestOnBorrow()
356     * testOnBorrow} is set to <code>true</code> and validation fails, the
357     * instance is destroyed and the next available instance is examined. This
358     * continues until either a valid instance is returned or there are no more
359     * idle instances available.
360     * <p>
361     * If there are no idle instances available in the pool, behavior depends on
362     * the {@link #getMaxTotal() maxTotal}, (if applicable)
363     * {@link #getBlockWhenExhausted()} and the value passed in to the
364     * <code>borrowMaxWaitMillis</code> parameter. If the number of instances
365     * checked out from the pool is less than <code>maxTotal,</code> a new
366     * instance is created, activated and (if applicable) validated and returned
367     * to the caller. If validation fails, a <code>NoSuchElementException</code>
368     * is thrown.
369     * <p>
370     * If the pool is exhausted (no available idle instances and no capacity to
371     * create new ones), this method will either block (if
372     * {@link #getBlockWhenExhausted()} is true) or throw a
373     * <code>NoSuchElementException</code> (if
374     * {@link #getBlockWhenExhausted()} is false). The length of time that this
375     * method will block when {@link #getBlockWhenExhausted()} is true is
376     * determined by the value passed in to the <code>borrowMaxWaitMillis</code>
377     * parameter.
378     * <p>
379     * When the pool is exhausted, multiple calling threads may be
380     * simultaneously blocked waiting for instances to become available. A
381     * "fairness" algorithm has been implemented to ensure that threads receive
382     * available instances in request arrival order.
383     *
384     * @param borrowMaxWaitMillis The time to wait in milliseconds for an object
385     *                            to become available
386     *
387     * @return object instance from the pool
388     *
389     * @throws NoSuchElementException if an instance cannot be returned
390     *
391     * @throws Exception if an object instance cannot be returned due to an
392     *                   error
393     */
394    public T borrowObject(final long borrowMaxWaitMillis) throws Exception {
395        assertOpen();
396
397        final AbandonedConfig ac = this.abandonedConfig;
398        if (ac != null && ac.getRemoveAbandonedOnBorrow() &&
399                (getNumIdle() < 2) &&
400                (getNumActive() > getMaxTotal() - 3) ) {
401            removeAbandoned(ac);
402        }
403
404        PooledObject<T> p = null;
405
406        // Get local copy of current config so it is consistent for entire
407        // method execution
408        final boolean blockWhenExhausted = getBlockWhenExhausted();
409
410        boolean create;
411        final long waitTime = System.currentTimeMillis();
412
413        while (p == null) {
414            create = false;
415            p = idleObjects.pollFirst();
416            if (p == null) {
417                p = create();
418                if (p != null) {
419                    create = true;
420                }
421            }
422            if (blockWhenExhausted) {
423                if (p == null) {
424                    if (borrowMaxWaitMillis < 0) {
425                        p = idleObjects.takeFirst();
426                    } else {
427                        p = idleObjects.pollFirst(borrowMaxWaitMillis,
428                                TimeUnit.MILLISECONDS);
429                    }
430                }
431                if (p == null) {
432                    throw new NoSuchElementException(
433                            "Timeout waiting for idle object");
434                }
435            } else {
436                if (p == null) {
437                    throw new NoSuchElementException("Pool exhausted");
438                }
439            }
440            if (!p.allocate()) {
441                p = null;
442            }
443
444            if (p != null) {
445                try {
446                    factory.activateObject(p);
447                } catch (final Exception e) {
448                    try {
449                        destroy(p);
450                    } catch (final Exception e1) {
451                        // Ignore - activation failure is more important
452                    }
453                    p = null;
454                    if (create) {
455                        final NoSuchElementException nsee = new NoSuchElementException(
456                                "Unable to activate object");
457                        nsee.initCause(e);
458                        throw nsee;
459                    }
460                }
461                if (p != null && (getTestOnBorrow() || create && getTestOnCreate())) {
462                    boolean validate = false;
463                    Throwable validationThrowable = null;
464                    try {
465                        validate = factory.validateObject(p);
466                    } catch (final Throwable t) {
467                        PoolUtils.checkRethrow(t);
468                        validationThrowable = t;
469                    }
470                    if (!validate) {
471                        try {
472                            destroy(p);
473                            destroyedByBorrowValidationCount.incrementAndGet();
474                        } catch (final Exception e) {
475                            // Ignore - validation failure is more important
476                        }
477                        p = null;
478                        if (create) {
479                            final NoSuchElementException nsee = new NoSuchElementException(
480                                    "Unable to validate object");
481                            nsee.initCause(validationThrowable);
482                            throw nsee;
483                        }
484                    }
485                }
486            }
487        }
488
489        updateStatsBorrow(p, System.currentTimeMillis() - waitTime);
490
491        return p.getObject();
492    }
493
494    /**
495     * {@inheritDoc}
496     * <p>
497     * If {@link #getMaxIdle() maxIdle} is set to a positive value and the
498     * number of idle instances has reached this value, the returning instance
499     * is destroyed.
500     * <p>
501     * If {@link #getTestOnReturn() testOnReturn} == true, the returning
502     * instance is validated before being returned to the idle instance pool. In
503     * this case, if validation fails, the instance is destroyed.
504     * <p>
505     * Exceptions encountered destroying objects for any reason are swallowed
506     * but notified via a {@link SwallowedExceptionListener}.
507     */
508    @Override
509    public void returnObject(final T obj) {
510        final PooledObject<T> p = allObjects.get(new IdentityWrapper<>(obj));
511
512        if (p == null) {
513            if (!isAbandonedConfig()) {
514                throw new IllegalStateException(
515                        "Returned object not currently part of this pool");
516            }
517            return; // Object was abandoned and removed
518        }
519
520        markReturningState(p);
521
522        final long activeTime = p.getActiveTimeMillis();
523
524        if (getTestOnReturn() && !factory.validateObject(p)) {
525            try {
526                destroy(p);
527            } catch (final Exception e) {
528                swallowException(e);
529            }
530            try {
531                ensureIdle(1, false);
532            } catch (final Exception e) {
533                swallowException(e);
534            }
535            updateStatsReturn(activeTime);
536            return;
537        }
538
539        try {
540            factory.passivateObject(p);
541        } catch (final Exception e1) {
542            swallowException(e1);
543            try {
544                destroy(p);
545            } catch (final Exception e) {
546                swallowException(e);
547            }
548            try {
549                ensureIdle(1, false);
550            } catch (final Exception e) {
551                swallowException(e);
552            }
553            updateStatsReturn(activeTime);
554            return;
555        }
556
557        if (!p.deallocate()) {
558            throw new IllegalStateException(
559                    "Object has already been returned to this pool or is invalid");
560        }
561
562        final int maxIdleSave = getMaxIdle();
563        if (isClosed() || maxIdleSave > -1 && maxIdleSave <= idleObjects.size()) {
564            try {
565                destroy(p);
566            } catch (final Exception e) {
567                swallowException(e);
568            }
569        } else {
570            if (getLifo()) {
571                idleObjects.addFirst(p);
572            } else {
573                idleObjects.addLast(p);
574            }
575            if (isClosed()) {
576                // Pool closed while object was being added to idle objects.
577                // Make sure the returned object is destroyed rather than left
578                // in the idle object pool (which would effectively be a leak)
579                clear();
580            }
581        }
582        updateStatsReturn(activeTime);
583    }
584
585    /**
586     * {@inheritDoc}
587     * <p>
588     * Activation of this method decrements the active count and attempts to
589     * destroy the instance.
590     *
591     * @throws Exception             if an exception occurs destroying the
592     *                               object
593     * @throws IllegalStateException if obj does not belong to this pool
594     */
595    @Override
596    public void invalidateObject(final T obj) throws Exception {
597        final PooledObject<T> p = allObjects.get(new IdentityWrapper<>(obj));
598        if (p == null) {
599            if (isAbandonedConfig()) {
600                return;
601            }
602            throw new IllegalStateException(
603                    "Invalidated object not currently part of this pool");
604        }
605        synchronized (p) {
606            if (p.getState() != PooledObjectState.INVALID) {
607                destroy(p);
608            }
609        }
610        ensureIdle(1, false);
611    }
612
613    /**
614     * Clears any objects sitting idle in the pool by removing them from the
615     * idle instance pool and then invoking the configured
616     * {@link PooledObjectFactory#destroyObject(PooledObject)} method on each
617     * idle instance.
618     * <p>
619     * Implementation notes:
620     * <ul>
621     * <li>This method does not destroy or effect in any way instances that are
622     * checked out of the pool when it is invoked.</li>
623     * <li>Invoking this method does not prevent objects being returned to the
624     * idle instance pool, even during its execution. Additional instances may
625     * be returned while removed items are being destroyed.</li>
626     * <li>Exceptions encountered destroying idle instances are swallowed
627     * but notified via a {@link SwallowedExceptionListener}.</li>
628     * </ul>
629     */
630    @Override
631    public void clear() {
632        PooledObject<T> p = idleObjects.poll();
633
634        while (p != null) {
635            try {
636                destroy(p);
637            } catch (final Exception e) {
638                swallowException(e);
639            }
640            p = idleObjects.poll();
641        }
642    }
643
644    @Override
645    public int getNumActive() {
646        return allObjects.size() - idleObjects.size();
647    }
648
649    @Override
650    public int getNumIdle() {
651        return idleObjects.size();
652    }
653
654    /**
655     * Closes the pool. Once the pool is closed, {@link #borrowObject()} will
656     * fail with IllegalStateException, but {@link #returnObject(Object)} and
657     * {@link #invalidateObject(Object)} will continue to work, with returned
658     * objects destroyed on return.
659     * <p>
660     * Destroys idle instances in the pool by invoking {@link #clear()}.
661     */
662    @Override
663    public void close() {
664        if (isClosed()) {
665            return;
666        }
667
668        synchronized (closeLock) {
669            if (isClosed()) {
670                return;
671            }
672
673            // Stop the evictor before the pool is closed since evict() calls
674            // assertOpen()
675            stopEvitor();
676
677            closed = true;
678            // This clear removes any idle objects
679            clear();
680
681            jmxUnregister();
682
683            // Release any threads that were waiting for an object
684            idleObjects.interuptTakeWaiters();
685        }
686    }
687
688    /**
689     * {@inheritDoc}
690     * <p>
691     * Successive activations of this method examine objects in sequence,
692     * cycling through objects in oldest-to-youngest order.
693     */
694    @Override
695    public void evict() throws Exception {
696        assertOpen();
697
698        if (idleObjects.size() > 0) {
699
700            PooledObject<T> underTest = null;
701            final EvictionPolicy<T> evictionPolicy = getEvictionPolicy();
702
703            synchronized (evictionLock) {
704                final EvictionConfig evictionConfig = new EvictionConfig(
705                        getMinEvictableIdleTimeMillis(),
706                        getSoftMinEvictableIdleTimeMillis(),
707                        getMinIdle());
708
709                final boolean testWhileIdle = getTestWhileIdle();
710
711                for (int i = 0, m = getNumTests(); i < m; i++) {
712                    if (evictionIterator == null || !evictionIterator.hasNext()) {
713                        evictionIterator = new EvictionIterator(idleObjects);
714                    }
715                    if (!evictionIterator.hasNext()) {
716                        // Pool exhausted, nothing to do here
717                        return;
718                    }
719
720                    try {
721                        underTest = evictionIterator.next();
722                    } catch (final NoSuchElementException nsee) {
723                        // Object was borrowed in another thread
724                        // Don't count this as an eviction test so reduce i;
725                        i--;
726                        evictionIterator = null;
727                        continue;
728                    }
729
730                    if (!underTest.startEvictionTest()) {
731                        // Object was borrowed in another thread
732                        // Don't count this as an eviction test so reduce i;
733                        i--;
734                        continue;
735                    }
736
737                    // User provided eviction policy could throw all sorts of
738                    // crazy exceptions. Protect against such an exception
739                    // killing the eviction thread.
740                    boolean evict;
741                    try {
742                        evict = evictionPolicy.evict(evictionConfig, underTest,
743                                idleObjects.size());
744                    } catch (final Throwable t) {
745                        // Slightly convoluted as SwallowedExceptionListener
746                        // uses Exception rather than Throwable
747                        PoolUtils.checkRethrow(t);
748                        swallowException(new Exception(t));
749                        // Don't evict on error conditions
750                        evict = false;
751                    }
752
753                    if (evict) {
754                        destroy(underTest);
755                        destroyedByEvictorCount.incrementAndGet();
756                    } else {
757                        if (testWhileIdle) {
758                            boolean active = false;
759                            try {
760                                factory.activateObject(underTest);
761                                active = true;
762                            } catch (final Exception e) {
763                                destroy(underTest);
764                                destroyedByEvictorCount.incrementAndGet();
765                            }
766                            if (active) {
767                                if (!factory.validateObject(underTest)) {
768                                    destroy(underTest);
769                                    destroyedByEvictorCount.incrementAndGet();
770                                } else {
771                                    try {
772                                        factory.passivateObject(underTest);
773                                    } catch (final Exception e) {
774                                        destroy(underTest);
775                                        destroyedByEvictorCount.incrementAndGet();
776                                    }
777                                }
778                            }
779                        }
780                        if (!underTest.endEvictionTest(idleObjects)) {
781                            // TODO - May need to add code here once additional
782                            // states are used
783                        }
784                    }
785                }
786            }
787        }
788        final AbandonedConfig ac = this.abandonedConfig;
789        if (ac != null && ac.getRemoveAbandonedOnMaintenance()) {
790            removeAbandoned(ac);
791        }
792    }
793
794    /**
795     * Tries to ensure that {@link #getMinIdle()} idle instances are available
796     * in the pool.
797     *
798     * @throws Exception If the associated factory throws an exception
799     * @since 2.4
800     */
801    public void preparePool() throws Exception {
802        if (getMinIdle() < 1) {
803            return;
804        }
805        ensureMinIdle();
806    }
807
808    /**
809     * Attempts to create a new wrapped pooled object.
810     * <p>
811     * If there are {@link #getMaxTotal()} objects already in circulation
812     * or in process of being created, this method returns null.
813     *
814     * @return The new wrapped pooled object
815     *
816     * @throws Exception if the object factory's {@code makeObject} fails
817     */
818    private PooledObject<T> create() throws Exception {
819        int localMaxTotal = getMaxTotal();
820        // This simplifies the code later in this method
821        if (localMaxTotal < 0) {
822            localMaxTotal = Integer.MAX_VALUE;
823        }
824
825        final long localStartTimeMillis = System.currentTimeMillis();
826        final long localMaxWaitTimeMillis = Math.max(getMaxWaitMillis(), 0);
827
828        // Flag that indicates if create should:
829        // - TRUE:  call the factory to create an object
830        // - FALSE: return null
831        // - null:  loop and re-test the condition that determines whether to
832        //          call the factory
833        Boolean create = null;
834        while (create == null) {
835            synchronized (makeObjectCountLock) {
836                final long newCreateCount = createCount.incrementAndGet();
837                if (newCreateCount > localMaxTotal) {
838                    // The pool is currently at capacity or in the process of
839                    // making enough new objects to take it to capacity.
840                    createCount.decrementAndGet();
841                    if (makeObjectCount == 0) {
842                        // There are no makeObject() calls in progress so the
843                        // pool is at capacity. Do not attempt to create a new
844                        // object. Return and wait for an object to be returned
845                        create = Boolean.FALSE;
846                    } else {
847                        // There are makeObject() calls in progress that might
848                        // bring the pool to capacity. Those calls might also
849                        // fail so wait until they complete and then re-test if
850                        // the pool is at capacity or not.
851                        makeObjectCountLock.wait(localMaxWaitTimeMillis);
852                    }
853                } else {
854                    // The pool is not at capacity. Create a new object.
855                    makeObjectCount++;
856                    create = Boolean.TRUE;
857                }
858            }
859
860            // Do not block more if maxWaitTimeMillis is set.
861            if (create == null &&
862                (localMaxWaitTimeMillis > 0 &&
863                 System.currentTimeMillis() - localStartTimeMillis >= localMaxWaitTimeMillis)) {
864                create = Boolean.FALSE;
865            }
866        }
867
868        if (!create.booleanValue()) {
869            return null;
870        }
871
872        final PooledObject<T> p;
873        try {
874            p = factory.makeObject();
875        } catch (final Throwable e) {
876            createCount.decrementAndGet();
877            throw e;
878        } finally {
879            synchronized (makeObjectCountLock) {
880                makeObjectCount--;
881                makeObjectCountLock.notifyAll();
882            }
883        }
884
885        final AbandonedConfig ac = this.abandonedConfig;
886        if (ac != null && ac.getLogAbandoned()) {
887            p.setLogAbandoned(true);
888            // TODO: in 3.0, this can use the method defined on PooledObject
889            if (p instanceof DefaultPooledObject<?>) {
890                ((DefaultPooledObject<T>) p).setRequireFullStackTrace(ac.getRequireFullStackTrace());
891            }
892        }
893
894        createdCount.incrementAndGet();
895        allObjects.put(new IdentityWrapper<>(p.getObject()), p);
896        return p;
897    }
898
899    /**
900     * Destroys a wrapped pooled object.
901     *
902     * @param toDestroy The wrapped pooled object to destroy
903     *
904     * @throws Exception If the factory fails to destroy the pooled object
905     *                   cleanly
906     */
907    private void destroy(final PooledObject<T> toDestroy) throws Exception {
908        toDestroy.invalidate();
909        idleObjects.remove(toDestroy);
910        allObjects.remove(new IdentityWrapper<>(toDestroy.getObject()));
911        try {
912            factory.destroyObject(toDestroy);
913        } finally {
914            destroyedCount.incrementAndGet();
915            createCount.decrementAndGet();
916        }
917
918        if (idleObjects.isEmpty() && idleObjects.hasTakeWaiters()) {
919            // POOL-356.
920            // In case there are already threads waiting on something in the pool
921            // (e.g. idleObjects.takeFirst(); then we need to provide them a fresh instance.
922            // Otherwise they will be stuck forever (or until timeout)
923            final PooledObject<T> freshPooled = create();
924            idleObjects.put(freshPooled);
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}