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

modalWait loop / modal dialogs can hang under certain circumstances

XMLWordPrintable

    • sparc
    • solaris_2.5.1


      Name: mf23781 Date: 12/01/97

      The problem is that clipboard operations (observed in this case) and
      modal dialog boxes (theoretically) can hang, because the flagging for
      modal loops is not quite right.

      Observed on AIX, but also present on Solaris and *all* derived
      ports. *** DEFECT 3557 **************************************


      Sample java program that shows the clipboard bad behavior....
      maybe more complicated than it needs to be, but....

      import java.awt.Toolkit;
      import java.awt.datatransfer.DataFlavor;
      import java.awt.datatransfer.Clipboard;
      import java.awt.datatransfer.StringSelection;
      import java.awt.datatransfer.Transferable;
      import java.awt.datatransfer.UnsupportedFlavorException;
      import java.io.IOException;

      public class CBfail
      {
        protected Clipboard xClipboard;
        public static MyStringSelection xStringSelection;

        public CBfail()
        {
          xClipboard = Toolkit.getDefaultToolkit().getSystemClipboard();


        }

        public void putToCb(String s)
        {
          getFromCb(); // see what's in it first

          xStringSelection = new MyStringSelection(s);
          System.out.print("xStringSelection '" + xStringSelection + "'\n");

          xClipboard.setContents(xStringSelection, xStringSelection);
          System.out.print("xClipboard.setContents '" + xClipboard + "'\n");
        }

        public String getFromCb()
        {
          String ps = new String("failure");
          Transferable t = xClipboard.getContents(this);
          System.out.print("Transferable '" + t + "'\n");
          try
          {
            ps = (String)t.getTransferData(DataFlavor.stringFlavor);
            System.out.print("xClipboard.getContents '" + ps + "'\n");
          }
          catch (UnsupportedFlavorException excpt)
          {
            System.out.println( "UnsupportedFlavorException caught" );
            System.out.println(excpt.getMessage());
          }
          catch (IOException excpt)
          {
            System.out.println( "IOException caught" );
            System.out.println(excpt.getMessage());
          }
          return ps;
        }

        public static void main(String args[])
        {
          CBfail cbf = new CBfail();
          cbf.putToCb("Put this in first");
          String s = cbf.getFromCb();
          System.out.print("Now do a paste operation into a window and see if
      you see this: '" + s + "'\n");
        }

        class MyStringSelection extends StringSelection
        {
          public MyStringSelection(String data)
          {
            super(data);
          }

          public void lostOwnership(Clipboard cb, Transferable t)
          {
            System.out.print("lostOwnership Clipboard " + cb + " Transferable
      " + t + "\n");
          }
        }
      }


      --


      Note:

      On AIX JDK 1.1.2 & 1.1.4, the app just hangs after the "Transferable" line.
      On OS/2, Win32 & Solaris, it works fine...

          <Note by rlee (Roger Lee), 97/11/10 16:10:49, action: assign>
      Old Owner: pjr
      New Owner: rlee



          <Note by rlee (Roger Lee), 97/11/10 17:11:47, action: note>
      It seems the hang occurs when the getTransferData() method invokes
      native method sun_awt_motif_X11Selection_pGetTransferData().
      I guess this looks like a locking contention problem at the moment.
      Continuing investigations..

          <Note by rlee (Roger Lee), 97/11/13 14:09:47, action: note>
      After wasting some time on a stupid debugging oversight, it seems that
      the modalWait() routine contains the problem.

      When going modal, it sets global inModalWait to request modal state and
      notifes the event queue thread to suspend (while inModalWait) normal
      business until the modal thread has finished.
      The event queue thread wakes up, takes note of the request and enters
      modal state, notifying other threads (the modal requestor) to continue.
      The modalWait() thread does its stuff, then decrements inModalWait,
      does AWT_NOTIFY_ALL, then AWT_UNLOCK, and now the modal activity is over.

      This isn't sufficient to allow the event queue thread to return to normal
      working, because while the modal caller thread is still working, it hasn't
      paused to allow the event queue thread to notice that inModalWait has
      been reset. I inserted an AWT_WAIT() near the end of modalWait() and
      this fixes the clipboard hang:

      src file: src/sunix/sun/awt/awt_MToolkit.c
      function: sun_awt_motif_MToolkit_modalWait()

      ...
          inModalWait--;
          modalActive--;

          AWT_NOTIFY_ALL();
          AWT_WAIT(TIMEOUT_INFINITY);
          AWT_UNLOCK();
      }

      However, I notice that the testcase puts some replacement text into
      the clipboard; this works on Solaris, but with this fix-so-far, not AIX.
      I need to satisfy myself that my fix hasn't broken something else.

          <Note by rlee (Roger Lee), 97/11/13 17:11:04, action: note>
      Matt explained that there are alternative 'clipboard' buffers;
      the one used by the Java Clipboard api uses the Motif clipboard
      and is accessible using Motif applications with cut/paste actions
      usually under an Edit menu. In addition, the application putting the
      data into the clipboard doesn't really do that, it's just notifying
      X that it is the program to ask for the data when another application
      wants to retrieve it. This means that the data is only available
      as long as the source application is active.

      To recap, the above change does fix the hang in getTransferData(),
      and the replacement clipboard data is correctly retrievable from
      a Motif application using a paste action.

      I propose to make this change to CMVC tomorrow. Any regressions elsewhere
      due to this change to the modalWait() code will come out in the wash.

          <Note by rlee (Roger Lee), 97/11/13 17:11:38, action: accept>
      Proposed change reviewed by rlee

          <Note by rlee (Roger Lee), 97/11/14 10:37:43, action: note>
      Jfixed u114 on Fri Nov 14 10:37:36 GMT 1997 by rlee

          <Note by sblack (Stephen Blackheath), 97/11/14 11:56:04, action: note>
      I took a look at this fix and at first I could not understand
      why it hung. The problem is that without this wait, if you go
      into a modal loop, exit the modal loop, and then go back into
      another modal loop immediately afterwards, the main event
      loop will not even notice that the first modal loop has exited.
      The second modal loop is then sitting there waiting for the
      main loop to notify it, but it is blissfully unaware that
      anything has happened...

      I don't think this fix is sufficient to avoid problems with
      one thread closing a modal loop and another thread opening one
      immediately afterwards (which is quite plausible, because of
      the locking). Perhaps some more flagging is required here.




      ======================================================================

            Unassigned Unassigned
            miflemi Mick Fleming
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: