# HG changeset patch # User mbalao # Date 1539350455 -7200 # Fri Oct 12 15:20:55 2018 +0200 # Node ID e6e3bdf4f789b2e287c35fe1ca50473ead713fc6 # Parent 354fb27fd38ac0bcab1363ae5316b533c07214c7 8204142: AWT hang occurs when sequenced events arrive out of sequence in multiple AppContexts Summary: Synchronization of SequencedEvent events from different AppContexts fixed diff --git a/src/java.desktop/share/classes/java/awt/SequencedEvent.java b/src/java.desktop/share/classes/java/awt/SequencedEvent.java --- a/src/java.desktop/share/classes/java/awt/SequencedEvent.java +++ b/src/java.desktop/share/classes/java/awt/SequencedEvent.java @@ -27,6 +27,7 @@ import java.security.AccessController; import java.security.PrivilegedAction; +import java.util.Iterator; import java.util.LinkedList; import sun.awt.AWTAccessor; import sun.awt.AppContext; @@ -56,6 +57,7 @@ private final AWTEvent nested; private AppContext appContext; private boolean disposed; + private final LinkedList pendingEvents = new LinkedList<>(); private static boolean fxAppThreadIsDispatchThread; private Thread fxCheckSequenceThread; @@ -81,6 +83,34 @@ }); } + private static final class SequencedEventsFilter implements EventFilter { + private final SequencedEvent currentSequencedEvent; + private SequencedEventsFilter(SequencedEvent currentSequencedEvent) { + this.currentSequencedEvent = currentSequencedEvent; + } + @Override + public FilterAction acceptEvent(AWTEvent ev) { + if (ev.getID() == ID) { + // Move forward dispatching only if the event is previous + // in SequencedEvent.list. Otherwise, hold it for reposting later. + synchronized (SequencedEvent.class) { + Iterator it = list.iterator(); + while (it.hasNext()) { + SequencedEvent iev = it.next(); + if (iev.equals(currentSequencedEvent)) { + break; + } else if (iev.equals(ev)) { + return FilterAction.ACCEPT; + } + } + } + currentSequencedEvent.pendingEvents.add(ev); + return FilterAction.REJECT; + } + return FilterAction.ACCEPT; + } + } + /** * Constructs a new SequencedEvent which will dispatch the specified * nested event. @@ -135,7 +165,8 @@ if (Thread.currentThread() instanceof EventDispatchThread) { EventDispatchThread edt = (EventDispatchThread) Thread.currentThread(); - edt.pumpEvents(ID, () -> !SequencedEvent.this.isFirstOrDisposed()); + edt.pumpEventsForFilter(() -> !SequencedEvent.this.isFirstOrDisposed(), + new SequencedEventsFilter(this)); } else { if (fxAppThreadIsDispatchThread) { fxCheckSequenceThread.start(); @@ -239,10 +270,6 @@ } disposed = true; } - // Wake myself up - if (appContext != null) { - SunToolkit.postEvent(appContext, new SentEvent()); - } SequencedEvent next = null; @@ -263,5 +290,9 @@ if (next != null && next.appContext != null) { SunToolkit.postEvent(next.appContext, new SentEvent()); } + + for(AWTEvent e : pendingEvents) { + SunToolkit.postEvent(appContext, e); + } } }