(v3.x) Deadlock in case of concurrent calls to MultiThreadedHttpConnectionManager.shutdown and shutdownAll ----------------------------------------------------------------------------------------------------------
Key: HTTPCLIENT-976 URL: https://issues.apache.org/jira/browse/HTTPCLIENT-976 Project: HttpComponents HttpClient Issue Type: Bug Affects Versions: 3.1 Final Reporter: Sylvain Laurent Fix For: 3.1.1 There's a concurrency issue in MultiThreadedHttpConnectionManager in case 2 threads call shutdown and shutdownAll in parallel. Let's say Thread A calls shutdownAll (which is static) and Thread B calls shutdown (on an instance M of MultiThreadedHttpConnectionManager ). Here is an example of a deadlock : - Thread A enters shutdownAll and acquires lock on REFERENCE_TO_CONNECTION_SOURCE and ALL_CONNECTION_MANAGERS - Thread B enters shutdown for instance M and acquires lock on M (shutdown is synchronized) and its connectionPool and - inside shutdownAll Thread A tries to call shutdown on M - Thread A waits for lock on M (currently held by B) - Thread B continues and calls shutdownCheckedOutConnections which tries to acquire lock on REFERENCE_TO_CONNECTION_SOURCE, currently held by thread A --> DEADLOCK ! Here is a stacktrace for version 3.0.1 (but the bug seems to be in 3.1 too) : {code} "Thread-2": at org.apache.commons.httpclient.MultiThreadedHttpConnectionManager.shutdown(MultiThreadedHttpConnectionManager.java:266) - waiting to lock <0x030dc020> (a org.apache.commons.httpclient.MultiThreadedHttpConnectionManager) at org.apache.commons.httpclient.MultiThreadedHttpConnectionManager.shutdownAll(MultiThreadedHttpConnectionManager.java:120) - locked <0x030db0e0> (a java.util.WeakHashMap) - locked <0x030db0a0> (a java.util.HashMap) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at org.springframework.beans.factory.support.DisposableBeanAdapter.invokeCustomDestroyMethod(DisposableBeanAdapter.java:273) at org.springframework.beans.factory.support.DisposableBeanAdapter.destroy(DisposableBeanAdapter.java:199) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.destroyBean(DefaultSingletonBeanRegistry.java:487) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.destroySingleton(DefaultSingletonBeanRegistry.java:463) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.destroySingletons(DefaultSingletonBeanRegistry.java:431) - locked <0x03149a08> (a java.util.LinkedHashMap) at org.springframework.context.support.AbstractApplicationContext.destroyBeans(AbstractApplicationContext.java:1048) at org.springframework.context.support.AbstractApplicationContext.doClose(AbstractApplicationContext.java:1022) at org.springframework.context.support.AbstractApplicationContext$3.run(AbstractApplicationContext.java:940) "Thread-1": at org.apache.commons.httpclient.MultiThreadedHttpConnectionManager.shutdownCheckedOutConnections(MultiThreadedHttpConnectionManager.java:186) - waiting to lock <0x030db0a0> (a java.util.HashMap) at org.apache.commons.httpclient.MultiThreadedHttpConnectionManager.access$600(MultiThreadedHttpConnectionManager.java:64) at org.apache.commons.httpclient.MultiThreadedHttpConnectionManager$ConnectionPool.shutdown(MultiThreadedHttpConnectionManager.java:713) - locked <0x030dd4b8> (a org.apache.commons.httpclient.MultiThreadedHttpConnectionManager$ConnectionPool) at org.apache.commons.httpclient.MultiThreadedHttpConnectionManager.shutdown(MultiThreadedHttpConnectionManager.java:269) - locked <0x030dd4b8> (a org.apache.commons.httpclient.MultiThreadedHttpConnectionManager$ConnectionPool) - locked <0x030dc020> (a org.apache.commons.httpclient.MultiThreadedHttpConnectionManager) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at org.springframework.beans.factory.support.DisposableBeanAdapter.invokeCustomDestroyMethod(DisposableBeanAdapter.java:273) at org.springframework.beans.factory.support.DisposableBeanAdapter.destroy(DisposableBeanAdapter.java:199) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.destroyBean(DefaultSingletonBeanRegistry.java:487) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.destroySingleton(DefaultSingletonBeanRegistry.java:463) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.destroyBean(DefaultSingletonBeanRegistry.java:498) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.destroySingleton(DefaultSingletonBeanRegistry.java:463) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.destroySingletons(DefaultSingletonBeanRegistry.java:431) - locked <0x02cf9810> (a java.util.LinkedHashMap) at org.springframework.context.support.AbstractApplicationContext.destroyBeans(AbstractApplicationContext.java:1048) at org.springframework.context.support.AbstractApplicationContext.doClose(AbstractApplicationContext.java:1022) at org.springframework.context.support.AbstractApplicationContext$3.run(AbstractApplicationContext.java:940) {code} -- This message is automatically generated by JIRA. - You can reply to this email to add a comment to the issue online. --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@hc.apache.org For additional commands, e-mail: dev-h...@hc.apache.org