Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-4119383

Deadlock between modal dialog and Container.add()

XMLWordPrintable

    • 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)
      ======================================================================

            dmendenhsunw David Mendenhall (Inactive)
            pallenba Peter Allenbach (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: