|
[
Permlink
| « Hide
]
Matthew Moore added a comment - 12/Nov/07 08:02 PM
Just wanted to add that GenericObjectPool.evict() suffers the same problem, in that the object-wide lock is held during potentially blocking validation operations when testWhileIdle is true.
Patch to remove excess synchronization in GenericObjectPool.
Changes and rationale for GOP.patch.
Pool 1.3 added synchronization to address threadsafety issues presented in [1]. The potential race conditions identified all involved threads invoking close() on the pool while other threads were accessing or depending on the pool's closed member or, more dangerously, the _factory. In the 1.2 implementation, close() set _factory to null, so unsynchronized access to _factory could lead to null pointer exceptions. In 1.3, close was modified to no longer set _factory to null and closed was declared volatile. Neither of these eliminates the need to protect the data, but the two together make the identified race conditions both less likely and less damaging. The patch essentially reverts synchronization to the 1.2 level. Changes: borrowObject - narrowed the synchronization to the wait loop, moving assertOpen inside the loop. Maintained synchronization of access to pool fields. Control driven by stack variables outside synchronized blocks does not depend on pool state. Access to _factory outside of synchronized context is technically unsafe, since there is a synchronized setFactory method. This method throws IllegalStateException, however, if invoked when there are active objects, so this is not a practial problem. close no longer modifies _factory. invalidateObject - narrowed scope of synchronization to _numActive decrement and notify. Unsynchronized access to _factory is not a practical issue per comment above. returnObject - removed synchronization entirely. Only _factory was being protected. addObjectToPool - took factory methods out of synchronized scope. The decision on whether or not to add the returned object back to the pool is made inside the synchronized block and no change in pool state should cause incorrect behavior for the factory methods outside the block. Also added an isClosed check before adding objects back to the pool. addObject - moved makeObject outside scope of synchronization and moved the assertOpen inside the synchronized block, catching (and rethrowing after cleanup) IllegalStateException, which could happen if the pool is closed while makeObject is in progress. [1] http://www.mail-archive.com/commons-dev@jakarta.apache.org/msg68616.html Pacth (pool-93-markt-v2.patch) from
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||