-
Bug
-
Resolution: Fixed
-
P3
-
1.2.0
-
1.2.2
-
x86, sparc
-
solaris_2.6, windows_nt
Name: paC48320 Date: 03/13/98
Attached is a file (using only AWT and no Swing) which will
deadlock every time. It demonstrates a built-in deadlock
between Container.add() and Container.addNotify() when a
modal dialog is invoked.
In a nutshell, we believe there are two dangerous pieces of
code, both in Container.java. They share a common assumption
that is not valid -- namely that an addNotify() will not cause
another thread to contend for Component.LOCK. This assumption
can be broken by bringing up a modal dialog.
The first place is in Container.addImpl() where it does the
following code. This code is inside a larger
synchronized(Component.LOCK):
if (peer != null) {
comp.addNotify();
}
The second is in Container.addNotify(). The method has a
synchronized(Component.LOCK) block in which it is calling
addNotify() for all its child objects.
Now you might choose to view this as improper use of addNotify,
in which case you can ignore the suggestions below. Otherwise,
we would recommend the following 2 changes be made:
Container.addImpl():
Take the comp.addNotify() out of the synchronized block.
Container.addNotify()
Clone the component list and use that outside of a
synchronized block.
BTW, consulting your bug database makes me suspect the following
bugs may be caused by this problem:
4046430
4084320
4095123
============================================================
following is a demo of the bug
============================================================
package deadlock;
import java.awt.*;
import java.awt.event.*;
public class deadlock {
public deadlock() {
Frame1 frame = new Frame1();
frame.validate();
frame.setVisible(true);
}
//Main method
public static void main(String[] args) {
new deadlock();
}
}
class Frame1 extends Frame {
//Construct the frame
BorderLayout borderLayout1 = new BorderLayout();
BorderLayout borderLayout2 = new BorderLayout();
Frame1() {
try {
jbInit();
}
catch (Exception e) {
e.printStackTrace();
}
}
//Component initialization
private void jbInit() throws Exception {
MyPanel panel1 = new MyPanel(this);
this.setLayout(borderLayout1);
this.setSize(new Dimension(400, 300));
this.setTitle("Frame Title");
panel1.setLayout(borderLayout2);
this.add(panel1, BorderLayout.CENTER);
}
}
class Dialog1 extends Dialog {
BorderLayout borderLayout1 = new BorderLayout();
Button button1 = new Button();
Dialog1(Frame f) {
super(f, true); // <<<<<< create MODAL dialog (make 'false' to prevent deadlock)
try {
jbInit();
}
catch (Exception e) {
e.printStackTrace();
}
}
void jbInit() throws Exception {
button1.setLabel("close");
button1.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(ActionEvent e) {
button1_actionPerformed(e);
}
});
this.setLayout(borderLayout1);
this.add(button1, BorderLayout.NORTH);
}
void button1_actionPerformed(ActionEvent e) {
dispose();
}
}
class MyPanel extends Panel {
Frame frame;
MyPanel(Frame f) {
frame = f;
}
// The heart of the problem is here.
// Bringing up a modal dialog from an addNotify()
// will guarantee(!) a deadlock
public void addNotify() { // <<<<<<<<<<<
super.addNotify();
System.out.println("AddNotify bringing up modal dialog...");
Dialog1 dlg = new Dialog1(frame);
dlg.pack();
dlg.setVisible(true);
System.err.println("back from modal dialog");
}
}
(Review ID: 26512)
======================================================================
- duplicates
-
JDK-4195565 Window hide() does not hide its children on Win32 while on Solaris it does
- Closed
-
JDK-4195569 Solaris: hide a modal dialog's parent could cause the left Frame freeze
- Closed