-
Bug
-
Resolution: Fixed
-
P4
-
11, 13, 14, 15
-
None
-
b08
Report by Adrian Nistor <adrnisto@amazon.com>.
The code in BeanContextSupport.java acquires synchronization objects in different orders. Once acquires BeanContext.globalHierarchyLock and then children, another acquires children and then BeanContext.globalHierarchyLock).
Acquiring synchronization objects in different orders can cause a circular wait (deadlock).
Here is the first order: (1) first acquire BeanContext.globalHierarchyLock and then children:
enter public method remove(Object) at line 484
call remove(Object, boolean) at line 485
acquire synchronization on BeanContext.globalHierarchyLock at line 502
acquire synchronization on children at line 534
Here is the second order: (2) first acquire children and then BeanContext.globalHierarchyLock:
enter public method propertyChange() at line 1110
acquire synchronization on children at line 1114
call remove(Object, boolean) at line 1121
acquire synchronization on BeanContext.globalHierarchyLock at line 502
A potential fix always acquires synchronization in only 1 order: first BeanContext.globalHierarchyLock and then children. Add a synchronized(BeanContext.globalHierarchyLock) before the synchronized(children) at line 1114.
This fix is correct because it does not add any new synchronization on BeanContext.globalHierarchyLock.
This is because a call to propertyChange() at line 1110 already performs synchronized(BeanContext.globalHierarchyLock) at line 502. See the 4th line of the call stack for the second order above.
I.e., this fix just calls synchronized(BeanContext.globalHierarchyLock) a bit earlier, which allows it to enforce only 1 order.
public void propertyChange(PropertyChangeEvent pce) {
String propertyName = pce.getPropertyName();
Object source = pce.getSource();
synchronized(BeanContext.globalHierarchyLock) { <<<<<<<<<<<<<< added this. See above discussion that this does *not* add new synchronization, just changes the lock order
synchronized(children) {
The code in BeanContextSupport.java acquires synchronization objects in different orders. Once acquires BeanContext.globalHierarchyLock and then children, another acquires children and then BeanContext.globalHierarchyLock).
Acquiring synchronization objects in different orders can cause a circular wait (deadlock).
Here is the first order: (1) first acquire BeanContext.globalHierarchyLock and then children:
enter public method remove(Object) at line 484
call remove(Object, boolean) at line 485
acquire synchronization on BeanContext.globalHierarchyLock at line 502
acquire synchronization on children at line 534
Here is the second order: (2) first acquire children and then BeanContext.globalHierarchyLock:
enter public method propertyChange() at line 1110
acquire synchronization on children at line 1114
call remove(Object, boolean) at line 1121
acquire synchronization on BeanContext.globalHierarchyLock at line 502
A potential fix always acquires synchronization in only 1 order: first BeanContext.globalHierarchyLock and then children. Add a synchronized(BeanContext.globalHierarchyLock) before the synchronized(children) at line 1114.
This fix is correct because it does not add any new synchronization on BeanContext.globalHierarchyLock.
This is because a call to propertyChange() at line 1110 already performs synchronized(BeanContext.globalHierarchyLock) at line 502. See the 4th line of the call stack for the second order above.
I.e., this fix just calls synchronized(BeanContext.globalHierarchyLock) a bit earlier, which allows it to enforce only 1 order.
public void propertyChange(PropertyChangeEvent pce) {
String propertyName = pce.getPropertyName();
Object source = pce.getSource();
synchronized(BeanContext.globalHierarchyLock) { <<<<<<<<<<<<<< added this. See above discussion that this does *not* add new synchronization, just changes the lock order
synchronized(children) {
- duplicates
-
JDK-8238569 Bean Context has a deadlock
-
- Closed
-