You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@commons.apache.org by gg...@apache.org on 2019/08/10 22:26:46 UTC

svn commit: r1048500 [22/39] - in /websites/production/commons/content/proper: commons-pool/ commons-pool/apidocs/ commons-pool/apidocs/org/apache/commons/pool2/ commons-pool/apidocs/org/apache/commons/pool2/class-use/ commons-pool/apidocs/org/apache/c...

Added: websites/production/commons/content/proper/commons-pool/jacoco/org.apache.commons.pool2.impl/GenericObjectPool.java.html
==============================================================================
--- websites/production/commons/content/proper/commons-pool/jacoco/org.apache.commons.pool2.impl/GenericObjectPool.java.html (added)
+++ websites/production/commons/content/proper/commons-pool/jacoco/org.apache.commons.pool2.impl/GenericObjectPool.java.html Sat Aug 10 22:26:44 2019
@@ -0,0 +1,1216 @@
+<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml" lang="en"><head><meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/><link rel="stylesheet" href="../jacoco-resources/report.css" type="text/css"/><link rel="shortcut icon" href="../jacoco-resources/report.gif" type="image/gif"/><title>GenericObjectPool.java</title><link rel="stylesheet" href="../jacoco-resources/prettify.css" type="text/css"/><script type="text/javascript" src="../jacoco-resources/prettify.js"></script></head><body onload="window['PR_TAB_WIDTH']=4;prettyPrint()"><div class="breadcrumb" id="breadcrumb"><span class="info"><a href="../jacoco-sessions.html" class="el_session">Sessions</a></span><a href="../index.html" class="el_report">Apache Commons Pool</a> &gt; <a href="index.source.html" class="el_package">org.apache.commons.pool2.impl</a> &gt; <span class="el_sour
 ce">GenericObjectPool.java</span></div><h1>GenericObjectPool.java</h1><pre class="source lang-java linenums">/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the &quot;License&quot;); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an &quot;AS IS&quot; BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.pool2.impl;
