United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
Bug ID: JDK-6607660 java.awt.Container.getMouseEventTargetImpl should be invoked while holding the TreeLock
JDK-6607660 : java.awt.Container.getMouseEventTargetImpl should be invoked while holding the TreeLock

Details
Type:
Bug
Submit Date:
2007-09-21
Status:
Closed
Updated Date:
2011-05-17
Project Name:
JDK
Resolved Date:
2011-05-17
Component:
client-libs
OS:
generic
Sub-Component:
java.awt
CPU:
generic
Priority:
P4
Resolution:
Fixed
Affected Versions:
7
Fixed Versions:

Related Reports
Relates:
Relates:

Sub Tasks

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
EVALUATION

Need to add the locking. This may require to perform some comprehensive testing.
                                     
2007-09-21
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 {
                                     
2007-10-10



Hardware and Software, Engineered to Work Together