<AWT Dev> [7u8] Review request for 7177040: Deadlock between PostEventQueue.noEvents, EventQueue.isDispatchThread and SwingUtilities.invokeLater
Peter Levart
peter.levart at gmail.com
Tue Jul 24 07:53:55 PDT 2012
Hi Oleg,
Here's even better flush() method. It completes the flush even if
interrupted while waiting and then sets the interrupted status just before
exit...
public void flush() {
boolean interrupted = false;
try {
EventQueueItem tempQueue;
synchronized (this) {
while (flushingThread != null && flushingThread !=
Thread.currentThread()) {
try {
wait();
}
catch (InterruptedException e) {
interrupted = true;
}
}
// prevent recursion
if (flushingThread == Thread.currentThread()) return;
tempQueue = queueHead;
queueHead = queueTail = null;
// queue was empty
if (tempQueue == null) return;
flushingThread = Thread.currentThread();
notify();
}
try {
while (tempQueue != null) {
eventQueue.postEvent(tempQueue.event);
tempQueue = tempQueue.next;
}
}
finally {
synchronized (this) {
flushingThread = null;
notify();
}
}
}
finally
{
if (interrupted) Thread.currentThread().interrupt();
}
}
Regards, Peter
2012/7/24 Peter Levart <peter.levart at gmail.com>
> Ok, now to get rid of flushLock in SunToolkit so that flushPendingEvents
> is written as plain:
>
> public static void flushPendingEvents() {
> AppContext appContext = AppContext.getAppContext();
> PostEventQueue postEventQueue =
> (PostEventQueue)appContext.get(POST_EVENT_QUEUE_KEY);
> if (postEventQueue != null) {
> postEventQueue.flush();
> }
> }
>
> ... you could merge the recursion prevention functionality into the
> PostEventQueue in a manner similar to this:
>
> class PostEventQueue {
> private EventQueueItem queueHead = null;
> private EventQueueItem queueTail = null;
> private final EventQueue eventQueue;
>
> // For the recursion prevention and noEvents() status
> private Thread flushingThread = null;
>
> PostEventQueue(EventQueue eq) {
> eventQueue = eq;
> }
>
> public synchronized boolean noEvents() {
> return queueHead == null && flushingThread == null;
> }
>
> public void flush() {
> EventQueueItem tempQueue;
> synchronized (this) {
> while (flushingThread != null && flushingThread !=
> Thread.currentThread()) try {
> wait();
> }
> catch (InterruptedException e) { // what can we do?
> Thread.currentThread().interrupt();
> return;
> }
>
> // prevent recursion
> if (flushingThread == Thread.currentThread()) return;
>
> tempQueue = queueHead;
> queueHead = queueTail = null;
>
> // queue was empty
> if (tempQueue == null) return;
>
> flushingThread = Thread.currentThread();
> notify();
> }
> try {
> while (tempQueue != null) {
> eventQueue.postEvent(tempQueue.event);
> tempQueue = tempQueue.next;
> }
> }
> finally {
> synchronized (this) {
> flushingThread = null;
> notify();
> }
> }
> }
>
> /*
> * Enqueue an AWTEvent to be posted to the Java EventQueue.
> */
> void postEvent(AWTEvent event) {
> EventQueueItem item = new EventQueueItem(event);
>
> synchronized (this) {
> if (queueHead == null) {
> queueHead = queueTail = item;
> } else {
> queueTail.next = item;
> queueTail = item;
> }
> }
> SunToolkit.wakeupEventQueue(eventQueue, event.getSource() ==
> AWTAutoShutdown.getInstance());
> }
> } // class PostEventQueue
>
>
> What do you think?
>
> Regards, Peter
>
>
> 2012/7/24 Oleg Pekhovskiy <oleg.pekhovskiy at oracle.com>
>
>> Hi Peter,
>>
>> so obvious, thank you!
>>
>> Oleg.
>>
>>
>> 7/24/2012 3:42 PM, Peter Levart wrote:
>>
>>> Hi Oleg,
>>>
>>> This is just cosmetics, but:
>>>
>>> SunToolkit:
>>> public synchronized boolean noEvents() {
>>> return queueHead == null && !isFlushing;
>>> }
>>>
>>> ... a thread calling noEvents could see occasional "spikes" of false
>>> return even though there is no flushing being performed (when other thread
>>> is calling flush on an empty PostEventQueue).
>>>
>>> Improved flush method would look like this:
>>>
>>> public void flush() {
>>> EventQueueItem tempQueue;
>>> synchronized (this) {
>>> tempQueue = queueHead;
>>> queueHead = queueTail = null;
>>> isFlushing =*/(tempQueue != null)/*;
>>>
>>> }
>>> try {
>>> while (tempQueue != null) {
>>> eventQueue.postEvent(**tempQueue.event);
>>> tempQueue = tempQueue.next;
>>> }
>>> }
>>> finally {
>>> isFlushing = false;
>>> }
>>> }
>>>
>>> Regards, Peter
>>>
>>> 2012/7/23 Oleg Pekhovskiy <oleg.pekhovskiy at oracle.com <mailto:
>>> oleg.pekhovskiy@**oracle.com <oleg.pekhovskiy at oracle.com>>>
>>>
>>>
>>> Hi!
>>>
>>> Please review this back-port being already pushed to jdk8 but
>>> deferred for 7u6.
>>>
>>> Bug:
>>> http://bugs.sun.com/view_bug.**do?bug_id=7177040<http://bugs.sun.com/view_bug.do?bug_id=7177040>
>>>
>>> Webrev:
>>> http://cr.openjdk.java.net/~**bagiras/7u8/7177040.1<http://cr.openjdk.java.net/~bagiras/7u8/7177040.1>
>>> <http://cr.openjdk.java.net/%**7Ebagiras/7u8/7177040.1<http://cr.openjdk.java.net/%7Ebagiras/7u8/7177040.1>
>>> >
>>>
>>>
>>> Review thread for 7u6:
>>> http://mail.openjdk.java.net/**pipermail/awt-dev/2012-July/**
>>> 003106.html<http://mail.openjdk.java.net/pipermail/awt-dev/2012-July/003106.html>
>>>
>>> Reviewers 7u6 & 8:
>>> Anthony Petrov, Anton Tarasov
>>>
>>> Thanks,
>>> Oleg
>>>
>>>
>>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://mail.openjdk.java.net/pipermail/awt-dev/attachments/20120724/3680914e/attachment.html
More information about the awt-dev
mailing list