+
+import org.apache.commons.pool2.ObjectPool;
+import org.apache.commons.pool2.PoolUtils;
+import org.apache.commons.pool2.PooledObject;
+import org.apache.commons.pool2.PooledObjectFactory;
+import org.apache.commons.pool2.PooledObjectState;
+import org.apache.commons.pool2.SwallowedExceptionListener;
+import org.apache.commons.pool2.TrackedUse;
+import org.apache.commons.pool2.UsageTracking;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.NoSuchElementException;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicLong;
+
+/**
+ * A configurable {@link ObjectPool} implementation.
+ * &lt;p&gt;
+ * When coupled with the appropriate {@link PooledObjectFactory},
+ * &lt;code&gt;GenericObjectPool&lt;/code&gt; provides robust pooling functionality for
+ * arbitrary objects.&lt;/p&gt;
+ * &lt;p&gt;
+ * Optionally, one may configure the pool to examine and possibly evict objects
+ * as they sit idle in the pool and to ensure that a minimum number of idle
+ * objects are available. This is performed by an &quot;idle object eviction&quot; thread,
+ * which runs asynchronously. Caution should be used when configuring this
+ * optional feature. Eviction runs contend with client threads for access to
+ * objects in the pool, so if they run too frequently performance issues may
+ * result.&lt;/p&gt;
+ * &lt;p&gt;
+ * The pool can also be configured to detect and remove &quot;abandoned&quot; objects,
+ * i.e. objects that have been checked out of the pool but neither used nor
+ * returned before the configured
+ * {@link AbandonedConfig#getRemoveAbandonedTimeout() removeAbandonedTimeout}.
+ * Abandoned object removal can be configured to happen when
+ * &lt;code&gt;borrowObject&lt;/code&gt; is invoked and the pool is close to starvation, or
+ * it can be executed by the idle object evictor, or both. If pooled objects
+ * implement the {@link TrackedUse} interface, their last use will be queried
+ * using the &lt;code&gt;getLastUsed&lt;/code&gt; method on that interface; otherwise
+ * abandonment is determined by how long an object has been checked out from
+ * the pool.&lt;/p&gt;
+ * &lt;p&gt;
+ * Implementation note: To prevent possible deadlocks, care has been taken to
+ * ensure that no call to a factory method will occur within a synchronization
+ * block. See POOL-125 and DBCP-44 for more information.&lt;/p&gt;
+ * &lt;p&gt;
+ * This class is intended to be thread-safe.&lt;/p&gt;
+ *
+ * @see GenericKeyedObjectPool
+ *
+ * @param &lt;T&gt; Type of element pooled in this pool.
+ *
+ * @since 2.0
+ */
+public class GenericObjectPool&lt;T&gt; extends BaseGenericObjectPool&lt;T&gt;
+        implements ObjectPool&lt;T&gt;, GenericObjectPoolMXBean, UsageTracking&lt;T&gt; {
+
+    /**
+     * Creates a new &lt;code&gt;GenericObjectPool&lt;/code&gt; using defaults from
+     * {@link GenericObjectPoolConfig}.
+     *
+     * @param factory The object factory to be used to create object instances
+     *                used by this pool
+     */
+    public GenericObjectPool(final PooledObjectFactory&lt;T&gt; factory) {
+<span class="fc" id="L88">        this(factory, new GenericObjectPoolConfig&lt;T&gt;());</span>
+<span class="fc" id="L89">    }</span>
+
+    /**
+     * Creates a new &lt;code&gt;GenericObjectPool&lt;/code&gt; using a specific
+     * configuration.
+     *
+     * @param factory   The object factory to be used to create object instances
+     *                  used by this pool
+     * @param config    The configuration to use for this pool instance. The
+     *                  configuration is used by value. Subsequent changes to
+     *                  the configuration object will not be reflected in the
+     *                  pool.
+     */
+    public GenericObjectPool(final PooledObjectFactory&lt;T&gt; factory,
+            final GenericObjectPoolConfig&lt;T&gt; config) {
+
+<span class="fc" id="L105">        super(config, ONAME_BASE, config.getJmxNamePrefix());</span>
+
+<span class="fc bfc" id="L107" title="All 2 branches covered.">        if (factory == null) {</span>
+<span class="fc" id="L108">            jmxUnregister(); // tidy up</span>
+<span class="fc" id="L109">            throw new IllegalArgumentException(&quot;factory may not be null&quot;);</span>
+        }
+<span class="fc" id="L111">        this.factory = factory;</span>
+
+<span class="fc" id="L113">        idleObjects = new LinkedBlockingDeque&lt;&gt;(config.getFairness());</span>
+
+<span class="fc" id="L115">        setConfig(config);</span>
+<span class="fc" id="L116">    }</span>
+
+    /**
+     * Creates a new &lt;code&gt;GenericObjectPool&lt;/code&gt; that tracks and destroys
+     * objects that are checked out, but never returned to the pool.
+     *
+     * @param factory   The object factory to be used to create object instances
+     *                  used by this pool
+     * @param config    The base pool configuration to use for this pool instance.
+     *                  The configuration is used by value. Subsequent changes to
+     *                  the configuration object will not be reflected in the
+     *                  pool.
+     * @param abandonedConfig  Configuration for abandoned object identification
+     *                         and removal.  The configuration is used by value.
+     */
+    public GenericObjectPool(final PooledObjectFactory&lt;T&gt; factory,
+            final GenericObjectPoolConfig&lt;T&gt; config, final AbandonedConfig abandonedConfig) {
+<span class="fc" id="L133">        this(factory, config);</span>
+<span class="fc" id="L134">        setAbandonedConfig(abandonedConfig);</span>
+<span class="fc" id="L135">    }</span>
+
+    /**
+     * Returns the cap on the number of &quot;idle&quot; instances in the pool. If maxIdle
+     * is set too low on heavily loaded systems it is possible you will see
+     * objects being destroyed and almost immediately new objects being created.
+     * This is a result of the active threads momentarily returning objects
+     * faster than they are requesting them, causing the number of idle
+     * objects to rise above maxIdle. The best value for maxIdle for heavily
+     * loaded system will vary but the default is a good starting point.
+     *
+     * @return the maximum number of &quot;idle&quot; instances that can be held in the
+     *         pool or a negative value if there is no limit
+     *
+     * @see #setMaxIdle
+     */
+    @Override
+    public int getMaxIdle() {
+<span class="fc" id="L153">        return maxIdle;</span>
+    }
+
+    /**
+     * Returns the cap on the number of &quot;idle&quot; instances in the pool. If maxIdle
+     * is set too low on heavily loaded systems it is possible you will see
+     * objects being destroyed and almost immediately new objects being created.
+     * This is a result of the active threads momentarily returning objects
+     * faster than they are requesting them, causing the number of idle
+     * objects to rise above maxIdle. The best value for maxIdle for heavily
+     * loaded system will vary but the default is a good starting point.
+     *
+     * @param maxIdle
+     *            The cap on the number of &quot;idle&quot; instances in the pool. Use a
+     *            negative value to indicate an unlimited number of idle
+     *            instances
+     *
+     * @see #getMaxIdle
+     */
+    public void setMaxIdle(final int maxIdle) {
+<span class="fc" id="L173">        this.maxIdle = maxIdle;</span>
+<span class="fc" id="L174">    }</span>
+
+    /**
+     * Sets the target for the minimum number of idle objects to maintain in
+     * the pool. This setting only has an effect if it is positive and
+     * {@link #getTimeBetweenEvictionRunsMillis()} is greater than zero. If this
+     * is the case, an attempt is made to ensure that the pool has the required
+     * minimum number of instances during idle object eviction runs.
+     * &lt;p&gt;
+     * If the configured value of minIdle is greater than the configured value
+     * for maxIdle then the value of maxIdle will be used instead.
+     * &lt;/p&gt;
+     *
+     * @param minIdle
+     *            The minimum number of objects.
+     *
+     * @see #getMinIdle()
+     * @see #getMaxIdle()
+     * @see #getTimeBetweenEvictionRunsMillis()
+     */
+    public void setMinIdle(final int minIdle) {
+<span class="fc" id="L195">        this.minIdle = minIdle;</span>
+<span class="fc" id="L196">    }</span>
+
+    /**
+     * Returns the target for the minimum number of idle objects to maintain in
+     * the pool. This setting only has an effect if it is positive and
+     * {@link #getTimeBetweenEvictionRunsMillis()} is greater than zero. If this
+     * is the case, an attempt is made to ensure that the pool has the required
+     * minimum number of instances during idle object eviction runs.
+     * &lt;p&gt;
+     * If the configured value of minIdle is greater than the configured value
+     * for maxIdle then the value of maxIdle will be used instead.
+     * &lt;/p&gt;
+     *
+     * @return The minimum number of objects.
+     *
+     * @see #setMinIdle(int)
+     * @see #setMaxIdle(int)
+     * @see #setTimeBetweenEvictionRunsMillis(long)
+     */
+    @Override
+    public int getMinIdle() {
+<span class="fc" id="L217">        final int maxIdleSave = getMaxIdle();</span>
+<span class="fc bfc" id="L218" title="All 2 branches covered.">        if (this.minIdle &gt; maxIdleSave) {</span>
+<span class="fc" id="L219">            return maxIdleSave;</span>
+        }
+<span class="fc" id="L221">        return minIdle;</span>
+    }
+
+    /**
+     * Gets whether or not abandoned object removal is configured for this pool.
+     *
+     * @return true if this pool is configured to detect and remove
+     * abandoned objects
+     */
+    @Override
+    public boolean isAbandonedConfig() {
+<span class="pc bpc" id="L232" title="1 of 2 branches missed.">        return abandonedConfig != null;</span>
+    }
+
+    /**
+     * Gets whether this pool identifies and logs any abandoned objects.
+     *
+     * @return {@code true} if abandoned object removal is configured for this
+     *         pool and removal events are to be logged otherwise {@code false}
+     *
+     * @see AbandonedConfig#getLogAbandoned()
+     */
+    @Override
+    public boolean getLogAbandoned() {
+<span class="nc" id="L245">        final AbandonedConfig ac = this.abandonedConfig;</span>
+<span class="nc bnc" id="L246" title="All 4 branches missed.">        return ac != null &amp;&amp; ac.getLogAbandoned();</span>
+    }
+
+    /**
+     * Gets whether a check is made for abandoned objects when an object is borrowed
+     * from this pool.
+     *
+     * @return {@code true} if abandoned object removal is configured to be
+     *         activated by borrowObject otherwise {@code false}
+     *
+     * @see AbandonedConfig#getRemoveAbandonedOnBorrow()
+     */
+    @Override
+    public boolean getRemoveAbandonedOnBorrow() {
+<span class="nc" id="L260">        final AbandonedConfig ac = this.abandonedConfig;</span>
+<span class="nc bnc" id="L261" title="All 4 branches missed.">        return ac != null &amp;&amp; ac.getRemoveAbandonedOnBorrow();</span>
+    }
+
+    /**
+     * Gets whether a check is made for abandoned objects when the evictor runs.
+     *
+     * @return {@code true} if abandoned object removal is configured to be
+     *         activated when the evictor runs otherwise {@code false}
+     *
+     * @see AbandonedConfig#getRemoveAbandonedOnMaintenance()
+     */
+    @Override
+    public boolean getRemoveAbandonedOnMaintenance() {
+<span class="nc" id="L274">        final AbandonedConfig ac = this.abandonedConfig;</span>
+<span class="nc bnc" id="L275" title="All 4 branches missed.">        return ac != null &amp;&amp; ac.getRemoveAbandonedOnMaintenance();</span>
+    }
+
+    /**
+     * Obtains the timeout before which an object will be considered to be
+     * abandoned by this pool.
+     *
+     * @return The abandoned object timeout in seconds if abandoned object
+     *         removal is configured for this pool; Integer.MAX_VALUE otherwise.
+     *
+     * @see AbandonedConfig#getRemoveAbandonedTimeout()
+     */
+    @Override
+    public int getRemoveAbandonedTimeout() {
+<span class="nc" id="L289">        final AbandonedConfig ac = this.abandonedConfig;</span>
+<span class="nc bnc" id="L290" title="All 2 branches missed.">        return ac != null ? ac.getRemoveAbandonedTimeout() : Integer.MAX_VALUE;</span>
+    }
+
+
+    /**
+     * Sets the base pool configuration.
+     *
+     * @param conf the new configuration to use. This is used by value.
+     *
+     * @see GenericObjectPoolConfig
+     */
+    public void setConfig(final GenericObjectPoolConfig&lt;T&gt; conf) {
+<span class="fc" id="L302">        super.setConfig(conf);</span>
+<span class="fc" id="L303">        setMaxIdle(conf.getMaxIdle());</span>
+<span class="fc" id="L304">        setMinIdle(conf.getMinIdle());</span>
+<span class="fc" id="L305">        setMaxTotal(conf.getMaxTotal());</span>
+<span class="fc" id="L306">    }</span>
+
+    /**
+     * Sets the abandoned object removal configuration.
+     *
+     * @param abandonedConfig the new configuration to use. This is used by value.
+     *
+     * @see AbandonedConfig
+     */
+    public void setAbandonedConfig(final AbandonedConfig abandonedConfig) {
+<span class="pc bpc" id="L316" title="1 of 2 branches missed.">        if (abandonedConfig == null) {</span>
+<span class="nc" id="L317">            this.abandonedConfig = null;</span>
+        } else {
+<span class="fc" id="L319">            this.abandonedConfig = new AbandonedConfig();</span>
+<span class="fc" id="L320">            this.abandonedConfig.setLogAbandoned(abandonedConfig.getLogAbandoned());</span>
+<span class="fc" id="L321">            this.abandonedConfig.setLogWriter(abandonedConfig.getLogWriter());</span>
+<span class="fc" id="L322">            this.abandonedConfig.setRemoveAbandonedOnBorrow(abandonedConfig.getRemoveAbandonedOnBorrow());</span>
+<span class="fc" id="L323">            this.abandonedConfig.setRemoveAbandonedOnMaintenance(abandonedConfig.getRemoveAbandonedOnMaintenance());</span>
+<span class="fc" id="L324">            this.abandonedConfig.setRemoveAbandonedTimeout(abandonedConfig.getRemoveAbandonedTimeout());</span>
+<span class="fc" id="L325">            this.abandonedConfig.setUseUsageTracking(abandonedConfig.getUseUsageTracking());</span>
+<span class="fc" id="L326">            this.abandonedConfig.setRequireFullStackTrace(abandonedConfig.getRequireFullStackTrace());</span>
+        }
+<span class="fc" id="L328">    }</span>
+
+    /**
+     * Obtains a reference to the factory used to create, destroy and validate
+     * the objects used by this pool.
+     *
+     * @return the factory
+     */
+    public PooledObjectFactory&lt;T&gt; getFactory() {
+<span class="nc" id="L337">        return factory;</span>
+    }
+
+    /**
+     * Equivalent to &lt;code&gt;{@link #borrowObject(long)
+     * borrowObject}({@link #getMaxWaitMillis()})&lt;/code&gt;.
+     * &lt;p&gt;
+     * {@inheritDoc}
+     * &lt;/p&gt;
+     */
+    @Override
+    public T borrowObject() throws Exception {
+<span class="fc" id="L349">        return borrowObject(getMaxWaitMillis());</span>
+    }
+
+    /**
+     * Borrows an object from the pool using the specific waiting time which only
+     * applies if {@link #getBlockWhenExhausted()} is true.
+     * &lt;p&gt;
+     * If there is one or more idle instance available in the pool, then an
+     * idle instance will be selected based on the value of {@link #getLifo()},
+     * activated and returned. If activation fails, or {@link #getTestOnBorrow()
+     * testOnBorrow} is set to &lt;code&gt;true&lt;/code&gt; and validation fails, the
+     * instance is destroyed and the next available instance is examined. This
+     * continues until either a valid instance is returned or there are no more
+     * idle instances available.
+     * &lt;/p&gt;
+     * &lt;p&gt;
+     * If there are no idle instances available in the pool, behavior depends on
+     * the {@link #getMaxTotal() maxTotal}, (if applicable)
+     * {@link #getBlockWhenExhausted()} and the value passed in to the
+     * &lt;code&gt;borrowMaxWaitMillis&lt;/code&gt; parameter. If the number of instances
+     * checked out from the pool is less than &lt;code&gt;maxTotal,&lt;/code&gt; a new
+     * instance is created, activated and (if applicable) validated and returned
+     * to the caller. If validation fails, a &lt;code&gt;NoSuchElementException&lt;/code&gt;
+     * is thrown.
+     * &lt;/p&gt;
+     * &lt;p&gt;
+     * If the pool is exhausted (no available idle instances and no capacity to
+     * create new ones), this method will either block (if
+     * {@link #getBlockWhenExhausted()} is true) or throw a
+     * &lt;code&gt;NoSuchElementException&lt;/code&gt; (if
+     * {@link #getBlockWhenExhausted()} is false). The length of time that this
+     * method will block when {@link #getBlockWhenExhausted()} is true is
+     * determined by the value passed in to the &lt;code&gt;borrowMaxWaitMillis&lt;/code&gt;
+     * parameter.
+     * &lt;/p&gt;
+     * &lt;p&gt;
+     * When the pool is exhausted, multiple calling threads may be
+     * simultaneously blocked waiting for instances to become available. A
+     * &quot;fairness&quot; algorithm has been implemented to ensure that threads receive
+     * available instances in request arrival order.
+     * &lt;/p&gt;
+     *
+     * @param borrowMaxWaitMillis The time to wait in milliseconds for an object
+     *                            to become available
+     *
+     * @return object instance from the pool
+     *
+     * @throws NoSuchElementException if an instance cannot be returned
+     *
+     * @throws Exception if an object instance cannot be returned due to an
+     *                   error
+     */
+    public T borrowObject(final long borrowMaxWaitMillis) throws Exception {
+<span class="fc" id="L402">        assertOpen();</span>
+
+<span class="fc" id="L404">        final AbandonedConfig ac = this.abandonedConfig;</span>
+<span class="fc bfc" id="L405" title="All 4 branches covered.">        if (ac != null &amp;&amp; ac.getRemoveAbandonedOnBorrow() &amp;&amp;</span>
+<span class="pc bpc" id="L406" title="1 of 2 branches missed.">                (getNumIdle() &lt; 2) &amp;&amp;</span>
+<span class="fc bfc" id="L407" title="All 2 branches covered.">                (getNumActive() &gt; getMaxTotal() - 3) ) {</span>
+<span class="fc" id="L408">            removeAbandoned(ac);</span>
+        }
+
+<span class="fc" id="L411">        PooledObject&lt;T&gt; p = null;</span>
+
+        // Get local copy of current config so it is consistent for entire
+        // method execution
+<span class="fc" id="L415">        final boolean blockWhenExhausted = getBlockWhenExhausted();</span>
+
+        boolean create;
+<span class="fc" id="L418">        final long waitTime = System.currentTimeMillis();</span>
+
+<span class="fc bfc" id="L420" title="All 2 branches covered.">        while (p == null) {</span>
+<span class="fc" id="L421">            create = false;</span>
+<span class="fc" id="L422">            p = idleObjects.pollFirst();</span>
+<span class="fc bfc" id="L423" title="All 2 branches covered.">            if (p == null) {</span>
+<span class="fc" id="L424">                p = create();</span>
+<span class="fc bfc" id="L425" title="All 2 branches covered.">                if (p != null) {</span>
+<span class="fc" id="L426">                    create = true;</span>
+                }
+            }
+<span class="fc bfc" id="L429" title="All 2 branches covered.">            if (blockWhenExhausted) {</span>
+<span class="fc bfc" id="L430" title="All 2 branches covered.">                if (p == null) {</span>
+<span class="fc bfc" id="L431" title="All 2 branches covered.">                    if (borrowMaxWaitMillis &lt; 0) {</span>
+<span class="fc" id="L432">                        p = idleObjects.takeFirst();</span>
+                    } else {
+<span class="fc" id="L434">                        p = idleObjects.pollFirst(borrowMaxWaitMillis,</span>
+                                TimeUnit.MILLISECONDS);
+                    }
+                }
+<span class="fc bfc" id="L438" title="All 2 branches covered.">                if (p == null) {</span>
+<span class="fc" id="L439">                    throw new NoSuchElementException(</span>
+                            &quot;Timeout waiting for idle object&quot;);
+                }
+            } else {
+<span class="fc bfc" id="L443" title="All 2 branches covered.">                if (p == null) {</span>
+<span class="fc" id="L444">                    throw new NoSuchElementException(&quot;Pool exhausted&quot;);</span>
+                }
+            }
+<span class="fc bfc" id="L447" title="All 2 branches covered.">            if (!p.allocate()) {</span>
+<span class="fc" id="L448">                p = null;</span>
+            }
+
+<span class="fc bfc" id="L451" title="All 2 branches covered.">            if (p != null) {</span>
+                try {
+<span class="fc" id="L453">                    factory.activateObject(p);</span>
+<span class="fc" id="L454">                } catch (final Exception e) {</span>
+                    try {
+<span class="fc" id="L456">                        destroy(p);</span>
+<span class="nc" id="L457">                    } catch (final Exception e1) {</span>
+                        // Ignore - activation failure is more important
+<span class="fc" id="L459">                    }</span>
+<span class="fc" id="L460">                    p = null;</span>
+<span class="fc bfc" id="L461" title="All 2 branches covered.">                    if (create) {</span>
+<span class="fc" id="L462">                        final NoSuchElementException nsee = new NoSuchElementException(</span>
+                                &quot;Unable to activate object&quot;);
+<span class="fc" id="L464">                        nsee.initCause(e);</span>
+<span class="fc" id="L465">                        throw nsee;</span>
+                    }
+<span class="fc" id="L467">                }</span>
+<span class="fc bfc" id="L468" title="All 4 branches covered.">                if (p != null &amp;&amp; getTestOnBorrow()) {</span>
+<span class="fc" id="L469">                    boolean validate = false;</span>
+<span class="fc" id="L470">                    Throwable validationThrowable = null;</span>
+                    try {
+<span class="fc" id="L472">                        validate = factory.validateObject(p);</span>
+<span class="fc" id="L473">                    } catch (final Throwable t) {</span>
+<span class="fc" id="L474">                        PoolUtils.checkRethrow(t);</span>
+<span class="fc" id="L475">                        validationThrowable = t;</span>
+<span class="fc" id="L476">                    }</span>
+<span class="fc bfc" id="L477" title="All 2 branches covered.">                    if (!validate) {</span>
+                        try {
+<span class="fc" id="L479">                            destroy(p);</span>
+<span class="fc" id="L480">                            destroyedByBorrowValidationCount.incrementAndGet();</span>
+<span class="fc" id="L481">                        } catch (final Exception e) {</span>
+                            // Ignore - validation failure is more important
+<span class="fc" id="L483">                        }</span>
+<span class="fc" id="L484">                        p = null;</span>
+<span class="fc bfc" id="L485" title="All 2 branches covered.">                        if (create) {</span>
+<span class="fc" id="L486">                            final NoSuchElementException nsee = new NoSuchElementException(</span>
+                                    &quot;Unable to validate object&quot;);
+<span class="fc" id="L488">                            nsee.initCause(validationThrowable);</span>
+<span class="fc" id="L489">                            throw nsee;</span>
+                        }
+                    }
+<span class="fc" id="L492">                }</span>
+            }
+        }
+
+<span class="fc" id="L496">        updateStatsBorrow(p, System.currentTimeMillis() - waitTime);</span>
+
+<span class="fc" id="L498">        return p.getObject();</span>
+    }
+
+    /**
+     * {@inheritDoc}
+     * &lt;p&gt;
+     * If {@link #getMaxIdle() maxIdle} is set to a positive value and the
+     * number of idle instances has reached this value, the returning instance
+     * is destroyed.
+     * &lt;/p&gt;
+     * &lt;p&gt;
+     * If {@link #getTestOnReturn() testOnReturn} == true, the returning
+     * instance is validated before being returned to the idle instance pool. In
+     * this case, if validation fails, the instance is destroyed.
+     * &lt;/p&gt;
+     * &lt;p&gt;
+     * Exceptions encountered destroying objects for any reason are swallowed
+     * but notified via a {@link SwallowedExceptionListener}.
+     * &lt;/p&gt;
+     */
+    @Override
+    public void returnObject(final T obj) {
+<span class="fc" id="L520">        final PooledObject&lt;T&gt; p = allObjects.get(new IdentityWrapper&lt;&gt;(obj));</span>
+
+<span class="pc bpc" id="L522" title="1 of 2 branches missed.">        if (p == null) {</span>
+<span class="nc bnc" id="L523" title="All 2 branches missed.">            if (!isAbandonedConfig()) {</span>
+<span class="nc" id="L524">                throw new IllegalStateException(</span>
+                        &quot;Returned object not currently part of this pool&quot;);
+            }
+<span class="nc" id="L527">            return; // Object was abandoned and removed</span>
+        }
+
+<span class="fc" id="L530">        markReturningState(p);</span>
+
+<span class="fc" id="L532">        final long activeTime = p.getActiveTimeMillis();</span>
+
+<span class="fc bfc" id="L534" title="All 4 branches covered.">        if (getTestOnReturn() &amp;&amp; !factory.validateObject(p)) {</span>
+            try {
+<span class="fc" id="L536">                destroy(p);</span>
+<span class="fc" id="L537">            } catch (final Exception e) {</span>
+<span class="fc" id="L538">                swallowException(e);</span>
+<span class="fc" id="L539">            }</span>
+            try {
+<span class="fc" id="L541">                ensureIdle(1, false);</span>
+<span class="nc" id="L542">            } catch (final Exception e) {</span>
+<span class="nc" id="L543">                swallowException(e);</span>
+<span class="fc" id="L544">            }</span>
+<span class="fc" id="L545">            updateStatsReturn(activeTime);</span>
+<span class="fc" id="L546">            return;</span>
+        }
+
+        try {
+<span class="fc" id="L550">            factory.passivateObject(p);</span>
+<span class="fc" id="L551">        } catch (final Exception e1) {</span>
+<span class="fc" id="L552">            swallowException(e1);</span>
+            try {
+<span class="fc" id="L554">                destroy(p);</span>
+<span class="fc" id="L555">            } catch (final Exception e) {</span>
+<span class="fc" id="L556">                swallowException(e);</span>
+<span class="fc" id="L557">            }</span>
+            try {
+<span class="fc" id="L559">                ensureIdle(1, false);</span>
+<span class="nc" id="L560">            } catch (final Exception e) {</span>
+<span class="nc" id="L561">                swallowException(e);</span>
+<span class="fc" id="L562">            }</span>
+<span class="fc" id="L563">            updateStatsReturn(activeTime);</span>
+<span class="fc" id="L564">            return;</span>
+<span class="fc" id="L565">        }</span>
+
+<span class="pc bpc" id="L567" title="1 of 2 branches missed.">        if (!p.deallocate()) {</span>
+<span class="nc" id="L568">            throw new IllegalStateException(</span>
+                    &quot;Object has already been returned to this pool or is invalid&quot;);
+        }
+
+<span class="fc" id="L572">        final int maxIdleSave = getMaxIdle();</span>
+<span class="fc bfc" id="L573" title="All 6 branches covered.">        if (isClosed() || maxIdleSave &gt; -1 &amp;&amp; maxIdleSave &lt;= idleObjects.size()) {</span>
+            try {
+<span class="fc" id="L575">                destroy(p);</span>
+<span class="fc" id="L576">            } catch (final Exception e) {</span>
+<span class="fc" id="L577">                swallowException(e);</span>
+<span class="fc" id="L578">            }</span>
+        } else {
+<span class="fc bfc" id="L580" title="All 2 branches covered.">            if (getLifo()) {</span>
+<span class="fc" id="L581">                idleObjects.addFirst(p);</span>
+            } else {
+<span class="fc" id="L583">                idleObjects.addLast(p);</span>
+            }
+<span class="pc bpc" id="L585" title="1 of 2 branches missed.">            if (isClosed()) {</span>
+                // Pool closed while object was being added to idle objects.
+                // Make sure the returned object is destroyed rather than left
+                // in the idle object pool (which would effectively be a leak)
+<span class="nc" id="L589">                clear();</span>
+            }
+        }
+<span class="fc" id="L592">        updateStatsReturn(activeTime);</span>
+<span class="fc" id="L593">    }</span>
+
+    /**
+     * {@inheritDoc}
+     * &lt;p&gt;
+     * Activation of this method decrements the active count and attempts to
+     * destroy the instance.
+     * &lt;/p&gt;
+     *
+     * @throws Exception             if an exception occurs destroying the
+     *                               object
+     * @throws IllegalStateException if obj does not belong to this pool
+     */
+    @Override
+    public void invalidateObject(final T obj) throws Exception {
+<span class="fc" id="L608">        final PooledObject&lt;T&gt; p = allObjects.get(new IdentityWrapper&lt;&gt;(obj));</span>
+<span class="fc bfc" id="L609" title="All 2 branches covered.">        if (p == null) {</span>
+<span class="pc bpc" id="L610" title="1 of 2 branches missed.">            if (isAbandonedConfig()) {</span>
+<span class="nc" id="L611">                return;</span>
+            }
+<span class="fc" id="L613">            throw new IllegalStateException(</span>
+                    &quot;Invalidated object not currently part of this pool&quot;);
+        }
+<span class="fc" id="L616">        synchronized (p) {</span>
+<span class="fc bfc" id="L617" title="All 2 branches covered.">            if (p.getState() != PooledObjectState.INVALID) {</span>
+<span class="fc" id="L618">                destroy(p);</span>
+            }
+<span class="fc" id="L620">        }</span>
+<span class="fc" id="L621">        ensureIdle(1, false);</span>
+<span class="fc" id="L622">    }</span>
+
+    /**
+     * Clears any objects sitting idle in the pool by removing them from the
+     * idle instance pool and then invoking the configured
+     * {@link PooledObjectFactory#destroyObject(PooledObject)} method on each
+     * idle instance.
+     * &lt;p&gt;
+     * Implementation notes:
+     * &lt;/p&gt;
+     * &lt;ul&gt;
+     * &lt;li&gt;This method does not destroy or effect in any way instances that are
+     * checked out of the pool when it is invoked.&lt;/li&gt;
+     * &lt;li&gt;Invoking this method does not prevent objects being returned to the
+     * idle instance pool, even during its execution. Additional instances may
+     * be returned while removed items are being destroyed.&lt;/li&gt;
+     * &lt;li&gt;Exceptions encountered destroying idle instances are swallowed
+     * but notified via a {@link SwallowedExceptionListener}.&lt;/li&gt;
+     * &lt;/ul&gt;
+     */
+    @Override
+    public void clear() {
+<span class="fc" id="L644">        PooledObject&lt;T&gt; p = idleObjects.poll();</span>
+
+<span class="fc bfc" id="L646" title="All 2 branches covered.">        while (p != null) {</span>
+            try {
+<span class="fc" id="L648">                destroy(p);</span>
+<span class="fc" id="L649">            } catch (final Exception e) {</span>
+<span class="fc" id="L650">                swallowException(e);</span>
+<span class="fc" id="L651">            }</span>
+<span class="fc" id="L652">            p = idleObjects.poll();</span>
+        }
+<span class="fc" id="L654">    }</span>
+
+    @Override
+    public int getNumActive() {
+<span class="fc" id="L658">        return allObjects.size() - idleObjects.size();</span>
+    }
+
+    @Override
+    public int getNumIdle() {
+<span class="fc" id="L663">        return idleObjects.size();</span>
+    }
+
+    /**
+     * Closes the pool. Once the pool is closed, {@link #borrowObject()} will
+     * fail with IllegalStateException, but {@link #returnObject(Object)} and
+     * {@link #invalidateObject(Object)} will continue to work, with returned
+     * objects destroyed on return.
+     * &lt;p&gt;
+     * Destroys idle instances in the pool by invoking {@link #clear()}.
+     * &lt;/p&gt;
+     */
+    @Override
+    public void close() {
+<span class="fc bfc" id="L677" title="All 2 branches covered.">        if (isClosed()) {</span>
+<span class="fc" id="L678">            return;</span>
+        }
+
+<span class="fc" id="L681">        synchronized (closeLock) {</span>
+<span class="pc bpc" id="L682" title="1 of 2 branches missed.">            if (isClosed()) {</span>
+<span class="nc" id="L683">                return;</span>
+            }
+
+            // Stop the evictor before the pool is closed since evict() calls
+            // assertOpen()
+<span class="fc" id="L688">            stopEvictor();</span>
+
+<span class="fc" id="L690">            closed = true;</span>
+            // This clear removes any idle objects
+<span class="fc" id="L692">            clear();</span>
+
+<span class="fc" id="L694">            jmxUnregister();</span>
+
+            // Release any threads that were waiting for an object
+<span class="fc" id="L697">            idleObjects.interuptTakeWaiters();</span>
+<span class="fc" id="L698">        }</span>
+<span class="fc" id="L699">    }</span>
+
+    /**
+     * {@inheritDoc}
+     * &lt;p&gt;
+     * Successive activations of this method examine objects in sequence,
+     * cycling through objects in oldest-to-youngest order.
+     * &lt;/p&gt;
+     */
+    @Override
+    public void evict() throws Exception {
+<span class="fc" id="L710">        assertOpen();</span>
+
+<span class="fc bfc" id="L712" title="All 2 branches covered.">        if (idleObjects.size() &gt; 0) {</span>
+
+<span class="fc" id="L714">            PooledObject&lt;T&gt; underTest = null;</span>
+<span class="fc" id="L715">            final EvictionPolicy&lt;T&gt; evictionPolicy = getEvictionPolicy();</span>
+
+<span class="fc" id="L717">            synchronized (evictionLock) {</span>
+<span class="fc" id="L718">                final EvictionConfig evictionConfig = new EvictionConfig(</span>
+<span class="fc" id="L719">                        getMinEvictableIdleTimeMillis(),</span>
+<span class="fc" id="L720">                        getSoftMinEvictableIdleTimeMillis(),</span>
+<span class="fc" id="L721">                        getMinIdle());</span>
+
+<span class="fc" id="L723">                final boolean testWhileIdle = getTestWhileIdle();</span>
+
+<span class="fc bfc" id="L725" title="All 2 branches covered.">                for (int i = 0, m = getNumTests(); i &lt; m; i++) {</span>
+<span class="fc bfc" id="L726" title="All 4 branches covered.">                    if (evictionIterator == null || !evictionIterator.hasNext()) {</span>
+<span class="fc" id="L727">                        evictionIterator = new EvictionIterator(idleObjects);</span>
+                    }
+<span class="fc bfc" id="L729" title="All 2 branches covered.">                    if (!evictionIterator.hasNext()) {</span>
+                        // Pool exhausted, nothing to do here
+<span class="fc" id="L731">                        return;</span>
+                    }
+
+                    try {
+<span class="fc" id="L735">                        underTest = evictionIterator.next();</span>
+<span class="nc" id="L736">                    } catch (final NoSuchElementException nsee) {</span>
+                        // Object was borrowed in another thread
+                        // Don't count this as an eviction test so reduce i;
+<span class="nc" id="L739">                        i--;</span>
+<span class="nc" id="L740">                        evictionIterator = null;</span>
+<span class="nc" id="L741">                        continue;</span>
+<span class="fc" id="L742">                    }</span>
+
+<span class="fc bfc" id="L744" title="All 2 branches covered.">                    if (!underTest.startEvictionTest()) {</span>
+                        // Object was borrowed in another thread
+                        // Don't count this as an eviction test so reduce i;
+<span class="fc" id="L747">                        i--;</span>
+<span class="fc" id="L748">                        continue;</span>
+                    }
+
+                    // User provided eviction policy could throw all sorts of
+                    // crazy exceptions. Protect against such an exception
+                    // killing the eviction thread.
+                    boolean evict;
+                    try {
+<span class="fc" id="L756">                        evict = evictionPolicy.evict(evictionConfig, underTest,</span>
+<span class="fc" id="L757">                                idleObjects.size());</span>
+<span class="nc" id="L758">                    } catch (final Throwable t) {</span>
+                        // Slightly convoluted as SwallowedExceptionListener
+                        // uses Exception rather than Throwable
+<span class="nc" id="L761">                        PoolUtils.checkRethrow(t);</span>
+<span class="nc" id="L762">                        swallowException(new Exception(t));</span>
+                        // Don't evict on error conditions
+<span class="nc" id="L764">                        evict = false;</span>
+<span class="fc" id="L765">                    }</span>
+
+<span class="fc bfc" id="L767" title="All 2 branches covered.">                    if (evict) {</span>
+<span class="fc" id="L768">                        destroy(underTest);</span>
+<span class="fc" id="L769">                        destroyedByEvictorCount.incrementAndGet();</span>
+                    } else {
+<span class="fc bfc" id="L771" title="All 2 branches covered.">                        if (testWhileIdle) {</span>
+<span class="fc" id="L772">                            boolean active = false;</span>
+                            try {
+<span class="fc" id="L774">                                factory.activateObject(underTest);</span>
+<span class="fc" id="L775">                                active = true;</span>
+<span class="fc" id="L776">                            } catch (final Exception e) {</span>
+<span class="fc" id="L777">                                destroy(underTest);</span>
+<span class="fc" id="L778">                                destroyedByEvictorCount.incrementAndGet();</span>
+<span class="fc" id="L779">                            }</span>
+<span class="fc bfc" id="L780" title="All 2 branches covered.">                            if (active) {</span>
+<span class="fc bfc" id="L781" title="All 2 branches covered.">                                if (!factory.validateObject(underTest)) {</span>
+<span class="fc" id="L782">                                    destroy(underTest);</span>
+<span class="fc" id="L783">                                    destroyedByEvictorCount.incrementAndGet();</span>
+                                } else {
+                                    try {
+<span class="fc" id="L786">                                        factory.passivateObject(underTest);</span>
+<span class="nc" id="L787">                                    } catch (final Exception e) {</span>
+<span class="nc" id="L788">                                        destroy(underTest);</span>
+<span class="nc" id="L789">                                        destroyedByEvictorCount.incrementAndGet();</span>
+<span class="fc" id="L790">                                    }</span>
+                                }
+                            }
+                        }
+<span class="fc bfc" id="L794" title="All 2 branches covered.">                        if (!underTest.endEvictionTest(idleObjects)) {</span>
+                            // TODO - May need to add code here once additional
+                            // states are used
+                        }
+                    }
+                }
+<span class="fc" id="L800">            }</span>
+        }
+<span class="fc" id="L802">        final AbandonedConfig ac = this.abandonedConfig;</span>
+<span class="pc bpc" id="L803" title="1 of 4 branches missed.">        if (ac != null &amp;&amp; ac.getRemoveAbandonedOnMaintenance()) {</span>
+<span class="fc" id="L804">            removeAbandoned(ac);</span>
+        }
+<span class="fc" id="L806">    }</span>
+
+    /**
+     * Tries to ensure that {@link #getMinIdle()} idle instances are available
+     * in the pool.
+     *
+     * @throws Exception If the associated factory throws an exception
+     * @since 2.4
+     */
+    public void preparePool() throws Exception {
+<span class="nc bnc" id="L816" title="All 2 branches missed.">        if (getMinIdle() &lt; 1) {</span>
+<span class="nc" id="L817">            return;</span>
+        }
+<span class="nc" id="L819">        ensureMinIdle();</span>
+<span class="nc" id="L820">    }</span>
+
+    /**
+     * Attempts to create a new wrapped pooled object.
+     * &lt;p&gt;
+     * If there are {@link #getMaxTotal()} objects already in circulation
+     * or in process of being created, this method returns null.
+     * &lt;/p&gt;
+     *
+     * @return The new wrapped pooled object
+     *
+     * @throws Exception if the object factory's {@code makeObject} fails
+     */
+    private PooledObject&lt;T&gt; create() throws Exception {
+<span class="fc" id="L834">        int localMaxTotal = getMaxTotal();</span>
+        // This simplifies the code later in this method
+<span class="fc bfc" id="L836" title="All 2 branches covered.">        if (localMaxTotal &lt; 0) {</span>
+<span class="fc" id="L837">            localMaxTotal = Integer.MAX_VALUE;</span>
+        }
+
+<span class="fc" id="L840">        final long localStartTimeMillis = System.currentTimeMillis();</span>
+<span class="fc" id="L841">        final long localMaxWaitTimeMillis = Math.max(getMaxWaitMillis(), 0);</span>
+
+        // Flag that indicates if create should:
+        // - TRUE:  call the factory to create an object
+        // - FALSE: return null
+        // - null:  loop and re-test the condition that determines whether to
+        //          call the factory
+<span class="fc" id="L848">        Boolean create = null;</span>
+<span class="fc bfc" id="L849" title="All 2 branches covered.">        while (create == null) {</span>
+<span class="fc" id="L850">            synchronized (makeObjectCountLock) {</span>
+<span class="fc" id="L851">                final long newCreateCount = createCount.incrementAndGet();</span>
+<span class="fc bfc" id="L852" title="All 2 branches covered.">                if (newCreateCount &gt; localMaxTotal) {</span>
+                    // The pool is currently at capacity or in the process of
+                    // making enough new objects to take it to capacity.
+<span class="fc" id="L855">                    createCount.decrementAndGet();</span>
+<span class="fc bfc" id="L856" title="All 2 branches covered.">                    if (makeObjectCount == 0) {</span>
+                        // There are no makeObject() calls in progress so the
+                        // pool is at capacity. Do not attempt to create a new
+                        // object. Return and wait for an object to be returned
+<span class="fc" id="L860">                        create = Boolean.FALSE;</span>
+                    } else {
+                        // There are makeObject() calls in progress that might
+                        // bring the pool to capacity. Those calls might also
+                        // fail so wait until they complete and then re-test if
+                        // the pool is at capacity or not.
+<span class="fc" id="L866">                        makeObjectCountLock.wait(localMaxWaitTimeMillis);</span>
+                    }
+                } else {
+                    // The pool is not at capacity. Create a new object.
+<span class="fc" id="L870">                    makeObjectCount++;</span>
+<span class="fc" id="L871">                    create = Boolean.TRUE;</span>
+                }
+<span class="fc" id="L873">            }</span>
+
+            // Do not block more if maxWaitTimeMillis is set.
+<span class="fc bfc" id="L876" title="All 4 branches covered.">            if (create == null &amp;&amp;</span>
+                (localMaxWaitTimeMillis &gt; 0 &amp;&amp;
+<span class="fc bfc" id="L878" title="All 2 branches covered.">                 System.currentTimeMillis() - localStartTimeMillis &gt;= localMaxWaitTimeMillis)) {</span>
+<span class="fc" id="L879">                create = Boolean.FALSE;</span>
+            }
+        }
+
+<span class="fc bfc" id="L883" title="All 2 branches covered.">        if (!create.booleanValue()) {</span>
+<span class="fc" id="L884">            return null;</span>
+        }
+
+        final PooledObject&lt;T&gt; p;
+        try {
+<span class="fc" id="L889">            p = factory.makeObject();</span>
+<span class="fc bfc" id="L890" title="All 4 branches covered.">            if (getTestOnCreate() &amp;&amp; !factory.validateObject(p)) {</span>
+<span class="fc" id="L891">                createCount.decrementAndGet();</span>
+<span class="fc" id="L892">                return null;</span>
+            }
+<span class="fc" id="L894">        } catch (final Throwable e) {</span>
+<span class="fc" id="L895">            createCount.decrementAndGet();</span>
+<span class="fc" id="L896">            throw e;</span>
+        } finally {
+<span class="fc" id="L898">            synchronized (makeObjectCountLock) {</span>
+<span class="fc" id="L899">                makeObjectCount--;</span>
+<span class="fc" id="L900">                makeObjectCountLock.notifyAll();</span>
+<span class="fc" id="L901">            }</span>
+        }
+
+<span class="fc" id="L904">        final AbandonedConfig ac = this.abandonedConfig;</span>
+<span class="fc bfc" id="L905" title="All 4 branches covered.">        if (ac != null &amp;&amp; ac.getLogAbandoned()) {</span>
+<span class="fc" id="L906">            p.setLogAbandoned(true);</span>
+<span class="fc" id="L907">            p.setRequireFullStackTrace(ac.getRequireFullStackTrace());</span>
+        }
+
+<span class="fc" id="L910">        createdCount.incrementAndGet();</span>
+<span class="fc" id="L911">        allObjects.put(new IdentityWrapper&lt;&gt;(p.getObject()), p);</span>
+<span class="fc" id="L912">        return p;</span>
+    }
+
+    /**
+     * Destroys a wrapped pooled object.
+     *
+     * @param toDestroy The wrapped pooled object to destroy
+     *
+     * @throws Exception If the factory fails to destroy the pooled object
+     *                   cleanly
+     */
+    private void destroy(final PooledObject&lt;T&gt; toDestroy) throws Exception {
+<span class="fc" id="L924">        toDestroy.invalidate();</span>
+<span class="fc" id="L925">        idleObjects.remove(toDestroy);</span>
+<span class="fc" id="L926">        allObjects.remove(new IdentityWrapper&lt;&gt;(toDestroy.getObject()));</span>
+        try {
+<span class="fc" id="L928">            factory.destroyObject(toDestroy);</span>
+        } finally {
+<span class="fc" id="L930">            destroyedCount.incrementAndGet();</span>
+<span class="fc" id="L931">            createCount.decrementAndGet();</span>
+        }
+
+<span class="fc bfc" id="L934" title="All 4 branches covered.">        if (idleObjects.isEmpty() &amp;&amp; idleObjects.hasTakeWaiters()) {</span>
+            // POOL-356.
+            // In case there are already threads waiting on something in the pool
+            // (e.g. idleObjects.takeFirst(); then we need to provide them a fresh instance.
+            // Otherwise they will be stuck forever (or until timeout)
+<span class="fc" id="L939">            final PooledObject&lt;T&gt; freshPooled = create();</span>
+<span class="fc" id="L940">            idleObjects.put(freshPooled);</span>
+        }
+<span class="fc" id="L942">    }</span>
+
+    @Override
+    void ensureMinIdle() throws Exception {
+<span class="fc" id="L946">        ensureIdle(getMinIdle(), true);</span>
+<span class="fc" id="L947">    }</span>
+
+    /**
+     * Tries to ensure that {@code idleCount} idle instances exist in the pool.
+     * &lt;p&gt;
+     * Creates and adds idle instances until either {@link #getNumIdle()} reaches {@code idleCount}
+     * or the total number of objects (idle, checked out, or being created) reaches
+     * {@link #getMaxTotal()}. If {@code always} is false, no instances are created unless
+     * there are threads waiting to check out instances from the pool.
+     * &lt;/p&gt;
+     *
+     * @param idleCount the number of idle instances desired
+     * @param always true means create instances even if the pool has no threads waiting
+     * @throws Exception if the factory's makeObject throws
+     */
+    private void ensureIdle(final int idleCount, final boolean always) throws Exception {
+<span class="pc bpc" id="L963" title="1 of 8 branches missed.">        if (idleCount &lt; 1 || isClosed() || (!always &amp;&amp; !idleObjects.hasTakeWaiters())) {</span>
+<span class="fc" id="L964">            return;</span>
+        }
+
+<span class="fc bfc" id="L967" title="All 2 branches covered.">        while (idleObjects.size() &lt; idleCount) {</span>
+<span class="fc" id="L968">            final PooledObject&lt;T&gt; p = create();</span>
+<span class="fc bfc" id="L969" title="All 2 branches covered.">            if (p == null) {</span>
+                // Can't create objects, no reason to think another call to
+                // create will work. Give up.
+<span class="fc" id="L972">                break;</span>
+            }
+<span class="pc bpc" id="L974" title="1 of 2 branches missed.">            if (getLifo()) {</span>
+<span class="fc" id="L975">                idleObjects.addFirst(p);</span>
+            } else {
+<span class="nc" id="L977">                idleObjects.addLast(p);</span>
+            }
+<span class="fc" id="L979">        }</span>
+<span class="pc bpc" id="L980" title="1 of 2 branches missed.">        if (isClosed()) {</span>
+            // Pool closed while object was being added to idle objects.
+            // Make sure the returned object is destroyed rather than left
+            // in the idle object pool (which would effectively be a leak)
+<span class="nc" id="L984">            clear();</span>
+        }
+<span class="fc" id="L986">    }</span>
+
+    /**
+     * Creates an object, and place it into the pool. addObject() is useful for
+     * &quot;pre-loading&quot; a pool with idle objects.
+     * &lt;p&gt;
+     * If there is no capacity available to add to the pool, this is a no-op
+     * (no exception, no impact to the pool). &lt;/p&gt;
+     */
+    @Override
+    public void addObject() throws Exception {
+<span class="fc" id="L997">        assertOpen();</span>
+<span class="pc bpc" id="L998" title="1 of 2 branches missed.">        if (factory == null) {</span>
+<span class="nc" id="L999">            throw new IllegalStateException(</span>
+                    &quot;Cannot add objects without a factory.&quot;);
+        }
+<span class="fc" id="L1002">        final PooledObject&lt;T&gt; p = create();</span>
+<span class="fc" id="L1003">        addIdleObject(p);</span>
+<span class="fc" id="L1004">    }</span>
+
+    /**
+     * Adds the provided wrapped pooled object to the set of idle objects for
+     * this pool. The object must already be part of the pool.  If {@code p}
+     * is null, this is a no-op (no exception, but no impact on the pool).
+     *
+     * @param p The object to make idle
+     *
+     * @throws Exception If the factory fails to passivate the object
+     */
+    private void addIdleObject(final PooledObject&lt;T&gt; p) throws Exception {
+<span class="fc bfc" id="L1016" title="All 2 branches covered.">        if (p != null) {</span>
+<span class="fc" id="L1017">            factory.passivateObject(p);</span>
+<span class="fc bfc" id="L1018" title="All 2 branches covered.">            if (getLifo()) {</span>
+<span class="fc" id="L1019">                idleObjects.addFirst(p);</span>
+            } else {
+<span class="fc" id="L1021">                idleObjects.addLast(p);</span>
+            }
+        }
+<span class="fc" id="L1024">    }</span>
+
+    /**
+     * Calculates the number of objects to test in a run of the idle object
+     * evictor.
+     *
+     * @return The number of objects to test for validity
+     */
+    private int getNumTests() {
+<span class="fc" id="L1033">        final int numTestsPerEvictionRun = getNumTestsPerEvictionRun();</span>
+<span class="fc bfc" id="L1034" title="All 2 branches covered.">        if (numTestsPerEvictionRun &gt;= 0) {</span>
+<span class="fc" id="L1035">            return Math.min(numTestsPerEvictionRun, idleObjects.size());</span>
+        }
+<span class="fc" id="L1037">        return (int) (Math.ceil(idleObjects.size() /</span>
+<span class="fc" id="L1038">                Math.abs((double) numTestsPerEvictionRun)));</span>
+    }
+
+    /**
+     * Recovers abandoned objects which have been checked out but
+     * not used since longer than the removeAbandonedTimeout.
+     *
+     * @param ac The configuration to use to identify abandoned objects
+     */
+    private void removeAbandoned(final AbandonedConfig ac) {
+        // Generate a list of abandoned objects to remove
+<span class="fc" id="L1049">        final long now = System.currentTimeMillis();</span>
+<span class="fc" id="L1050">        final long timeout =</span>
+<span class="fc" id="L1051">                now - (ac.getRemoveAbandonedTimeout() * 1000L);</span>
+<span class="fc" id="L1052">        final ArrayList&lt;PooledObject&lt;T&gt;&gt; remove = new ArrayList&lt;&gt;();</span>
+<span class="fc" id="L1053">        final Iterator&lt;PooledObject&lt;T&gt;&gt; it = allObjects.values().iterator();</span>
+<span class="fc bfc" id="L1054" title="All 2 branches covered.">        while (it.hasNext()) {</span>
+<span class="fc" id="L1055">            final PooledObject&lt;T&gt; pooledObject = it.next();</span>
+<span class="fc" id="L1056">            synchronized (pooledObject) {</span>
+<span class="fc bfc" id="L1057" title="All 2 branches covered.">                if (pooledObject.getState() == PooledObjectState.ALLOCATED &amp;&amp;</span>
+<span class="fc bfc" id="L1058" title="All 2 branches covered.">                        pooledObject.getLastUsedTime() &lt;= timeout) {</span>
+<span class="fc" id="L1059">                    pooledObject.markAbandoned();</span>
+<span class="fc" id="L1060">                    remove.add(pooledObject);</span>
+                }
+<span class="fc" id="L1062">            }</span>
+<span class="fc" id="L1063">        }</span>
+
+        // Now remove the abandoned objects
+<span class="fc" id="L1066">        final Iterator&lt;PooledObject&lt;T&gt;&gt; itr = remove.iterator();</span>
+<span class="fc bfc" id="L1067" title="All 2 branches covered.">        while (itr.hasNext()) {</span>
+<span class="fc" id="L1068">            final PooledObject&lt;T&gt; pooledObject = itr.next();</span>
+<span class="fc bfc" id="L1069" title="All 2 branches covered.">            if (ac.getLogAbandoned()) {</span>
+<span class="fc" id="L1070">                pooledObject.printStackTrace(ac.getLogWriter());</span>
+            }
+            try {
+<span class="fc" id="L1073">                invalidateObject(pooledObject.getObject());</span>
+<span class="nc" id="L1074">            } catch (final Exception e) {</span>
+<span class="nc" id="L1075">                e.printStackTrace();</span>
+<span class="fc" id="L1076">            }</span>
+<span class="fc" id="L1077">        }</span>
+<span class="fc" id="L1078">    }</span>
+
+
+    //--- Usage tracking support -----------------------------------------------
+
+    @Override
+    public void use(final T pooledObject) {
+<span class="fc" id="L1085">        final AbandonedConfig ac = this.abandonedConfig;</span>
+<span class="pc bpc" id="L1086" title="2 of 4 branches missed.">        if (ac != null &amp;&amp; ac.getUseUsageTracking()) {</span>
+<span class="fc" id="L1087">            final PooledObject&lt;T&gt; wrapper = allObjects.get(new IdentityWrapper&lt;&gt;(pooledObject));</span>
+<span class="fc" id="L1088">            wrapper.use();</span>
+        }
+<span class="fc" id="L1090">    }</span>
+
+
+    //--- JMX support ----------------------------------------------------------
+
+<span class="fc" id="L1095">    private volatile String factoryType = null;</span>
+
+    /**
+     * Returns an estimate of the number of threads currently blocked waiting for
+     * an object from the pool. This is intended for monitoring only, not for
+     * synchronization control.
+     *
+     * @return The estimate of the number of threads currently blocked waiting
+     *         for an object from the pool
+     */
+    @Override
+    public int getNumWaiters() {
+<span class="nc bnc" id="L1107" title="All 2 branches missed.">        if (getBlockWhenExhausted()) {</span>
+<span class="nc" id="L1108">            return idleObjects.getTakeQueueLength();</span>
+        }
+<span class="nc" id="L1110">        return 0;</span>
+    }
+
+    /**
+     * Returns the type - including the specific type rather than the generic -
+     * of the factory.
+     *
+     * @return A string representation of the factory type
+     */
+    @Override
+    public String getFactoryType() {
+        // Not thread safe. Accept that there may be multiple evaluations.
+<span class="pc bpc" id="L1122" title="1 of 2 branches missed.">        if (factoryType == null) {</span>
+<span class="fc" id="L1123">            final StringBuilder result = new StringBuilder();</span>
+<span class="fc" id="L1124">            result.append(factory.getClass().getName());</span>
+<span class="fc" id="L1125">            result.append('&lt;');</span>
+<span class="fc" id="L1126">            final Class&lt;?&gt; pooledObjectType =</span>
+<span class="fc" id="L1127">                    PoolImplUtils.getFactoryType(factory.getClass());</span>
+<span class="fc" id="L1128">            result.append(pooledObjectType.getName());</span>
+<span class="fc" id="L1129">            result.append('&gt;');</span>
+<span class="fc" id="L1130">            factoryType = result.toString();</span>
+        }
+<span class="fc" id="L1132">        return factoryType;</span>
+    }
+
+    /**
+     * Provides information on all the objects in the pool, both idle (waiting
+     * to be borrowed) and active (currently borrowed).
+     * &lt;p&gt;
+     * Note: This is named listAllObjects so it is presented as an operation via
+     * JMX. That means it won't be invoked unless the explicitly requested
+     * whereas all attributes will be automatically requested when viewing the
+     * attributes for an object in a tool like JConsole.
+     * &lt;/p&gt;
+     *
+     * @return Information grouped on all the objects in the pool
+     */
+    @Override
+    public Set&lt;DefaultPooledObjectInfo&gt; listAllObjects() {
+<span class="fc" id="L1149">        final Set&lt;DefaultPooledObjectInfo&gt; result =</span>
+<span class="fc" id="L1150">                new HashSet&lt;&gt;(allObjects.size());</span>
+<span class="fc bfc" id="L1151" title="All 2 branches covered.">        for (final PooledObject&lt;T&gt; p : allObjects.values()) {</span>
+<span class="fc" id="L1152">            result.add(new DefaultPooledObjectInfo(p));</span>
+<span class="fc" id="L1153">        }</span>
+<span class="fc" id="L1154">        return result;</span>
+    }
+
+    // --- configuration attributes --------------------------------------------
+
+<span class="fc" id="L1159">    private volatile int maxIdle = GenericObjectPoolConfig.DEFAULT_MAX_IDLE;</span>
+<span class="fc" id="L1160">    private volatile int minIdle = GenericObjectPoolConfig.DEFAULT_MIN_IDLE;</span>
+    private final PooledObjectFactory&lt;T&gt; factory;
+
+
+    // --- internal attributes -------------------------------------------------
+
+    /*
+     * All of the objects currently associated with this pool in any state. It
+     * excludes objects that have been destroyed. The size of
+     * {@link #allObjects} will always be less than or equal to {@link
+     * #_maxActive}. Map keys are pooled objects, values are the PooledObject
+     * wrappers used internally by the pool.
+     */
+<span class="fc" id="L1173">    private final Map&lt;IdentityWrapper&lt;T&gt;, PooledObject&lt;T&gt;&gt; allObjects =</span>
+        new ConcurrentHashMap&lt;&gt;();
+    /*
+     * The combined count of the currently created objects and those in the
+     * process of being created. Under load, it may exceed {@link #_maxActive}
+     * if multiple threads try and create a new object at the same time but
+     * {@link #create()} will ensure that there are never more than
+     * {@link #_maxActive} objects created at any one time.
+     */
+<span class="fc" id="L1182">    private final AtomicLong createCount = new AtomicLong(0);</span>
+<span class="fc" id="L1183">    private long makeObjectCount = 0;</span>
+<span class="fc" id="L1184">    private final Object makeObjectCountLock = new Object();</span>
+    private final LinkedBlockingDeque&lt;PooledObject&lt;T&gt;&gt; idleObjects;
+
+    // JMX specific attributes
+    private static final String ONAME_BASE =
+        &quot;org.apache.commons.pool2:type=GenericObjectPool,name=&quot;;
+
+    // Additional configuration properties for abandoned object tracking
+<span class="fc" id="L1192">    private volatile AbandonedConfig abandonedConfig = null;</span>
+
+    @Override
+    protected void toStringAppendFields(final StringBuilder builder) {
+<span class="fc" id="L1196">        super.toStringAppendFields(builder);</span>
+<span class="fc" id="L1197">        builder.append(&quot;, factoryType=&quot;);</span>
+<span class="fc" id="L1198">        builder.append(factoryType);</span>
+<span class="fc" id="L1199">        builder.append(&quot;, maxIdle=&quot;);</span>
+<span class="fc" id="L1200">        builder.append(maxIdle);</span>
+<span class="fc" id="L1201">        builder.append(&quot;, minIdle=&quot;);</span>
+<span class="fc" id="L1202">        builder.append(minIdle);</span>
+<span class="fc" id="L1203">        builder.append(&quot;, factory=&quot;);</span>
+<span class="fc" id="L1204">        builder.append(factory);</span>
+<span class="fc" id="L1205">        builder.append(&quot;, allObjects=&quot;);</span>
+<span class="fc" id="L1206">        builder.append(allObjects);</span>
+<span class="fc" id="L1207">        builder.append(&quot;, createCount=&quot;);</span>
+<span class="fc" id="L1208">        builder.append(createCount);</span>
+<span class="fc" id="L1209">        builder.append(&quot;, idleObjects=&quot;);</span>
+<span class="fc" id="L1210">        builder.append(idleObjects);</span>
+<span class="fc" id="L1211">        builder.append(&quot;, abandonedConfig=&quot;);</span>
+<span class="fc" id="L1212">        builder.append(abandonedConfig);</span>
+<span class="fc" id="L1213">    }</span>
+
+}
+</pre><div class="footer"><span class="right">Created with <a href="http://www.jacoco.org/jacoco">JaCoCo</a> 0.8.3.201901230119</span></div></body></html>
\ No newline at end of file

