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> > <a href="index.source.html" class="el_package">org.apache.commons.pool2.impl</a> > <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 "License"); 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 "AS IS" 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.
+ * <p>
+ * When coupled with the appropriate {@link PooledObjectFactory},
+ * <code>GenericObjectPool</code> provides robust pooling functionality for
+ * arbitrary objects.</p>
+ * <p>
+ * 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 "idle object eviction" 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.</p>
+ * <p>
+ * The pool can also be configured to detect and remove "abandoned" 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
+ * <code>borrowObject</code> 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 <code>getLastUsed</code> method on that interface; otherwise
+ * abandonment is determined by how long an object has been checked out from
+ * the pool.</p>
+ * <p>
+ * 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.</p>
+ * <p>
+ * This class is intended to be thread-safe.</p>
+ *
+ * @see GenericKeyedObjectPool
+ *
+ * @param <T> Type of element pooled in this pool.
+ *
+ * @since 2.0
+ */
+public class GenericObjectPool<T> extends BaseGenericObjectPool<T>
+ implements ObjectPool<T>, GenericObjectPoolMXBean, UsageTracking<T> {
+
+ /**
+ * Creates a new <code>GenericObjectPool</code> 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<T> factory) {
+<span class="fc" id="L88"> this(factory, new GenericObjectPoolConfig<T>());</span>
+<span class="fc" id="L89"> }</span>
+
+ /**
+ * Creates a new <code>GenericObjectPool</code> 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<T> factory,
+ final GenericObjectPoolConfig<T> 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("factory may not be null");</span>
+ }
+<span class="fc" id="L111"> this.factory = factory;</span>
+
+<span class="fc" id="L113"> idleObjects = new LinkedBlockingDeque<>(config.getFairness());</span>
+
+<span class="fc" id="L115"> setConfig(config);</span>
+<span class="fc" id="L116"> }</span>
+
+ /**
+ * Creates a new <code>GenericObjectPool</code> 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<T> factory,
+ final GenericObjectPoolConfig<T> 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 "idle" 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 "idle" 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 "idle" 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 "idle" 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.
+ * <p>
+ * If the configured value of minIdle is greater than the configured value
+ * for maxIdle then the value of maxIdle will be used instead.
+ * </p>
+ *
+ * @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.
+ * <p>
+ * If the configured value of minIdle is greater than the configured value
+ * for maxIdle then the value of maxIdle will be used instead.
+ * </p>
+ *
+ * @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 > 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 && 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 && 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 && 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<T> 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<T> getFactory() {
+<span class="nc" id="L337"> return factory;</span>
+ }
+
+ /**
+ * Equivalent to <code>{@link #borrowObject(long)
+ * borrowObject}({@link #getMaxWaitMillis()})</code>.
+ * <p>
+ * {@inheritDoc}
+ * </p>
+ */
+ @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.
+ * <p>
+ * 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 <code>true</code> 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.
+ * </p>
+ * <p>
+ * 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
+ * <code>borrowMaxWaitMillis</code> parameter. If the number of instances
+ * checked out from the pool is less than <code>maxTotal,</code> a new
+ * instance is created, activated and (if applicable) validated and returned
+ * to the caller. If validation fails, a <code>NoSuchElementException</code>
+ * is thrown.
+ * </p>
+ * <p>
+ * 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
+ * <code>NoSuchElementException</code> (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 <code>borrowMaxWaitMillis</code>
+ * parameter.
+ * </p>
+ * <p>
+ * When the pool is exhausted, multiple calling threads may be
+ * simultaneously blocked waiting for instances to become available. A
+ * "fairness" algorithm has been implemented to ensure that threads receive
+ * available instances in request arrival order.
+ * </p>
+ *
+ * @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 && ac.getRemoveAbandonedOnBorrow() &&</span>
+<span class="pc bpc" id="L406" title="1 of 2 branches missed."> (getNumIdle() < 2) &&</span>
+<span class="fc bfc" id="L407" title="All 2 branches covered."> (getNumActive() > getMaxTotal() - 3) ) {</span>
+<span class="fc" id="L408"> removeAbandoned(ac);</span>
+ }
+
+<span class="fc" id="L411"> PooledObject<T> 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 < 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>
+ "Timeout waiting for idle object");
+ }
+ } else {
+<span class="fc bfc" id="L443" title="All 2 branches covered."> if (p == null) {</span>
+<span class="fc" id="L444"> throw new NoSuchElementException("Pool exhausted");</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>
+ "Unable to activate object");
+<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 && 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>
+ "Unable to validate object");
+<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}
+ * <p>
+ * 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.
+ * </p>
+ * <p>
+ * 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.
+ * </p>
+ * <p>
+ * Exceptions encountered destroying objects for any reason are swallowed
+ * but notified via a {@link SwallowedExceptionListener}.
+ * </p>
+ */
+ @Override
+ public void returnObject(final T obj) {
+<span class="fc" id="L520"> final PooledObject<T> p = allObjects.get(new IdentityWrapper<>(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>
+ "Returned object not currently part of this pool");
+ }
+<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() && !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>
+ "Object has already been returned to this pool or is invalid");
+ }
+
+<span class="fc" id="L572"> final int maxIdleSave = getMaxIdle();</span>
+<span class="fc bfc" id="L573" title="All 6 branches covered."> if (isClosed() || maxIdleSave > -1 && maxIdleSave <= 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}
+ * <p>
+ * Activation of this method decrements the active count and attempts to
+ * destroy the instance.
+ * </p>
+ *
+ * @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<T> p = allObjects.get(new IdentityWrapper<>(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>
+ "Invalidated object not currently part of this pool");
+ }
+<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.
+ * <p>
+ * Implementation notes:
+ * </p>
+ * <ul>
+ * <li>This method does not destroy or effect in any way instances that are
+ * checked out of the pool when it is invoked.</li>
+ * <li>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.</li>
+ * <li>Exceptions encountered destroying idle instances are swallowed
+ * but notified via a {@link SwallowedExceptionListener}.</li>
+ * </ul>
+ */
+ @Override
+ public void clear() {
+<span class="fc" id="L644"> PooledObject<T> 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.
+ * <p>
+ * Destroys idle instances in the pool by invoking {@link #clear()}.
+ * </p>
+ */
+ @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}
+ * <p>
+ * Successive activations of this method examine objects in sequence,
+ * cycling through objects in oldest-to-youngest order.
+ * </p>
+ */
+ @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() > 0) {</span>
+
+<span class="fc" id="L714"> PooledObject<T> underTest = null;</span>
+<span class="fc" id="L715"> final EvictionPolicy<T> 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 < 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 && 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() < 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.
+ * <p>
+ * If there are {@link #getMaxTotal()} objects already in circulation
+ * or in process of being created, this method returns null.
+ * </p>
+ *
+ * @return The new wrapped pooled object
+ *
+ * @throws Exception if the object factory's {@code makeObject} fails
+ */
+ private PooledObject<T> 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 < 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 > 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 &&</span>
+ (localMaxWaitTimeMillis > 0 &&
+<span class="fc bfc" id="L878" title="All 2 branches covered."> System.currentTimeMillis() - localStartTimeMillis >= 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<T> p;
+ try {
+<span class="fc" id="L889"> p = factory.makeObject();</span>
+<span class="fc bfc" id="L890" title="All 4 branches covered."> if (getTestOnCreate() && !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 && 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<>(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<T> 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<>(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() && 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<T> 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.
+ * <p>
+ * 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.
+ * </p>
+ *
+ * @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 < 1 || isClosed() || (!always && !idleObjects.hasTakeWaiters())) {</span>
+<span class="fc" id="L964"> return;</span>
+ }
+
+<span class="fc bfc" id="L967" title="All 2 branches covered."> while (idleObjects.size() < idleCount) {</span>
+<span class="fc" id="L968"> final PooledObject<T> 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
+ * "pre-loading" a pool with idle objects.
+ * <p>
+ * If there is no capacity available to add to the pool, this is a no-op
+ * (no exception, no impact to the pool). </p>
+ */
+ @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>
+ "Cannot add objects without a factory.");
+ }
+<span class="fc" id="L1002"> final PooledObject<T> 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<T> 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 >= 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<PooledObject<T>> remove = new ArrayList<>();</span>
+<span class="fc" id="L1053"> final Iterator<PooledObject<T>> 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<T> 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 &&</span>
+<span class="fc bfc" id="L1058" title="All 2 branches covered."> pooledObject.getLastUsedTime() <= 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<PooledObject<T>> 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<T> 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 && ac.getUseUsageTracking()) {</span>
+<span class="fc" id="L1087"> final PooledObject<T> wrapper = allObjects.get(new IdentityWrapper<>(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('<');</span>
+<span class="fc" id="L1126"> final Class<?> 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('>');</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).
+ * <p>
+ * 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.
+ * </p>
+ *
+ * @return Information grouped on all the objects in the pool
+ */
+ @Override
+ public Set<DefaultPooledObjectInfo> listAllObjects() {
+<span class="fc" id="L1149"> final Set<DefaultPooledObjectInfo> result =</span>
+<span class="fc" id="L1150"> new HashSet<>(allObjects.size());</span>
+<span class="fc bfc" id="L1151" title="All 2 branches covered."> for (final PooledObject<T> 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<T> 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<IdentityWrapper<T>, PooledObject<T>> allObjects =</span>
+ new ConcurrentHashMap<>();
+ /*
+ * 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<PooledObject<T>> idleObjects;
+
+ // JMX specific attributes
+ private static final String ONAME_BASE =
+ "org.apache.commons.pool2:type=GenericObjectPool,name=";
+
+ // 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(", factoryType=");</span>
+<span class="fc" id="L1198"> builder.append(factoryType);</span>
+<span class="fc" id="L1199"> builder.append(", maxIdle=");</span>
+<span class="fc" id="L1200"> builder.append(maxIdle);</span>
+<span class="fc" id="L1201"> builder.append(", minIdle=");</span>
+<span class="fc" id="L1202"> builder.append(minIdle);</span>
+<span class="fc" id="L1203"> builder.append(", factory=");</span>
+<span class="fc" id="L1204"> builder.append(factory);</span>
+<span class="fc" id="L1205"> builder.append(", allObjects=");</span>
+<span class="fc" id="L1206"> builder.append(allObjects);</span>
+<span class="fc" id="L1207"> builder.append(", createCount=");</span>
+<span class="fc" id="L1208"> builder.append(createCount);</span>
+<span class="fc" id="L1209"> builder.append(", idleObjects=");</span>
+<span class="fc" id="L1210"> builder.append(idleObjects);</span>
+<span class="fc" id="L1211"> builder.append(", abandonedConfig=");</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> > <a href="index.html" class="el_package">org.apache.commons.pool2.impl</a> > <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> > <a href="index.source.html" class="el_package">org.apache.commons.pool2.impl</a> > <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 "License"); 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 "AS IS" 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 "struct" encapsulating the configuration for a
+ * {@link GenericObjectPool}.
+ *
+ * <p>
+ * This class is not thread-safe; it is only intended to be used to provide
+ * attributes used when creating a pool.
+ * </p>
+ *
+ * @param <T> Type of element pooled.
+ * @since 2.0
+ */
+<span class="fc" id="L31">public class GenericObjectPoolConfig<T> extends BaseObjectPoolConfig<T> {</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("unchecked")
+ @Override
+ public GenericObjectPoolConfig<T> clone() {
+ try {
+<span class="nc" id="L142"> return (GenericObjectPoolConfig<T>) 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(", maxTotal=");</span>
+<span class="nc" id="L152"> builder.append(maxTotal);</span>
+<span class="nc" id="L153"> builder.append(", maxIdle=");</span>
+<span class="nc" id="L154"> builder.append(maxIdle);</span>
+<span class="nc" id="L155"> builder.append(", minIdle=");</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> > <a href="index.html" class="el_package">org.apache.commons.pool2.impl</a> > <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