Hi Oleg,<div><br></div><div>Here's even better flush() method. It completes the flush even if interrupted while waiting and then sets the interrupted status just before exit...<br><br><div> public void flush() {</div>
<div> boolean interrupted = false;</div><div> try {</div><div> EventQueueItem tempQueue;</div><div><br></div><div> synchronized (this) {</div><div> while (flushingThread != null && flushingThread != Thread.currentThread()) {</div>
<div> try {</div><div> wait();</div><div> }</div><div> catch (InterruptedException e) {</div><div> interrupted = true;</div>
<div> }</div><div> }</div><div><br></div><div> // prevent recursion</div><div> if (flushingThread == Thread.currentThread()) return;</div><div><br></div><div>
tempQueue = queueHead;</div><div> queueHead = queueTail = null;</div><div><br></div><div> // queue was empty</div><div> if (tempQueue == null) return;</div><div>
<br></div><div> flushingThread = Thread.currentThread();</div><div> notify();</div><div> }</div><div> try {</div><div> while (tempQueue != null) {</div><div>
eventQueue.postEvent(tempQueue.event);</div><div> tempQueue = tempQueue.next;</div><div> }</div><div> }</div><div> finally {</div><div> synchronized (this) {</div>
<div> flushingThread = null;</div><div> notify();</div><div> }</div><div> }</div><div> }</div><div> finally</div><div> {</div><div> if (interrupted) Thread.currentThread().interrupt();</div>
<div> }</div><div> }</div><div><br></div><div><br></div><div>Regards, Peter</div><div><br></div><div><br></div><div class="gmail_quote">2012/7/24 Peter Levart <span dir="ltr"><<a href="mailto:peter.levart@gmail.com" target="_blank">peter.levart@gmail.com</a>></span><br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Ok, now to get rid of flushLock in SunToolkit so that flushPendingEvents is written as plain:<div><br></div><div><div> public static void flushPendingEvents() {</div>
<div> AppContext appContext = AppContext.getAppContext();</div>
<div> PostEventQueue postEventQueue =</div><div> (PostEventQueue)appContext.get(POST_EVENT_QUEUE_KEY);</div><div> if (postEventQueue != null) {</div><div> postEventQueue.flush();</div>
<div>
}</div><div> }</div><div><br></div><div>... you could merge the recursion prevention functionality into the PostEventQueue in a manner similar to this:</div><div><br></div><div><div><div>class PostEventQueue {</div>
<div> private EventQueueItem queueHead = null;</div><div> private EventQueueItem queueTail = null;</div><div> private final EventQueue eventQueue;</div><div><br></div><div> // For the recursion prevention and noEvents() status</div>
<div> private Thread flushingThread = null;</div><div><br></div><div> PostEventQueue(EventQueue eq) {</div><div> eventQueue = eq;</div><div> }</div><div><br></div><div> public synchronized boolean noEvents() {</div>
<div> return queueHead == null && flushingThread == null;</div><div class="im"><div> }</div><div><br></div><div> public void flush() {</div><div> EventQueueItem tempQueue;</div><div> synchronized (this) {</div>
</div><div> while (flushingThread != null && flushingThread != Thread.currentThread()) try {</div><div> wait();</div><div> }</div><div> catch (InterruptedException e) { // what can we do?</div>
<div> Thread.currentThread().interrupt();</div><div> return;</div><div> }</div><div><br></div><div> // prevent recursion</div><div> if (flushingThread == Thread.currentThread()) return;</div>
<div class="im">
<div><br></div><div> tempQueue = queueHead;</div><div> queueHead = queueTail = null;</div><div><br></div></div><div> // queue was empty</div><div> if (tempQueue == null) return;</div>
<div><br></div><div> flushingThread = Thread.currentThread();</div><div> notify();</div><div class="im"><div> }</div><div> try {</div><div> while (tempQueue != null) {</div>
<div> eventQueue.postEvent(tempQueue.event);</div>
<div> tempQueue = tempQueue.next;</div><div> }</div><div> }</div><div> finally {</div></div><div> synchronized (this) {</div><div> flushingThread = null;</div>
<div>
notify();</div><div> }</div><div> }</div><div> }</div><div><br></div><div> /*</div><div> * Enqueue an AWTEvent to be posted to the Java EventQueue.</div><div> */</div><div>
void postEvent(AWTEvent event) {</div>
<div> EventQueueItem item = new EventQueueItem(event);</div><div><br></div><div> synchronized (this) {</div><div> if (queueHead == null) {</div><div> queueHead = queueTail = item;</div>
<div> } else {</div><div> queueTail.next = item;</div><div> queueTail = item;</div><div> }</div><div> }</div><div> SunToolkit.wakeupEventQueue(eventQueue, event.getSource() == AWTAutoShutdown.getInstance());</div>
<div> }</div><div>} // class PostEventQueue</div></div></div><div><br></div><div><br></div><div>What do you think?</div><div><br></div><div>Regards, Peter</div><div><div class="h5"><div><br></div><br><div class="gmail_quote">
2012/7/24 Oleg Pekhovskiy <span dir="ltr"><<a href="mailto:oleg.pekhovskiy@oracle.com" target="_blank">oleg.pekhovskiy@oracle.com</a>></span><br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hi Peter,<br>
<br>
so obvious, thank you!<br>
<br>
Oleg.<div><br>
<br>
7/24/2012 3:42 PM, Peter Levart wrote:<br>
</div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div>
Hi Oleg,<br>
<br>
This is just cosmetics, but:<br>
<br>
SunToolkit:<br>
public synchronized boolean noEvents() {<br>
return queueHead == null && !isFlushing;<br>
}<br>
<br>
... 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).<br>
<br>
Improved flush method would look like this:<br>
<br>
public void flush() {<br>
EventQueueItem tempQueue;<br>
synchronized (this) {<br>
tempQueue = queueHead;<br>
queueHead = queueTail = null;<br></div>
isFlushing =*/(tempQueue != null)/*;<div><br>
}<br>
try {<br>
while (tempQueue != null) {<br>
eventQueue.postEvent(<u></u>tempQueue.event);<br>
tempQueue = tempQueue.next;<br>
}<br>
}<br>
finally {<br>
isFlushing = false;<br>
}<br>
}<br>
<br>
Regards, Peter<br>
<br></div>
2012/7/23 Oleg Pekhovskiy <<a href="mailto:oleg.pekhovskiy@oracle.com" target="_blank">oleg.pekhovskiy@oracle.com</a> <mailto:<a href="mailto:oleg.pekhovskiy@oracle.com" target="_blank">oleg.pekhovskiy@<u></u>oracle.com</a>>><div>
<br>
<br>
Hi!<br>
<br>
Please review this back-port being already pushed to jdk8 but<br>
deferred for 7u6.<br>
<br>
Bug:<br>
<a href="http://bugs.sun.com/view_bug.do?bug_id=7177040" target="_blank">http://bugs.sun.com/view_bug.<u></u>do?bug_id=7177040</a><br>
<br>
Webrev:<br>
<a href="http://cr.openjdk.java.net/~bagiras/7u8/7177040.1" target="_blank">http://cr.openjdk.java.net/~<u></u>bagiras/7u8/7177040.1</a><br></div>
<<a href="http://cr.openjdk.java.net/%7Ebagiras/7u8/7177040.1" target="_blank">http://cr.openjdk.java.net/%<u></u>7Ebagiras/7u8/7177040.1</a>><div><br>
<br>
Review thread for 7u6:<br>
<a href="http://mail.openjdk.java.net/pipermail/awt-dev/2012-July/003106.html" target="_blank">http://mail.openjdk.java.net/<u></u>pipermail/awt-dev/2012-July/<u></u>003106.html</a><br>
<br>
Reviewers 7u6 & 8:<br>
Anthony Petrov, Anton Tarasov<br>
<br>
Thanks,<br>
Oleg<br>
<br>
<br>
</div></blockquote>
<br>
</blockquote></div><br></div></div></div>
</blockquote></div><br></div>