You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by "Mike Martin (JIRA)" <ji...@apache.org> on 2006/10/08 21:12:19 UTC

[jira] Created: (POOL-85) GenericKeyedObjectPool.getNumIdle() corrupted under high load

GenericKeyedObjectPool.getNumIdle() corrupted under high load
-------------------------------------------------------------

                 Key: POOL-85
                 URL: http://issues.apache.org/jira/browse/POOL-85
             Project: Commons Pool
          Issue Type: Bug
    Affects Versions: 1.3
            Reporter: Mike Martin


GenericKeyedObjectPool can have its getNumIdle() value corrupted (as in
becoming negative) under certain conditions.  The conditions appear to be:

o   _maxTotal > 0
o   Multiple keys are in use
o   Objects are borrowed by many threads at a fast rate
o   Demand exceeds _maxTotal

When _totalIdle gets corrupted then the "pool exhausted" computations are
compromised, resulting in invalid states such as _totalActive > _maxTotal.

I've determined the problem originates in ObjectTimestampPair; its compareTo()
method is not consistent with equals() (see note in java.lang.Comparable docs
about sorted sets & sorted maps).

When clearOldest() builds a TreeMap using ObjectTimestampPairs as keys the
inconsistency with equals can result in OTPs being mapped to the wrong pool
key if their timestamps are equal.  In turn this causes the eventual:

    list.remove(pairTimeStamp);

at line 902 to silently attempt removal from the wrong list.  The OTP doesn't
get removed but _totalIdle gets decremented.

Here's the patch:

--- GenericKeyedObjectPool.java.orig    Sun Apr 02 19:59:37 2006
+++ GenericKeyedObjectPool.java Sun Oct 08 13:32:40 2006
@@ -1335,7 +1335,12 @@
         }

         public int compareTo(ObjectTimestampPair other) {
-            return (int) (this.tstamp - other.tstamp);
+            int cmp = (int)(this.tstamp - other.tstamp);
+
+            if (cmp == 0)
+                cmp = System.identityHashCode(this) - System.identityHashCode(other);
+
+            return cmp;
         }
     }

Mike

-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: http://issues.apache.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira

        

---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org


[jira] Resolved: (POOL-85) GenericKeyedObjectPool.getNumIdle() corrupted under high load

Posted by "Sandy McArthur (JIRA)" <ji...@apache.org>.
     [ http://issues.apache.org/jira/browse/POOL-85?page=all ]

Sandy McArthur resolved POOL-85.
--------------------------------

    Fix Version/s: 2.0
       Resolution: Fixed

Impressive catch, fix committed.

> GenericKeyedObjectPool.getNumIdle() corrupted under high load
> -------------------------------------------------------------
>
>                 Key: POOL-85
>                 URL: http://issues.apache.org/jira/browse/POOL-85
>             Project: Commons Pool
>          Issue Type: Bug
>    Affects Versions: 1.3
>            Reporter: Mike Martin
>         Assigned To: Sandy McArthur
>             Fix For: 2.0
>
>
> GenericKeyedObjectPool can have its getNumIdle() value corrupted (as in
> becoming negative) under certain conditions.  The conditions appear to be:
> o   _maxTotal > 0
> o   Multiple keys are in use
> o   Objects are borrowed by many threads at a fast rate
> o   Demand exceeds _maxTotal
> When _totalIdle gets corrupted then the "pool exhausted" computations are
> compromised, resulting in invalid states such as _totalActive > _maxTotal.
> I've determined the problem originates in ObjectTimestampPair; its compareTo()
> method is not consistent with equals() (see note in java.lang.Comparable docs
> about sorted sets & sorted maps).
> When clearOldest() builds a TreeMap using ObjectTimestampPairs as keys the
> inconsistency with equals can result in OTPs being mapped to the wrong pool
> key if their timestamps are equal.  In turn this causes the eventual:
>     list.remove(pairTimeStamp);
> at line 902 to silently attempt removal from the wrong list.  The OTP doesn't
> get removed but _totalIdle gets decremented.
> Here's the patch:
> --- GenericKeyedObjectPool.java.orig    Sun Apr 02 19:59:37 2006
> +++ GenericKeyedObjectPool.java Sun Oct 08 13:32:40 2006
> @@ -1335,7 +1335,12 @@
>          }
>          public int compareTo(ObjectTimestampPair other) {
> -            return (int) (this.tstamp - other.tstamp);
> +            int cmp = (int)(this.tstamp - other.tstamp);
> +
> +            if (cmp == 0)
> +                cmp = System.identityHashCode(this) - System.identityHashCode(other);
> +
> +            return cmp;
>          }
>      }
> Mike

-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: http://issues.apache.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira

        

---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org