From 0e2b7c8fe59f2c999a0f11890fe479fca3226266 Mon Sep 17 00:00:00 2001 From: anthony Date: Tue, 19 May 2009 12:15:18 +0400 Subject: [PATCH] 6811219: Deadlock java AWT in XWarningWindow Summary: The locking scheme has been re-architected, the code slightly refactored. Reviewed-by: art, dcherepanov --- .../classes/sun/awt/X11/XWarningWindow.java | 179 ++++++++---------- .../classes/sun/awt/X11/XWindowPeer.java | 2 +- 2 files changed, 84 insertions(+), 97 deletions(-) diff --git a/src/solaris/classes/sun/awt/X11/XWarningWindow.java b/src/solaris/classes/sun/awt/X11/XWarningWindow.java index adb536440..a06d8bc85 100644 --- a/src/solaris/classes/sun/awt/X11/XWarningWindow.java +++ b/src/solaris/classes/sun/awt/X11/XWarningWindow.java @@ -34,74 +34,68 @@ import sun.awt.AWTAccessor; import sun.awt.SunToolkit; class XWarningWindow extends XWindow { - private final static int showingDelay = 330; - private final static int hidingDelay = 2000; + private final static int SHOWING_DELAY = 330; + private final static int HIDING_DELAY = 2000; private final Window ownerWindow; private WeakReference ownerPeer; - - public final Window getOwnerWindow() { - return ownerWindow; - } private long parentWindow; private final static String OWNER = "OWNER"; - - private static XIconInfo[][] icons; - private InfoWindow.Tooltip tooltip; - private static synchronized XIconInfo getSecurityIconInfo(int size, int num) { - if (icons == null) { - icons = new XIconInfo[4][3]; - if (XlibWrapper.dataModel == 32) { - icons[0][0] = new XIconInfo(XAWTIcon32_security_icon_bw16_png.security_icon_bw16_png); - icons[0][1] = new XIconInfo(XAWTIcon32_security_icon_interim16_png.security_icon_interim16_png); - icons[0][2] = new XIconInfo(XAWTIcon32_security_icon_yellow16_png.security_icon_yellow16_png); - icons[1][0] = new XIconInfo(XAWTIcon32_security_icon_bw24_png.security_icon_bw24_png); - icons[1][1] = new XIconInfo(XAWTIcon32_security_icon_interim24_png.security_icon_interim24_png); - icons[1][2] = new XIconInfo(XAWTIcon32_security_icon_yellow24_png.security_icon_yellow24_png); - icons[2][0] = new XIconInfo(XAWTIcon32_security_icon_bw32_png.security_icon_bw32_png); - icons[2][1] = new XIconInfo(XAWTIcon32_security_icon_interim32_png.security_icon_interim32_png); - icons[2][2] = new XIconInfo(XAWTIcon32_security_icon_yellow32_png.security_icon_yellow32_png); - icons[3][0] = new XIconInfo(XAWTIcon32_security_icon_bw48_png.security_icon_bw48_png); - icons[3][1] = new XIconInfo(XAWTIcon32_security_icon_interim48_png.security_icon_interim48_png); - icons[3][2] = new XIconInfo(XAWTIcon32_security_icon_yellow48_png.security_icon_yellow48_png); - } else { - icons[0][0] = new XIconInfo(XAWTIcon64_security_icon_bw16_png.security_icon_bw16_png); - icons[0][1] = new XIconInfo(XAWTIcon64_security_icon_interim16_png.security_icon_interim16_png); - icons[0][2] = new XIconInfo(XAWTIcon64_security_icon_yellow16_png.security_icon_yellow16_png); - icons[1][0] = new XIconInfo(XAWTIcon64_security_icon_bw24_png.security_icon_bw24_png); - icons[1][1] = new XIconInfo(XAWTIcon64_security_icon_interim24_png.security_icon_interim24_png); - icons[1][2] = new XIconInfo(XAWTIcon64_security_icon_yellow24_png.security_icon_yellow24_png); - icons[2][0] = new XIconInfo(XAWTIcon64_security_icon_bw32_png.security_icon_bw32_png); - icons[2][1] = new XIconInfo(XAWTIcon64_security_icon_interim32_png.security_icon_interim32_png); - icons[2][2] = new XIconInfo(XAWTIcon64_security_icon_yellow32_png.security_icon_yellow32_png); - icons[3][0] = new XIconInfo(XAWTIcon64_security_icon_bw48_png.security_icon_bw48_png); - icons[3][1] = new XIconInfo(XAWTIcon64_security_icon_interim48_png.security_icon_interim48_png); - icons[3][2] = new XIconInfo(XAWTIcon64_security_icon_yellow48_png.security_icon_yellow48_png); - } - } - final int sizeIndex = size % icons.length; - return icons[sizeIndex][num % icons[sizeIndex].length]; - } - + /** + * Animation stage. + */ private volatile int currentIcon = 0; - /* -1 - uninitialized yet + /* -1 - uninitialized. * 0 - 16x16 * 1 - 24x24 * 2 - 32x32 * 3 - 48x48 */ - private volatile int currentSize = -1; - - /** Indicates whether the shape of the window must be updated - */ - private volatile boolean sizeUpdated = true; + private int currentSize = -1; + private static XIconInfo[][] icons; + private static XIconInfo getSecurityIconInfo(int size, int num) { + synchronized (XWarningWindow.class) { + if (icons == null) { + icons = new XIconInfo[4][3]; + if (XlibWrapper.dataModel == 32) { + icons[0][0] = new XIconInfo(XAWTIcon32_security_icon_bw16_png.security_icon_bw16_png); + icons[0][1] = new XIconInfo(XAWTIcon32_security_icon_interim16_png.security_icon_interim16_png); + icons[0][2] = new XIconInfo(XAWTIcon32_security_icon_yellow16_png.security_icon_yellow16_png); + icons[1][0] = new XIconInfo(XAWTIcon32_security_icon_bw24_png.security_icon_bw24_png); + icons[1][1] = new XIconInfo(XAWTIcon32_security_icon_interim24_png.security_icon_interim24_png); + icons[1][2] = new XIconInfo(XAWTIcon32_security_icon_yellow24_png.security_icon_yellow24_png); + icons[2][0] = new XIconInfo(XAWTIcon32_security_icon_bw32_png.security_icon_bw32_png); + icons[2][1] = new XIconInfo(XAWTIcon32_security_icon_interim32_png.security_icon_interim32_png); + icons[2][2] = new XIconInfo(XAWTIcon32_security_icon_yellow32_png.security_icon_yellow32_png); + icons[3][0] = new XIconInfo(XAWTIcon32_security_icon_bw48_png.security_icon_bw48_png); + icons[3][1] = new XIconInfo(XAWTIcon32_security_icon_interim48_png.security_icon_interim48_png); + icons[3][2] = new XIconInfo(XAWTIcon32_security_icon_yellow48_png.security_icon_yellow48_png); + } else { + icons[0][0] = new XIconInfo(XAWTIcon64_security_icon_bw16_png.security_icon_bw16_png); + icons[0][1] = new XIconInfo(XAWTIcon64_security_icon_interim16_png.security_icon_interim16_png); + icons[0][2] = new XIconInfo(XAWTIcon64_security_icon_yellow16_png.security_icon_yellow16_png); + icons[1][0] = new XIconInfo(XAWTIcon64_security_icon_bw24_png.security_icon_bw24_png); + icons[1][1] = new XIconInfo(XAWTIcon64_security_icon_interim24_png.security_icon_interim24_png); + icons[1][2] = new XIconInfo(XAWTIcon64_security_icon_yellow24_png.security_icon_yellow24_png); + icons[2][0] = new XIconInfo(XAWTIcon64_security_icon_bw32_png.security_icon_bw32_png); + icons[2][1] = new XIconInfo(XAWTIcon64_security_icon_interim32_png.security_icon_interim32_png); + icons[2][2] = new XIconInfo(XAWTIcon64_security_icon_yellow32_png.security_icon_yellow32_png); + icons[3][0] = new XIconInfo(XAWTIcon64_security_icon_bw48_png.security_icon_bw48_png); + icons[3][1] = new XIconInfo(XAWTIcon64_security_icon_interim48_png.security_icon_interim48_png); + icons[3][2] = new XIconInfo(XAWTIcon64_security_icon_yellow48_png.security_icon_yellow48_png); + } + } + } + final int sizeIndex = size % icons.length; + return icons[sizeIndex][num % icons[sizeIndex].length]; + } - private synchronized boolean updateIconSize() { - int newSize = currentSize; + private void updateIconSize() { + int newSize = -1; if (ownerWindow != null) { Insets insets = ownerWindow.getInsets(); @@ -117,14 +111,32 @@ class XWarningWindow extends XWindow { newSize = 3; } } - if (newSize != currentSize) { - currentSize = newSize; - sizeUpdated = true; + // Make sure we have a valid size + if (newSize == -1) { + newSize = 0; + } + + // Note: this is not the most wise solution to use awtLock here, + // this should have been sync'ed with the stateLock. However, + // the awtLock must be taken first (see XBaseWindow.getStateLock()), + // and we need the awtLock anyway to update the shape of the icon. + // So it's easier to use just one lock instead. + XToolkit.awtLock(); + try { + if (newSize != currentSize) { + currentSize = newSize; + XIconInfo ico = getSecurityIconInfo(currentSize, 0); + XlibWrapper.SetBitmapShape(XToolkit.getDisplay(), getWindow(), + ico.getWidth(), ico.getHeight(), ico.getIntData()); + AWTAccessor.getWindowAccessor().setSecurityWarningSize( + ownerWindow, ico.getWidth(), ico.getHeight()); + } + } finally { + XToolkit.awtUnlock(); } - return sizeUpdated; } - private synchronized XIconInfo getSecurityIconInfo() { + private XIconInfo getSecurityIconInfo() { updateIconSize(); return getSecurityIconInfo(currentSize, currentIcon); } @@ -183,28 +195,6 @@ class XWarningWindow extends XWindow { } } - private void updateWarningWindowBounds() { - XWindowPeer peer = ownerPeer.get(); - if (peer != null) { - synchronized (this) { - if (updateIconSize()) { - XIconInfo ico = getSecurityIconInfo(); - XToolkit.awtLock(); - try { - XlibWrapper.SetBitmapShape(XToolkit.getDisplay(), getWindow(), - ico.getWidth(), ico.getHeight(), ico.getIntData()); - } finally { - XToolkit.awtUnlock(); - } - sizeUpdated = false; - AWTAccessor.getWindowAccessor().setSecurityWarningSize( - ownerWindow, ico.getWidth(), ico.getHeight()); - } - } - peer.repositionSecurityWarning(); - } - } - /** * @param x,y,w,h coordinates of the untrusted window */ @@ -376,25 +366,22 @@ class XWarningWindow extends XWindow { private final Runnable showingTask = new Runnable() { public void run() { - new Thread() { - public void run() { - if (!isVisible()) { - xSetVisible(true); - updateWarningWindowBounds(); - } - repaint(); - if (currentIcon > 0) { - currentIcon--; - XToolkit.schedule(showingTask, showingDelay); - } - }}.start(); + if (!isVisible()) { + xSetVisible(true); + updateIconSize(); + XWindowPeer peer = ownerPeer.get(); + if (peer != null) { + peer.repositionSecurityWarning(); + } + } + repaint(); + if (currentIcon > 0) { + currentIcon--; + XToolkit.schedule(showingTask, SHOWING_DELAY); + } } }; - public void setSecurityWarningVisible(boolean visible) { - setSecurityWarningVisible(visible, true); - } - public void setSecurityWarningVisible(boolean visible, boolean doSchedule) { if (visible) { XToolkit.remove(hidingTask); @@ -416,7 +403,7 @@ class XWarningWindow extends XWindow { return; } if (doSchedule) { - XToolkit.schedule(hidingTask, hidingDelay); + XToolkit.schedule(hidingTask, HIDING_DELAY); } else { hidingTask.run(); } diff --git a/src/solaris/classes/sun/awt/X11/XWindowPeer.java b/src/solaris/classes/sun/awt/X11/XWindowPeer.java index e78d007bd..d578bc6bf 100644 --- a/src/solaris/classes/sun/awt/X11/XWindowPeer.java +++ b/src/solaris/classes/sun/awt/X11/XWindowPeer.java @@ -1108,7 +1108,7 @@ class XWindowPeer extends XPanelPeer implements WindowPeer, } } - warningWindow.setSecurityWarningVisible(show); + warningWindow.setSecurityWarningVisible(show, true); } boolean isOverrideRedirect() { -- GitLab