Java Solaris Communities Sun Store Join SDN My Profile Why Join?
 
Bug Database
Bug Detail
Quick Lists
Top 25 Bugs
Top 25 RFE's
Recently Closed Bugs
Printable Page Printable Page


Bug Database
Bug ID: 4098756
Votes 3
Synopsis Deadlock when removing items from Choice component
Category java:classes_awt
Reported Against 1.1.5 , 1.2beta2
Release Fixed
State 11-Closed, Not Reproducible, bug
Priority: 4-Low
Related Bugs 4098758
Submit Date 11-DEC-1997
Description




I have a Choice component that consists of a set
of entries centered around a certain value.  When
another value is selected from the Choice, the
old entries are removed and new ones added,
centered around the new value.  On Windows 95 and
NT, if the arrow keys are used to select the
new value, the application deadlocks.

To reproduce:

1) Compile and run the included program.
2) Click on the Choice with the left mouse
   button to display the menu.
3) Use the up or down arrow keys to traverse
   the menu.  The application will lock up.

Analysis:

It looks like the peer has handled the arrow
key events and placed an ItemEvent in the
event queue.  This gets processed in the
EventDispatchThread.  At the same time, the
peer has directly called Choice.select() in
the AWT-Windows thread.  EventDispatchThread
acquire the Choice lock when removing the entries
then tries to remove them in the peer, thus
requiring a lock on the peer.  The peer lock
is already owned by the AWT-Windows thread
which is now trying to acquire the Choice lock
in select().  The thread dump follows the source
code.

Source code:

import java.awt.*;
import java.awt.event.*;

public class ChoiceTest extends Dialog implements ItemListener {

// Main program

    public static void main(String[] args) {

	Frame	f = new Frame("Choice Test");
	f.setSize(100, 100);
	f.show();

	ChoiceTest	win = new ChoiceTest(f);
	win.pack();
	win.show();

	System.exit(0);
    }

// The choice component

    private Choice	menu;

// Dialog constructor

    public ChoiceTest(Frame parent) {

	super(parent, /*modal=*/true);

	menu = new Choice();
	add(menu);

	buildMenu(10);

	menu.addItemListener(this);
    }

// Build a menu of 11 entries centered around the given value

    private void buildMenu(int val) {

	menu.removeAll();

	int	minVal = val - 5;
	int	maxVal = val + 5;
	for (int i=minVal; i<=maxVal; i++) menu.addItem(String.valueOf(i));

	menu.select(String.valueOf(val));
    }

// When a new item is selected, build a new menu centered around that item

    public void itemStateChanged(ItemEvent evt) {

	if ( evt.getStateChange() == ItemEvent.SELECTED ) {
	    int	val = Integer.parseInt(menu.getSelectedItem());
	    buildMenu(val);
	}
    }

} // End ChoiceTest

Full thread dump:

    "Screen Updater" (TID:0xf56260, sys_thread_t:0x877e30, Win32ID:0x51, state:CW) prio=4
        java.lang.Object.wait(Object.java:315)
        sun.awt.ScreenUpdater.nextEntry(ScreenUpdater.java:78)
        sun.awt.ScreenUpdater.run(ScreenUpdater.java:98)
    "AWT-Windows" (TID:0xf54b70, sys_thread_t:0x875a80, Win32ID:0x67, state:MW) prio=5
        java.awt.Choice.select(Choice.java:293)
        sun.awt.windows.WChoicePeer.handleAction(WChoicePeer.java:86)
        sun.awt.windows.WToolkit.run(WToolkit.java:106)
        java.lang.Thread.run(Thread.java:474)
    "AWT-EventQueue-0" (TID:0xf54a98, sys_thread_t:0x875c20, Win32ID:0x8f, state:R) prio=5
        java.awt.Choice.remove(Choice.java:228)
        java.awt.Choice.removeAll(Choice.java:246)
        ChoiceTest.buildMenu(ChoiceTest.java:43)
        ChoiceTest.itemStateChanged(ChoiceTest.java:58)
        java.awt.Choice.processItemEvent(Choice.java:402)
        java.awt.Choice.processEvent(Choice.java:374)
        java.awt.Component.dispatchEventImpl(Component.java:1764)
        java.awt.Component.dispatchEvent(Component.java:1704)
        java.awt.EventDispatchThread.run(EventDispatchThread.java:63)
    "Finalizer thread" (TID:0xf500d0, sys_thread_t:0x864620, Win32ID:0x81, state:CW) prio=2
    "main" (TID:0xf500a8, sys_thread_t:0x86d720, Win32ID:0x2c, state:CW) prio=5
        sun.awt.windows.WDialogPeer.show(WDialogPeer.java:55)
        java.awt.Dialog.show(Dialog.java:220)
        ChoiceTest.main(ChoiceTest.java:16)
Monitor Cache Dump:
      xxxxx@xxxxx  /FA8480: owner "AWT-EventQueue-0" (0x875c20, 2 entries)
      xxxxx@xxxxx  /FA9830: <unowned>
        Waiters: 1
      xxxxx@xxxxx  /FA9348: <unowned>
        Waiters: 1
Registered Monitor Dump:
    Thread queue lock: <unowned>
    Name and type hash table lock: <unowned>
    String intern lock: <unowned>
    JNI pinning lock: <unowned>
    JNI global reference lock: <unowned>
    BinClass lock: <unowned>
    Class loading lock: <unowned>
    Java stack lock: <unowned>
    Code rewrite lock: <unowned>
    Heap lock: <unowned>
    Has finalization queue lock: <unowned>
    Finalize me queue lock: <unowned>
        Waiters: 1
    Monitor cache expansion lock: <unowned>
    Monitor registry: <unowned>
(Review ID: 21776)
======================================================================
Work Around




Peer could call select() before adding
ItemEvent to event queue.
======================================================================
Evaluation
Occurs on 1.2beta4.  This happens because the Choise Box is responding to SELCHANGE message where as we should be responding to the CBN_SELENDOK message.  

MsgRouting AwtChoice::WmNotify(UINT notifyCode)
{
    if (notifyCode == CBN_SELCHANGE) {
        DoCallback("handleAction", "(I)V", SendMessage(CB_GETCURSEL));
    }
    return mrDoDefault;
}

changes to:-

MsgRouting AwtChoice::WmNotify(UINT notifyCode)
{
    if (notifyCode == CBN_SELENDOK) {
        DoCallback("handleAction", "(I)V", SendMessage(CB_GETCURSEL));
    }
    return mrDoDefault;
}
  xxxxx@xxxxx   1998-06-18

This no longer occurs on 1.2

  xxxxx@xxxxx   1998-08-26


This bug can be reproduced in 1.2beta4 and 1.1.5 and 1.1.6, but it cannot be reproduced using 1.1.7 or 1.2fcs.  


  xxxxx@xxxxx   1998-11-04
  xxxxx@xxxxx   1998-11-04
Comments
  
  Include a link with my name & email   


PLEASE NOTE: JDK6 is formerly known as Project Mustang