Added: websites/production/commons/content/proper/commons-pool/jacoco/org.apache.commons.pool2.impl/GenericObjectPoolConfig.html
==============================================================================
--- websites/production/commons/content/proper/commons-pool/jacoco/org.apache.commons.pool2.impl/GenericObjectPoolConfig.html (added)
+++ websites/production/commons/content/proper/commons-pool/jacoco/org.apache.commons.pool2.impl/GenericObjectPoolConfig.html Sat Aug 10 22:26:44 2019
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml" lang="en"><head><meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/><link rel="stylesheet" href="../jacoco-resources/report.css" type="text/css"/><link rel="shortcut icon" href="../jacoco-resources/report.gif" type="image/gif"/><title>GenericObjectPoolConfig</title><script type="text/javascript" src="../jacoco-resources/sort.js"></script></head><body onload="initialSort(['breadcrumb'])"><div class="breadcrumb" id="breadcrumb"><span class="info"><a href="../jacoco-sessions.html" class="el_session">Sessions</a></span><a href="../index.html" class="el_report">Apache Commons Pool</a> &gt; <a href="index.html" class="el_package">org.apache.commons.pool2.impl</a> &gt; <span class="el_class">GenericObjectPoolConfig</span></div><h1>GenericObjectPoolConfig</h1><table class="coverage" cellsp
 acing="0" id="coveragetable"><thead><tr><td class="sortable" id="a" onclick="toggleSort(this)">Element</td><td class="down sortable bar" id="b" onclick="toggleSort(this)">Missed Instructions</td><td class="sortable ctr2" id="c" onclick="toggleSort(this)">Cov.</td><td class="sortable bar" id="d" onclick="toggleSort(this)">Missed Branches</td><td class="sortable ctr2" id="e" onclick="toggleSort(this)">Cov.</td><td class="sortable ctr1" id="f" onclick="toggleSort(this)">Missed</td><td class="sortable ctr2" id="g" onclick="toggleSort(this)">Cxty</td><td class="sortable ctr1" id="h" onclick="toggleSort(this)">Missed</td><td class="sortable ctr2" id="i" onclick="toggleSort(this)">Lines</td><td class="sortable ctr1" id="j" onclick="toggleSort(this)">Missed</td><td class="sortable ctr2" id="k" onclick="toggleSort(this)">Methods</td></tr></thead><tfoot><tr><td>Total</td><td class="bar">40 of 73</td><td class="ctr2">45%</td><td class="bar">0 of 0</td><td class="ctr2">n/a</td><td class="ctr1">
 2</td><td class="ctr2">9</td><td class="ctr1">11</td><td class="ctr2">24</td><td class="ctr1">2</td><td class="ctr2">9</td></tr></tfoot><tbody><tr><td id="a8"><a href="GenericObjectPoolConfig.java.html#L150" class="el_method">toStringAppendFields(StringBuilder)</a></td><td class="bar" id="b0"><img src="../jacoco-resources/redbar.gif" width="120" height="10" title="31" alt="31"/></td><td class="ctr2" id="c7">0%</td><td class="bar" id="d0"/><td class="ctr2" id="e0">n/a</td><td class="ctr1" id="f0">1</td><td class="ctr2" id="g0">1</td><td class="ctr1" id="h0">8</td><td class="ctr2" id="i0">8</td><td class="ctr1" id="j0">1</td><td class="ctr2" id="k0">1</td></tr><tr><td id="a0"><a href="GenericObjectPoolConfig.java.html#L142" class="el_method">clone()</a></td><td class="bar" id="b1"><img src="../jacoco-resources/redbar.gif" width="34" height="10" title="9" alt="9"/></td><td class="ctr2" id="c8">0%</td><td class="bar" id="d1"/><td class="ctr2" id="e1">n/a</td><td class="ctr1" id="f1">1</
 td><td class="ctr2" id="g1">1</td><td class="ctr1" id="h1">3</td><td class="ctr2" id="i2">3</td><td class="ctr1" id="j1">1</td><td class="ctr2" id="k1">1</td></tr><tr><td id="a1"><a href="GenericObjectPoolConfig.java.html#L31" class="el_method">GenericObjectPoolConfig()</a></td><td class="bar" id="b2"><img src="../jacoco-resources/greenbar.gif" width="46" height="10" title="12" alt="12"/></td><td class="ctr2" id="c0">100%</td><td class="bar" id="d2"/><td class="ctr2" id="e2">n/a</td><td class="ctr1" id="f2">0</td><td class="ctr2" id="g2">1</td><td class="ctr1" id="h2">0</td><td class="ctr2" id="i1">4</td><td class="ctr1" id="j2">0</td><td class="ctr2" id="k2">1</td></tr><tr><td id="a6"><a href="GenericObjectPoolConfig.java.html#L81" class="el_method">setMaxTotal(int)</a></td><td class="bar" id="b3"><img src="../jacoco-resources/greenbar.gif" width="15" height="10" title="4" alt="4"/></td><td class="ctr2" id="c1">100%</td><td class="bar" id="d3"/><td class="ctr2" id="e3">n/a</td><td 
 class="ctr1" id="f3">0</td><td class="ctr2" id="g3">1</td><td class="ctr1" id="h3">0</td><td class="ctr2" id="i3">2</td><td class="ctr1" id="j3">0</td><td class="ctr2" id="k3">1</td></tr><tr><td id="a5"><a href="GenericObjectPoolConfig.java.html#L108" class="el_method">setMaxIdle(int)</a></td><td class="bar" id="b4"><img src="../jacoco-resources/greenbar.gif" width="15" height="10" title="4" alt="4"/></td><td class="ctr2" id="c2">100%</td><td class="bar" id="d4"/><td class="ctr2" id="e4">n/a</td><td class="ctr1" id="f4">0</td><td class="ctr2" id="g4">1</td><td class="ctr1" id="h4">0</td><td class="ctr2" id="i4">2</td><td class="ctr1" id="j4">0</td><td class="ctr2" id="k4">1</td></tr><tr><td id="a7"><a href="GenericObjectPoolConfig.java.html#L135" class="el_method">setMinIdle(int)</a></td><td class="bar" id="b5"><img src="../jacoco-resources/greenbar.gif" width="15" height="10" title="4" alt="4"/></td><td class="ctr2" id="c3">100%</td><td class="bar" id="d5"/><td class="ctr2" id="e5"
 >n/a</td><td class="ctr1" id="f5">0</td><td class="ctr2" id="g5">1</td><td class="ctr1" id="h5">0</td><td class="ctr2" id="i5">2</td><td class="ctr1" id="j5">0</td><td class="ctr2" id="k5">1</td></tr><tr><td id="a3"><a href="GenericObjectPoolConfig.java.html#L68" class="el_method">getMaxTotal()</a></td><td class="bar" id="b6"><img src="../jacoco-resources/greenbar.gif" width="11" height="10" title="3" alt="3"/></td><td class="ctr2" id="c4">100%</td><td class="bar" id="d6"/><td class="ctr2" id="e6">n/a</td><td class="ctr1" id="f6">0</td><td class="ctr2" id="g6">1</td><td class="ctr1" id="h6">0</td><td class="ctr2" id="i6">1</td><td class="ctr1" id="j6">0</td><td class="ctr2" id="k6">1</td></tr><tr><td id="a2"><a href="GenericObjectPoolConfig.java.html#L95" class="el_method">getMaxIdle()</a></td><td class="bar" id="b7"><img src="../jacoco-resources/greenbar.gif" width="11" height="10" title="3" alt="3"/></td><td class="ctr2" id="c5">100%</td><td class="bar" id="d7"/><td class="ctr2" i
 d="e7">n/a</td><td class="ctr1" id="f7">0</td><td class="ctr2" id="g7">1</td><td class="ctr1" id="h7">0</td><td class="ctr2" id="i7">1</td><td class="ctr1" id="j7">0</td><td class="ctr2" id="k7">1</td></tr><tr><td id="a4"><a href="GenericObjectPoolConfig.java.html#L122" class="el_method">getMinIdle()</a></td><td class="bar" id="b8"><img src="../jacoco-resources/greenbar.gif" width="11" height="10" title="3" alt="3"/></td><td class="ctr2" id="c6">100%</td><td class="bar" id="d8"/><td class="ctr2" id="e8">n/a</td><td class="ctr1" id="f8">0</td><td class="ctr2" id="g8">1</td><td class="ctr1" id="h8">0</td><td class="ctr2" id="i8">1</td><td class="ctr1" id="j8">0</td><td class="ctr2" id="k8">1</td></tr></tbody></table><div class="footer"><span class="right">Created with <a href="http://www.jacoco.org/jacoco">JaCoCo</a> 0.8.3.201901230119</span></div></body></html>
\ No newline at end of file

Added: websites/production/commons/content/proper/commons-pool/jacoco/org.apache.commons.pool2.impl/GenericObjectPoolConfig.java.html
==============================================================================
--- websites/production/commons/content/proper/commons-pool/jacoco/org.apache.commons.pool2.impl/GenericObjectPoolConfig.java.html (added)
+++ websites/production/commons/content/proper/commons-pool/jacoco/org.apache.commons.pool2.impl/GenericObjectPoolConfig.java.html Sat Aug 10 22:26:44 2019
@@ -0,0 +1,159 @@
+<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml" lang="en"><head><meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/><link rel="stylesheet" href="../jacoco-resources/report.css" type="text/css"/><link rel="shortcut icon" href="../jacoco-resources/report.gif" type="image/gif"/><title>GenericObjectPoolConfig.java</title><link rel="stylesheet" href="../jacoco-resources/prettify.css" type="text/css"/><script type="text/javascript" src="../jacoco-resources/prettify.js"></script></head><body onload="window['PR_TAB_WIDTH']=4;prettyPrint()"><div class="breadcrumb" id="breadcrumb"><span class="info"><a href="../jacoco-sessions.html" class="el_session">Sessions</a></span><a href="../index.html" class="el_report">Apache Commons Pool</a> &gt; <a href="index.source.html" class="el_package">org.apache.commons.pool2.impl</a> &gt; <span class="e
 l_source">GenericObjectPoolConfig.java</span></div><h1>GenericObjectPoolConfig.java</h1><pre class="source lang-java linenums">/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the &quot;License&quot;); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an &quot;AS IS&quot; BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.pool2.impl;
