-
Type:
Bug
-
Status: Closed (View Workflow)
-
Priority:
Major
-
Resolution: Done
-
Affects Version/s: EAP_EWP 5.1.1, EAP_EWP 5.1.2
-
Fix Version/s: EAP_EWP 5.2.0
-
Component/s: JCA
-
Labels:None
-
Affects:Release Notes
-
Release Notes Text:
-
Release Notes Docs Status:Documented as Resolved Issue
-
Docs QE Status:NEW
A connection may leak when the idle timeout processing is executed setting the security-domain configuration. This leak is race condition issue between the IdleRemover thread and the JCA PoolFiller thread.
When the security-domain is set in datasource configuration, JBossManagedConnectionPool$BasePool.emptySubPool as the IdleRemover thread processing is called by processing of the 498th[*2] line in the removeIdleConnections method.
When the 494th[*1] line in the removeIdleConnections method as the IdleRemover thread is called, the 547th[*4] line in InternalManagedConnectionPool.fillToMin as the JCA PoolFiller thread is executed and a connection is created.
If [*4] is executed immediately after executing [*2], the pool.isEmpty[*3] processing in JBossManagedConnectionPool$BasePool.emptySubPool may return by true. If [*3] returns true, a connection is created which is not managed in connection pool. So if this behavior is repeating, a connection leaks at a time.
Moreover, if [*2] is executed before [*4] processing, all the connections will be released and connection will be not re-created to the min-pool-size.
|
the IdleRemover thread |
org.jboss.resource.connectionmanager.InternalManagedConnectionPool
|
449# public void removeIdleConnections()
|
--- snip
|
482# if (destroy != null)
|
483# {
|
484# for (int i = 0; i < destroy.size(); ++i)
|
485# {
|
486# ConnectionListener cl = (ConnectionListener) destroy.get(i);
|
487# if (trace)
|
488# log.trace("Destroying timedout connection " + cl);
|
489# doDestroy(cl);
|
490# }
|
491#
|
492# // We destroyed something, check the minimum.
|
493# if (shutdown.get() == false && poolParams.minSize > 0)
|
[*1]494# PoolFiller.fillPool(this);
|
495#
|
496# // Empty sub-pool
|
497# if (jmcp != null)
|
[*2]498# jmcp.getPoolingStrategy().emptySubPool(this);
|
499# }
|
|
|
org.jboss.resource.connectionmanager.JBossManagedConnectionPool
|
969# public void emptySubPool(InternalManagedConnectionPool pool)
|
970# {
|
971# if (pool != null)
|
972# {
|
973# synchronized (subPools)
|
974# {
|
975# for (Iterator i = subPools.values().iterator(); i.hasNext(); )
|
976# {
|
977# SubPoolContext subPoolContext = (SubPoolContext) i.next();
|
978# InternalManagedConnectionPool other = subPoolContext.getSubPool();
|
[*3]979# if (other == pool && pool.isEmpty())
|
980# {
|
981# pool.shutdown();
|
982# i.remove();
|
983# break;
|
984# }
|
985# }
|
986# }
|
987# }
|
988# }
|
|
the JCA PoolFiller thread |
org.jboss.resource.connectionmanager.InternalManagedConnectionPool
|
525# public void fillToMin()
|
526# {
|
527# while (true)
|
528# {
|
--- snip
|
544# // Create a connection to fill the pool
|
545# try
|
546# {
|
[*4]547# ConnectionListener cl = createConnectionEventListener(defaultSubject, defaultCri);
|
548# synchronized (cls)
|
549# {
|
550# if (trace)
|
551# log.trace("Filling pool cl=" + cl);
|
552# cls.add(cl);
|
553# }
|
554# }
|
[InternalManagedConnectionPool.java] http://anonsvn.jboss.org/repos/jbossas/tags/JBPAPP_5_1_2_GA/connector/src/main/org/jboss/resource/connectionmanager/InternalManagedConnectionPool.java
[JBossManagedConnectionPool.java] http://anonsvn.jboss.org/repos/jbossas/tags/JBPAPP_5_1_2_GA/connector/src/main/org/jboss/resource/connectionmanager/JBossManagedConnectionPool.java