JDK-6280857 : SystemTray testcase deadlocks on Linux
  • Type: Bug
  • Component: client-libs
  • Sub-Component: java.awt
  • Affected Version: 6
  • Priority: P3
  • Status: Closed
  • Resolution: Fixed
  • OS: linux
  • CPU: x86
  • Submitted: 2005-06-06
  • Updated: 2011-01-19
  • Resolved: 2005-08-06
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 6
6 b47Fixed
Related Reports
Relates :  
Relates :  
Description
This issue is faced in Redhat Linux Advanced Server 3.0 with mustang b39. Running the attached testcase on the OS results in deadlock. This does not occur always - I could reproduce it 2 out of three times.

Attached is the thread dump when it deadlocks
###@###.### 2005-06-06 13:44:41 GMT

Comments
SUGGESTED FIX ------- XTrayIconPeer.java ------- *** /tmp/sccs.tQaGPG Wed Jun 8 16:47:52 2005 --- XTrayIconPeer.java Wed Jun 8 16:43:43 2005 *************** *** 784,795 **** } else if (corner.x >= scrSize.width/2 && corner.y >= scrSize.height/2) { // 4th square setLocation(corner.x - indent - size.width, corner.y - indent - size.height); } ! super.show(); ! closer.schedule(); } public void hide() { closer.close(); } --- 784,799 ---- } else if (corner.x >= scrSize.width/2 && corner.y >= scrSize.height/2) { // 4th square setLocation(corner.x - indent - size.width, corner.y - indent - size.height); } ! EventQueue.invokeLater(new Runnable() { ! public void run() { ! InfoWindow.super.show(); ! InfoWindow.this.closer.schedule(); ! } ! }); } public void hide() { closer.close(); } ###@###.### 2005-06-16 08:02:20 GMT The fix above wasn't correct. This is the corrected one: ------- XTrayIconPeer.java ------- *** /tmp/sccs.lyaaMI ��+ ��L�� 25 18:42:19 2005 --- XTrayIconPeer.java ��+ ��L�� 25 18:39:36 2005 *************** *** 13,22 **** --- 13,24 ---- import java.text.BreakIterator; import java.util.Vector; import java.lang.reflect.Field; import java.util.AbstractQueue; import java.util.concurrent.ArrayBlockingQueue; + import java.security.AccessController; + import java.security.PrivilegedAction; public class XTrayIconPeer implements TrayIconPeer { TrayIcon target; TrayIconEventProxy eventProxy; XEmbeddedFrame eframe; *************** *** 393,407 **** } public void updateImage(Image image) { this.image = image; Graphics g = getGraphics(); ! paint(g); ! g.dispose(); } public void paint(Graphics g) { ! if (g != null) { BufferedImage bufImage = new BufferedImage(curW, curH, BufferedImage.TYPE_INT_ARGB); Graphics2D gr = bufImage.createGraphics(); gr.setColor(getBackground()); gr.fillRect(0, 0, curW, curH); gr.drawImage(image, 0, 0, curW, curH, observer); --- 395,411 ---- } public void updateImage(Image image) { this.image = image; Graphics g = getGraphics(); ! if (g != null) { ! paint(g); ! g.dispose(); ! } } public void paint(Graphics g) { ! if (g != null && curW > 0 && curH > 0) { BufferedImage bufImage = new BufferedImage(curW, curH, BufferedImage.TYPE_INT_ARGB); Graphics2D gr = bufImage.createGraphics(); gr.setColor(getBackground()); gr.fillRect(0, 0, curW, curH); gr.drawImage(image, 0, 0, curW, curH, observer); *************** *** 467,476 **** --- 471,483 ---- textLabel.setBackground(TOOLTIP_BACKGROUND_COLOR); textLabel.setFont(TOOLTIP_TEXT_FONT); add(textLabel); } + /* + * WARNING: this method is executed on Toolkit thread! + */ void display() { String tip = xtiPeer.tooltipString; if (tip == null) { return; } else if (tip.length() > TOOLTIP_MAX_LENGTH) { *************** *** 477,492 **** textLabel.setText(tip.substring(0, TOOLTIP_MAX_LENGTH)); } else { textLabel.setText(tip); } ! if (!isPointerOverTrayIcon(xtiPeer.getBounds())) { ! return; ! } ! ! Point pointer = MouseInfo.getPointerInfo().getLocation(); ! show(new Point(pointer.x, pointer.y), TOOLTIP_MOUSE_CURSOR_INDENT); } void enter() { XToolkit.schedule(starter, TOOLTIP_START_DELAY_TIME); } --- 484,514 ---- textLabel.setText(tip.substring(0, TOOLTIP_MAX_LENGTH)); } else { textLabel.setText(tip); } ! // Execute on EDT to avoid deadlock (see 6280857). ! EventQueue.invokeLater(new Runnable() { ! public void run() { ! Point pointer = (Point)AccessController.doPrivileged(new PrivilegedAction() { ! public Object run() { ! if (!isPointerOverTrayIcon(xtiPeer.getBounds())) { ! return null; ! } ! return MouseInfo.getPointerInfo().getLocation(); ! } ! }); ! if (pointer == null) { ! return; ! } ! synchronized (xtiPeer) { ! if (!xtiPeer.isDisposed) { ! show(new Point(pointer.x, pointer.y), TOOLTIP_MOUSE_CURSOR_INDENT); ! } ! } ! } ! }); } void enter() { XToolkit.schedule(starter, TOOLTIP_START_DELAY_TIME); } *************** *** 772,782 **** void setCloser(Runnable action, int time) { closer.set(action, time); } ! public void show(Point corner, int indent) { pack(); Dimension size = getSize(); Dimension scrSize = Toolkit.getDefaultToolkit().getScreenSize(); --- 794,807 ---- void setCloser(Runnable action, int time) { closer.set(action, time); } ! // Must be executed on EDT. ! protected void show(Point corner, int indent) { ! assert !XToolkit.isToolkitThread(); ! pack(); Dimension size = getSize(); Dimension scrSize = Toolkit.getDefaultToolkit().getScreenSize(); *************** *** 791,806 **** } else if (corner.x >= scrSize.width/2 && corner.y >= scrSize.height/2) { // 4th square setLocation(corner.x - indent - size.width, corner.y - indent - size.height); } ! EventQueue.invokeLater(new Runnable() { ! public void run() { ! InfoWindow.super.show(); ! InfoWindow.this.closer.schedule(); ! } ! }); } public void hide() { closer.close(); } --- 816,827 ---- } else if (corner.x >= scrSize.width/2 && corner.y >= scrSize.height/2) { // 4th square setLocation(corner.x - indent - size.width, corner.y - indent - size.height); } ! InfoWindow.super.show(); ! InfoWindow.this.closer.schedule(); } public void hide() { closer.close(); }
16-06-2005

EVALUATION On Linux we should show tooltip and balloon windows on EDT. ###@###.### 2005-06-06 14:02:20 GMT The situation is as follows. EDT and XToolkit deadlock each other. XToolkit.run method gets the AWTLock supposing that no one runs client code on toolkit thread. XTrayIconPeer schedules a task which shows TrayIcon tooltip window that results in that Window.show() method is called trying to acquire the AWTTreeLock. At the same time EDT is doing some GUI work holding AWTTreeLock, then it tries to acquire the AWTLock. Then we have a deadlock. ###@###.### 2005-06-15 14:34:06 GMT The fix is refined (see Suggested Fix). ###@###.### 2005-07-01 11:43:08 GMT
06-06-2005