6796915: Deadlock in XAWT when switching virtual desktops
authordcherepanov
Mon, 12 Oct 2009 19:07:43 +0400
changeset 4254 b63d0a7f93a7
parent 3971 067e6580a577
child 4255 69e00373e85b
6796915: Deadlock in XAWT when switching virtual desktops Reviewed-by: art, anthony
jdk/src/solaris/classes/sun/awt/X11/XDropTargetRegistry.java
jdk/src/solaris/classes/sun/awt/X11/XWindowPeer.java
--- a/jdk/src/solaris/classes/sun/awt/X11/XDropTargetRegistry.java	Thu Oct 01 15:06:16 2009 +0400
+++ b/jdk/src/solaris/classes/sun/awt/X11/XDropTargetRegistry.java	Mon Oct 12 19:07:43 2009 +0400
@@ -534,71 +534,71 @@
         return entry.getSite(x, y);
     }
 
+    /*
+     * Note: this method should be called under AWT lock.
+     */
     public void registerDropSite(long window) {
+        assert XToolkit.isAWTLockHeldByCurrentThread();
+
         if (window == 0) {
             throw new IllegalArgumentException();
         }
 
         XDropTargetEventProcessor.activate();
 
-        XToolkit.awtLock();
-        try {
-            long toplevel = getToplevelWindow(window);
+        long toplevel = getToplevelWindow(window);
 
-            /*
-             * No window with WM_STATE property is found.
-             * Since the window can be a plugin window reparented to the browser
-             * toplevel, we cannot determine which window will eventually have
-             * WM_STATE property set. So we schedule a timer callback that will
-             * periodically attempt to find an ancestor with WM_STATE and
-             * register the drop site appropriately.
-             */
-            if (toplevel == 0) {
-                addDelayedRegistrationEntry(window);
-                return;
+        /*
+         * No window with WM_STATE property is found.
+         * Since the window can be a plugin window reparented to the browser
+         * toplevel, we cannot determine which window will eventually have
+         * WM_STATE property set. So we schedule a timer callback that will
+         * periodically attempt to find an ancestor with WM_STATE and
+         * register the drop site appropriately.
+         */
+        if (toplevel == 0) {
+            addDelayedRegistrationEntry(window);
+            return;
+        }
+
+        if (toplevel == window) {
+            Iterator dropTargetProtocols =
+                XDragAndDropProtocols.getDropTargetProtocols();
+
+            while (dropTargetProtocols.hasNext()) {
+                XDropTargetProtocol dropTargetProtocol =
+                    (XDropTargetProtocol)dropTargetProtocols.next();
+                dropTargetProtocol.registerDropTarget(toplevel);
             }
-
-            if (toplevel == window) {
-                Iterator dropTargetProtocols =
-                    XDragAndDropProtocols.getDropTargetProtocols();
-
-                while (dropTargetProtocols.hasNext()) {
-                    XDropTargetProtocol dropTargetProtocol =
-                        (XDropTargetProtocol)dropTargetProtocols.next();
-                    dropTargetProtocol.registerDropTarget(toplevel);
-                }
-            } else {
-                registerEmbeddedDropSite(toplevel, window);
-            }
-        } finally {
-            XToolkit.awtUnlock();
+        } else {
+            registerEmbeddedDropSite(toplevel, window);
         }
     }
 
+    /*
+     * Note: this method should be called under AWT lock.
+     */
     public void unregisterDropSite(long window) {
+        assert XToolkit.isAWTLockHeldByCurrentThread();
+
         if (window == 0) {
             throw new IllegalArgumentException();
         }
 
-        XToolkit.awtLock();
-        try {
-            long toplevel = getToplevelWindow(window);
+        long toplevel = getToplevelWindow(window);
 
-            if (toplevel == window) {
-                Iterator dropProtocols =
-                    XDragAndDropProtocols.getDropTargetProtocols();
-
-                removeDelayedRegistrationEntry(window);
+        if (toplevel == window) {
+            Iterator dropProtocols =
+                XDragAndDropProtocols.getDropTargetProtocols();
 
-                while (dropProtocols.hasNext()) {
-                    XDropTargetProtocol dropProtocol = (XDropTargetProtocol)dropProtocols.next();
-                    dropProtocol.unregisterDropTarget(window);
-                }
-            } else {
-                unregisterEmbeddedDropSite(toplevel, window);
+            removeDelayedRegistrationEntry(window);
+
+            while (dropProtocols.hasNext()) {
+                XDropTargetProtocol dropProtocol = (XDropTargetProtocol)dropProtocols.next();
+                dropProtocol.unregisterDropTarget(window);
             }
-        } finally {
-            XToolkit.awtUnlock();
+        } else {
+            unregisterEmbeddedDropSite(toplevel, window);
         }
     }
 
--- a/jdk/src/solaris/classes/sun/awt/X11/XWindowPeer.java	Thu Oct 01 15:06:16 2009 +0400
+++ b/jdk/src/solaris/classes/sun/awt/X11/XWindowPeer.java	Mon Oct 12 19:07:43 2009 +0400
@@ -1757,25 +1757,36 @@
         }
     }
 
+    // should be synchronized on awtLock
     private int dropTargetCount = 0;
 
-    public synchronized void addDropTarget() {
-        if (dropTargetCount == 0) {
-            long window = getWindow();
-            if (window != 0) {
-                XDropTargetRegistry.getRegistry().registerDropSite(window);
+    public void addDropTarget() {
+        XToolkit.awtLock();
+        try {
+            if (dropTargetCount == 0) {
+                long window = getWindow();
+                if (window != 0) {
+                    XDropTargetRegistry.getRegistry().registerDropSite(window);
+                }
             }
+            dropTargetCount++;
+        } finally {
+            XToolkit.awtUnlock();
         }
-        dropTargetCount++;
     }
 
-    public synchronized void removeDropTarget() {
-        dropTargetCount--;
-        if (dropTargetCount == 0) {
-            long window = getWindow();
-            if (window != 0) {
-                XDropTargetRegistry.getRegistry().unregisterDropSite(window);
+    public void removeDropTarget() {
+        XToolkit.awtLock();
+        try {
+            dropTargetCount--;
+            if (dropTargetCount == 0) {
+                long window = getWindow();
+                if (window != 0) {
+                    XDropTargetRegistry.getRegistry().unregisterDropSite(window);
+                }
             }
+        } finally {
+            XToolkit.awtUnlock();
         }
     }
     void addRootPropertyEventDispatcher() {
@@ -1838,13 +1849,18 @@
         }
     }
 
-    protected synchronized void updateDropTarget() {
-        if (dropTargetCount > 0) {
-            long window = getWindow();
-            if (window != 0) {
-                XDropTargetRegistry.getRegistry().unregisterDropSite(window);
-                XDropTargetRegistry.getRegistry().registerDropSite(window);
+    protected void updateDropTarget() {
+        XToolkit.awtLock();
+        try {
+            if (dropTargetCount > 0) {
+                long window = getWindow();
+                if (window != 0) {
+                    XDropTargetRegistry.getRegistry().unregisterDropSite(window);
+                    XDropTargetRegistry.getRegistry().registerDropSite(window);
+                }
             }
+        } finally {
+            XToolkit.awtUnlock();
         }
     }