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