JDK-6607660 : java.awt.Container.getMouseEventTargetImpl should be invoked while holding the TreeLock
  • Type: Bug
  • Component: client-libs
  • Sub-Component: java.awt
  • Affected Version: 7
  • Priority: P4
  • Status: Closed
  • Resolution: Fixed
  • OS: generic
  • CPU: generic
  • Submitted: 2007-09-21
  • Updated: 2011-05-17
  • Resolved: 2011-05-17
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 7
7 b25Fixed
Related Reports
Relates :  
Relates :  
Description
The java.awt.Container.getMouseEventTargetImpl method is being called w/o holding the TreeLock (say, when it gets invoked from within the LightweightDispatcher). 

However this method deals with the component hierarchy. The same reason caused us to use this lock in the hw/lw mixing code (see 4811096). And actually this lock is required to fix the 5062995 (shaped windows and components), because the contains() method should fall back to the mixing code in order to get the shape of the component and determine whether it contains the given pixel.

Comments
SUGGESTED FIX --- old/src/share/classes/java/awt/Container.java 2007-10-10 11:26:47.000000000 +0400 +++ new/src/share/classes/java/awt/Container.java 2007-10-10 11:26:47.000000000 +0400 @@ -2268,53 +2268,55 @@ EventTargetFilter filter, boolean searchHeavyweightChildren, boolean searchHeavyweightDescendants) { - int ncomponents = this.ncomponents; - Component component[] = this.component; + synchronized (getTreeLock()) { + int ncomponents = this.ncomponents; + Component component[] = this.component; - for (int i = 0 ; i < ncomponents ; i++) { - Component comp = component[i]; - if (comp != null && comp.visible && - ((!searchHeavyweightChildren && - comp.peer instanceof LightweightPeer) || - (searchHeavyweightChildren && - !(comp.peer instanceof LightweightPeer))) && - comp.contains(x - comp.x, y - comp.y)) { - - // found a component that intersects the point, see if there is - // a deeper possibility. - if (comp instanceof Container) { - Container child = (Container) comp; - Component deeper = child.getMouseEventTarget(x - child.x, - y - child.y, - includeSelf, - filter, - searchHeavyweightDescendants); - if (deeper != null) { - return deeper; - } - } else { - if (filter.accept(comp)) { - // there isn't a deeper target, but this component is a - // target - return comp; + for (int i = 0 ; i < ncomponents ; i++) { + Component comp = component[i]; + if (comp != null && comp.visible && + ((!searchHeavyweightChildren && + comp.peer instanceof LightweightPeer) || + (searchHeavyweightChildren && + !(comp.peer instanceof LightweightPeer))) && + comp.contains(x - comp.x, y - comp.y)) { + + // found a component that intersects the point, see if there is + // a deeper possibility. + if (comp instanceof Container) { + Container child = (Container) comp; + Component deeper = child.getMouseEventTarget(x - child.x, + y - child.y, + includeSelf, + filter, + searchHeavyweightDescendants); + if (deeper != null) { + return deeper; + } + } else { + if (filter.accept(comp)) { + // there isn't a deeper target, but this component is a + // target + return comp; + } } - } + } } - } - - boolean isPeerOK; - boolean isMouseOverMe; - - isPeerOK = (peer instanceof LightweightPeer) || includeSelf; - isMouseOverMe = contains(x,y); - // didn't find a child target, return this component if it's a possible - // target - if (isMouseOverMe && isPeerOK && filter.accept(this)) { - return this; + boolean isPeerOK; + boolean isMouseOverMe; + + isPeerOK = (peer instanceof LightweightPeer) || includeSelf; + isMouseOverMe = contains(x,y); + + // didn't find a child target, return this component if it's a possible + // target + if (isMouseOverMe && isPeerOK && filter.accept(this)) { + return this; + } + // no possible target + return null; } - // no possible target - return null; } static interface EventTargetFilter {
10-10-2007

EVALUATION Need to add the locking. This may require to perform some comprehensive testing.
21-09-2007