during investigation of 6542185 I've found one more problem with pop().
It looks like if someone will post new event when popo() is waiting while dispatching of current event will be completed by previous EDT, this may create EDT for event queue which will be active after pop() and so current EDT becomes non-EDT in the middle of event dispatching :(
Here is a simple test to reproduce the problem:
import java.awt.EventQueue;
import java.awt.Toolkit;
import java.util.concurrent.atomic.AtomicBoolean;
public class simple_test {
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
System.out.println("current thread = " +
Thread.currentThread());
MyEventQueue eq = new MyEventQueue();
Toolkit.getDefaultToolkit().getSystemEventQueue().push(eq);
final AtomicBoolean monitor = new AtomicBoolean(false);
final AtomicBoolean monitor1 = new AtomicBoolean(false);
synchronized (monitor) {
EventQueue.invokeLater(new Runnable() {
public void run() {
synchronized (monitor) {
monitor.set(true);
monitor.notify();
}
synchronized (monitor1) {
try {
while (!monitor1.get()) {
System.out.println("waiting
pop() " + monitor1.get());
monitor1.wait(1000);
}
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
System.out.println("After pop(): thread =
" + Thread.currentThread() + " isEDT = " +
EventQueue.isDispatchThread());
if (!EventQueue.isDispatchThread()) {
throw new
IllegalThreadStateException("current thread is not a EDT");
}
}
});
try {
while (!monitor.get()) {
System.out.println("waiting invocation " +
monitor.get());
monitor.wait(100);
}
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
new Thread(new Runnable() {
public void run() {
for (int i = 0; i < 20; ++i) {
try {
Thread.sleep(50);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
System.out.println("sending event");
EventQueue.invokeLater(new Runnable() {
public void run() {
System.out.println("executing
event on thread = " + Thread.currentThread() + " isEDT = " +
EventQueue.isDispatchThread());
}
});
}
synchronized (monitor1) {
monitor1.set(true);
System.out.println("notifying about pop()
" + monitor1.get());
monitor1.notify();
}
}
}).start();
eq.pop();
}
});
}
private static final class MyEventQueue extends EventQueue {
public MyEventQueue() {
}
public void pop() {
System.out.println("pop()");
super.pop();
}
}
}