+
+/**
+ * A simple &quot;struct&quot; encapsulating the configuration for a
+ * {@link GenericObjectPool}.
+ *
+ * &lt;p&gt;
+ * This class is not thread-safe; it is only intended to be used to provide
+ * attributes used when creating a pool.
+ * &lt;/p&gt;
+ *
+ * @param &lt;T&gt; Type of element pooled.
+ * @since 2.0
+ */
+<span class="fc" id="L31">public class GenericObjectPoolConfig&lt;T&gt; extends BaseObjectPoolConfig&lt;T&gt; {</span>
+
+    /**
+     * The default value for the {@code maxTotal} configuration attribute.
+     * @see GenericObjectPool#getMaxTotal()
+     */
+    public static final int DEFAULT_MAX_TOTAL = 8;
+
+    /**
+     * The default value for the {@code maxIdle} configuration attribute.
+     * @see GenericObjectPool#getMaxIdle()
+     */
+    public static final int DEFAULT_MAX_IDLE = 8;
+
+    /**
+     * The default value for the {@code minIdle} configuration attribute.
+     * @see GenericObjectPool#getMinIdle()
+     */
+    public static final int DEFAULT_MIN_IDLE = 0;
+
+
+<span class="fc" id="L52">    private int maxTotal = DEFAULT_MAX_TOTAL;</span>
+
+<span class="fc" id="L54">    private int maxIdle = DEFAULT_MAX_IDLE;</span>
+
+<span class="fc" id="L56">    private int minIdle = DEFAULT_MIN_IDLE;</span>
+
+    /**
+     * Get the value for the {@code maxTotal} configuration attribute
+     * for pools created with this configuration instance.
+     *
+     * @return  The current setting of {@code maxTotal} for this
+     *          configuration instance
+     *
+     * @see GenericObjectPool#getMaxTotal()
+     */
+    public int getMaxTotal() {
+<span class="fc" id="L68">        return maxTotal;</span>
+    }
+
+    /**
+     * Set the value for the {@code maxTotal} configuration attribute for
+     * pools created with this configuration instance.
+     *
+     * @param maxTotal The new setting of {@code maxTotal}
+     *        for this configuration instance
+     *
+     * @see GenericObjectPool#setMaxTotal(int)
+     */
+    public void setMaxTotal(final int maxTotal) {
+<span class="fc" id="L81">        this.maxTotal = maxTotal;</span>
+<span class="fc" id="L82">    }</span>
+
+
+    /**
+     * Get the value for the {@code maxIdle} configuration attribute
+     * for pools created with this configuration instance.
+     *
+     * @return  The current setting of {@code maxIdle} for this
+     *          configuration instance
+     *
+     * @see GenericObjectPool#getMaxIdle()
+     */
+    public int getMaxIdle() {
+<span class="fc" id="L95">        return maxIdle;</span>
+    }
+
+    /**
+     * Set the value for the {@code maxIdle} configuration attribute for
+     * pools created with this configuration instance.
+     *
+     * @param maxIdle The new setting of {@code maxIdle}
+     *        for this configuration instance
+     *
+     * @see GenericObjectPool#setMaxIdle(int)
+     */
+    public void setMaxIdle(final int maxIdle) {
+<span class="fc" id="L108">        this.maxIdle = maxIdle;</span>
+<span class="fc" id="L109">    }</span>
+
+
+    /**
+     * Get the value for the {@code minIdle} configuration attribute
+     * for pools created with this configuration instance.
+     *
+     * @return  The current setting of {@code minIdle} for this
+     *          configuration instance
+     *
+     * @see GenericObjectPool#getMinIdle()
+     */
+    public int getMinIdle() {
+<span class="fc" id="L122">        return minIdle;</span>
+    }
+
+    /**
+     * Set the value for the {@code minIdle} configuration attribute for
+     * pools created with this configuration instance.
+     *
+     * @param minIdle The new setting of {@code minIdle}
+     *        for this configuration instance
+     *
+     * @see GenericObjectPool#setMinIdle(int)
+     */
+    public void setMinIdle(final int minIdle) {
+<span class="fc" id="L135">        this.minIdle = minIdle;</span>
+<span class="fc" id="L136">    }</span>
+
+    @SuppressWarnings(&quot;unchecked&quot;)
+    @Override
+    public GenericObjectPoolConfig&lt;T&gt; clone() {
+        try {
+<span class="nc" id="L142">            return (GenericObjectPoolConfig&lt;T&gt;) super.clone();</span>
+<span class="nc" id="L143">        } catch (final CloneNotSupportedException e) {</span>
+<span class="nc" id="L144">            throw new AssertionError(); // Can't happen</span>
+        }
+    }
+
+    @Override
+    protected void toStringAppendFields(final StringBuilder builder) {
+<span class="nc" id="L150">        super.toStringAppendFields(builder);</span>
+<span class="nc" id="L151">        builder.append(&quot;, maxTotal=&quot;);</span>
+<span class="nc" id="L152">        builder.append(maxTotal);</span>
+<span class="nc" id="L153">        builder.append(&quot;, maxIdle=&quot;);</span>
+<span class="nc" id="L154">        builder.append(maxIdle);</span>
+<span class="nc" id="L155">        builder.append(&quot;, minIdle=&quot;);</span>
+<span class="nc" id="L156">        builder.append(minIdle);</span>
+<span class="nc" id="L157">    }</span>
+}
+</pre><div class="footer"><span class="right">Created with <a href="http://www.jacoco.org/jacoco">JaCoCo</a> 0.8.3.201901230119</span></div></body></html>
\ No newline at end of file

