提交 0e2b7c8f 编写于 作者: A anthony

6811219: Deadlock java AWT in XWarningWindow

Summary: The locking scheme has been re-architected, the code slightly refactored.
Reviewed-by: art, dcherepanov
上级 a68d5dbb
...@@ -34,74 +34,68 @@ import sun.awt.AWTAccessor; ...@@ -34,74 +34,68 @@ import sun.awt.AWTAccessor;
import sun.awt.SunToolkit; import sun.awt.SunToolkit;
class XWarningWindow extends XWindow { class XWarningWindow extends XWindow {
private final static int showingDelay = 330; private final static int SHOWING_DELAY = 330;
private final static int hidingDelay = 2000; private final static int HIDING_DELAY = 2000;
private final Window ownerWindow; private final Window ownerWindow;
private WeakReference<XWindowPeer> ownerPeer; private WeakReference<XWindowPeer> ownerPeer;
public final Window getOwnerWindow() {
return ownerWindow;
}
private long parentWindow; private long parentWindow;
private final static String OWNER = "OWNER"; private final static String OWNER = "OWNER";
private static XIconInfo[][] icons;
private InfoWindow.Tooltip tooltip; private InfoWindow.Tooltip tooltip;
private static synchronized XIconInfo getSecurityIconInfo(int size, int num) { /**
if (icons == null) { * Animation stage.
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 volatile int currentIcon = 0; private volatile int currentIcon = 0;
/* -1 - uninitialized yet /* -1 - uninitialized.
* 0 - 16x16 * 0 - 16x16
* 1 - 24x24 * 1 - 24x24
* 2 - 32x32 * 2 - 32x32
* 3 - 48x48 * 3 - 48x48
*/ */
private volatile int currentSize = -1; private int currentSize = -1;
private static XIconInfo[][] icons;
/** Indicates whether the shape of the window must be updated private static XIconInfo getSecurityIconInfo(int size, int num) {
*/ synchronized (XWarningWindow.class) {
private volatile boolean sizeUpdated = true; 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() { private void updateIconSize() {
int newSize = currentSize; int newSize = -1;
if (ownerWindow != null) { if (ownerWindow != null) {
Insets insets = ownerWindow.getInsets(); Insets insets = ownerWindow.getInsets();
...@@ -117,14 +111,32 @@ class XWarningWindow extends XWindow { ...@@ -117,14 +111,32 @@ class XWarningWindow extends XWindow {
newSize = 3; newSize = 3;
} }
} }
if (newSize != currentSize) { // Make sure we have a valid size
currentSize = newSize; if (newSize == -1) {
sizeUpdated = true; 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(); updateIconSize();
return getSecurityIconInfo(currentSize, currentIcon); return getSecurityIconInfo(currentSize, currentIcon);
} }
...@@ -183,28 +195,6 @@ class XWarningWindow extends XWindow { ...@@ -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 * @param x,y,w,h coordinates of the untrusted window
*/ */
...@@ -376,25 +366,22 @@ class XWarningWindow extends XWindow { ...@@ -376,25 +366,22 @@ class XWarningWindow extends XWindow {
private final Runnable showingTask = new Runnable() { private final Runnable showingTask = new Runnable() {
public void run() { public void run() {
new Thread() { if (!isVisible()) {
public void run() { xSetVisible(true);
if (!isVisible()) { updateIconSize();
xSetVisible(true); XWindowPeer peer = ownerPeer.get();
updateWarningWindowBounds(); if (peer != null) {
} peer.repositionSecurityWarning();
repaint(); }
if (currentIcon > 0) { }
currentIcon--; repaint();
XToolkit.schedule(showingTask, showingDelay); if (currentIcon > 0) {
} currentIcon--;
}}.start(); XToolkit.schedule(showingTask, SHOWING_DELAY);
}
} }
}; };
public void setSecurityWarningVisible(boolean visible) {
setSecurityWarningVisible(visible, true);
}
public void setSecurityWarningVisible(boolean visible, boolean doSchedule) { public void setSecurityWarningVisible(boolean visible, boolean doSchedule) {
if (visible) { if (visible) {
XToolkit.remove(hidingTask); XToolkit.remove(hidingTask);
...@@ -416,7 +403,7 @@ class XWarningWindow extends XWindow { ...@@ -416,7 +403,7 @@ class XWarningWindow extends XWindow {
return; return;
} }
if (doSchedule) { if (doSchedule) {
XToolkit.schedule(hidingTask, hidingDelay); XToolkit.schedule(hidingTask, HIDING_DELAY);
} else { } else {
hidingTask.run(); hidingTask.run();
} }
......
...@@ -1108,7 +1108,7 @@ class XWindowPeer extends XPanelPeer implements WindowPeer, ...@@ -1108,7 +1108,7 @@ class XWindowPeer extends XPanelPeer implements WindowPeer,
} }
} }
warningWindow.setSecurityWarningVisible(show); warningWindow.setSecurityWarningVisible(show, true);
} }
boolean isOverrideRedirect() { boolean isOverrideRedirect() {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册