The Version table provides details related to the release that this issue/RFE will be addressed.
Unresolved : Release in which this issue/RFE will be addressed. Resolved: Release in which this issue/RFE has been resolved. Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.
Seems that it is an AWT bug in src\share\classes\java\awt\EventQueue.java (invokeAndWait). The fragment with the bug is:
synchronized (lock) {
Toolkit.getEventQueue().postEvent(event);
lock.wait();
}
Comments
EVALUATION
Introduced new isDispatched() method that can be used by a waiting thread (that calls notifier.wait() method) to prevent spurious wakeups and other potential problems.
EVALUATION
The 'real wait termination' above may be not as easy to impmlement. Indeed, it would require some new public methods in InvocationEvent class, or AWTAccessor approach (which is not very elegant) should be used.
Another option may be to avoid InvocationEvent's notifier machinery and perform a manual synchronization in EventQueue.invokeAndWait() like this:
diff -r 06f35d090a5e src/share/classes/java/awt/EventQueue.java
--- a/src/share/classes/java/awt/EventQueue.java Fri Jun 19 16:49:50 2009 -0400
+++ b/src/share/classes/java/awt/EventQueue.java Mon Jun 22 10:49:43 2009 +0400
@@ -1004,16 +1004,30 @@
throw new Error("Cannot call invokeAndWait from the event dispatcher thread");
}
- class AWTInvocationLock {}
- Object lock = new AWTInvocationLock();
+ class AWTInvocationRunnable implements Runnable {
+ private Runnable pipe = null;
+ private boolean dispatched = false;
+ public AWTInvocationRunnable(Runnable run) {
+ pipe = run;
+ }
+ public void run() {
+ pipe.run();
+ synchronized (this) {
+ dispatched = true;
+ notifyAll();
+ }
+ }
+ public synchronized boolean isDispatched() {
+ return dispatched;
+ }
+ }
+ AWTInvocationRunnable toRun = new AWTInvocationRunnable(runnable);
InvocationEvent event =
- new InvocationEvent(Toolkit.getDefaultToolkit(), runnable, lock,
- true);
+ new InvocationEvent(Toolkit.getDefaultToolkit(), toRun, null, true);
- synchronized (lock) {
- Toolkit.getEventQueue().postEvent(event);
- lock.wait();
+ Toolkit.getEventQueue().postEvent(event);
+ synchronized (toRun) {
+ while (!toRun.isDispatched()) {
+ toRun.wait();
+ }
}
Throwable eventThrowable = event.getThrowable();
22-06-2009
EVALUATION
The fragment
synchronized (lock) {
Toolkit.getEventQueue().postEvent(event);
lock.wait();
}
have to be changed to something like
synchronized (lock) {
Toolkit.getEventQueue().postEvent(event);
while( !<real wait termination> ){
try {
lock.wait();
} catch (InterruptedException e) {
break;
}
}
}
with correspondent changes in the InvocationEvent class.