Added: websites/production/commons/content/proper/commons-pool/jacoco/org.apache.commons.pool2.impl/InterruptibleReentrantLock.html
==============================================================================
--- websites/production/commons/content/proper/commons-pool/jacoco/org.apache.commons.pool2.impl/InterruptibleReentrantLock.html (added)
+++ websites/production/commons/content/proper/commons-pool/jacoco/org.apache.commons.pool2.impl/InterruptibleReentrantLock.html Sat Aug 10 22:26:44 2019
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml" lang="en"><head><meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/><link rel="stylesheet" href="../jacoco-resources/report.css" type="text/css"/><link rel="shortcut icon" href="../jacoco-resources/report.gif" type="image/gif"/><title>InterruptibleReentrantLock</title><script type="text/javascript" src="../jacoco-resources/sort.js"></script></head><body onload="initialSort(['breadcrumb'])"><div class="breadcrumb" id="breadcrumb"><span class="info"><a href="../jacoco-sessions.html" class="el_session">Sessions</a></span><a href="../index.html" class="el_report">Apache Commons Pool</a> &gt; <a href="index.html" class="el_package">org.apache.commons.pool2.impl</a> &gt; <span class="el_class">InterruptibleReentrantLock</span></div><h1>InterruptibleReentrantLock</h1><table class="coverag
 e" cellspacing="0" id="coveragetable"><thead><tr><td class="sortable" id="a" onclick="toggleSort(this)">Element</td><td class="down sortable bar" id="b" onclick="toggleSort(this)">Missed Instructions</td><td class="sortable ctr2" id="c" onclick="toggleSort(this)">Cov.</td><td class="sortable bar" id="d" onclick="toggleSort(this)">Missed Branches</td><td class="sortable ctr2" id="e" onclick="toggleSort(this)">Cov.</td><td class="sortable ctr1" id="f" onclick="toggleSort(this)">Missed</td><td class="sortable ctr2" id="g" onclick="toggleSort(this)">Cxty</td><td class="sortable ctr1" id="h" onclick="toggleSort(this)">Missed</td><td class="sortable ctr2" id="i" onclick="toggleSort(this)">Lines</td><td class="sortable ctr1" id="j" onclick="toggleSort(this)">Missed</td><td class="sortable ctr2" id="k" onclick="toggleSort(this)">Methods</td></tr></thead><tfoot><tr><td>Total</td><td class="bar">0 of 22</td><td class="ctr2">100%</td><td class="bar">0 of 2</td><td class="ctr2">100%</td><td cla
 ss="ctr1">0</td><td class="ctr2">3</td><td class="ctr1">0</td><td class="ctr2">7</td><td class="ctr1">0</td><td class="ctr2">2</td></tr></tfoot><tbody><tr><td id="a1"><a href="InterruptibleReentrantLock.java.html#L52" class="el_method">interruptWaiters(Condition)</a></td><td class="bar" id="b0"><img src="../jacoco-resources/greenbar.gif" width="120" height="10" title="18" alt="18"/></td><td class="ctr2" id="c0">100%</td><td class="bar" id="d0"><img src="../jacoco-resources/greenbar.gif" width="120" height="10" title="2" alt="2"/></td><td class="ctr2" id="e0">100%</td><td class="ctr1" id="f0">0</td><td class="ctr2" id="g0">2</td><td class="ctr1" id="h0">0</td><td class="ctr2" id="i0">5</td><td class="ctr1" id="j0">0</td><td class="ctr2" id="k0">1</td></tr><tr><td id="a0"><a href="InterruptibleReentrantLock.java.html#L43" class="el_method">InterruptibleReentrantLock(boolean)</a></td><td class="bar" id="b1"><img src="../jacoco-resources/greenbar.gif" width="26" height="10" title="4" al
 t="4"/></td><td class="ctr2" id="c1">100%</td><td class="bar" id="d1"/><td class="ctr2" id="e1">n/a</td><td class="ctr1" id="f1">0</td><td class="ctr2" id="g1">1</td><td class="ctr1" id="h1">0</td><td class="ctr2" id="i1">2</td><td class="ctr1" id="j1">0</td><td class="ctr2" id="k1">1</td></tr></tbody></table><div class="footer"><span class="right">Created with <a href="http://www.jacoco.org/jacoco">JaCoCo</a> 0.8.3.201901230119</span></div></body></html>
\ No newline at end of file