< prev index next >

src/java.desktop/share/classes/java/awt/SequencedEvent.java

Print this page
rev 51845 : 8204142: AWT hang occurs when sequenced events arrive out of sequence in multiple AppContexts
Summary: Event Dispatch Threads may be woken up by SentEvent AWT events (when SequencedEvent events are disposed)


  64             public AWTEvent getNested(AWTEvent sequencedEvent) {
  65                 return ((SequencedEvent)sequencedEvent).nested;
  66             }
  67             public boolean isSequencedEvent(AWTEvent event) {
  68                 return event instanceof SequencedEvent;
  69             }
  70 
  71             public AWTEvent create(AWTEvent event) {
  72                 return new SequencedEvent(event);
  73             }
  74         });
  75         AccessController.doPrivileged(new PrivilegedAction<Object>() {
  76             public Object run() {
  77                 fxAppThreadIsDispatchThread =
  78                         "true".equals(System.getProperty("javafx.embed.singleThread"));
  79                 return null;
  80             }
  81         });
  82     }
  83 











  84     /**
  85      * Constructs a new SequencedEvent which will dispatch the specified
  86      * nested event.
  87      *
  88      * @param nested the AWTEvent which this SequencedEvent's dispatch()
  89      *        method will dispatch
  90      */
  91     public SequencedEvent(AWTEvent nested) {
  92         super(nested.getSource(), ID);
  93         this.nested = nested;
  94         // All AWTEvents that are wrapped in SequencedEvents are (at
  95         // least currently) implicitly generated by the system
  96         SunToolkit.setSystemGenerated(nested);
  97 
  98         if (fxAppThreadIsDispatchThread) {
  99             fxCheckSequenceThread = new Thread() {
 100                 @Override
 101                 public void run() {
 102                     while(!isFirstOrDisposed()) {
 103                         try {


 118      * Dispatches the nested event after all previous nested events have been
 119      * dispatched or disposed. If this method is invoked before all previous nested events
 120      * have been dispatched, then this method blocks until such a point is
 121      * reached.
 122      * While waiting disposes nested events to disposed AppContext
 123      *
 124      * NOTE: Locking protocol.  Since dispose() can get EventQueue lock,
 125      * dispatch() shall never call dispose() while holding the lock on the list,
 126      * as EventQueue lock is held during dispatching.  The locks should be acquired
 127      * in the same order.
 128      */
 129     public final void dispatch() {
 130         try {
 131             appContext = AppContext.getAppContext();
 132 
 133             if (getFirst() != this) {
 134                 if (EventQueue.isDispatchThread()) {
 135                     if (Thread.currentThread() instanceof EventDispatchThread) {
 136                         EventDispatchThread edt = (EventDispatchThread)
 137                                 Thread.currentThread();
 138                         edt.pumpEvents(ID, () -> !SequencedEvent.this.isFirstOrDisposed());

 139                     } else {
 140                         if (fxAppThreadIsDispatchThread) {
 141                             fxCheckSequenceThread.start();
 142                             try {
 143                                 // check if event is dispatched or disposed
 144                                 // but since this user app thread is same as
 145                                 // dispatch thread in fx when run with
 146                                 // javafx.embed.singleThread=true
 147                                 // we do not wait infinitely to avoid deadlock
 148                                 // as dispatch will ultimately be done by this thread
 149                                 fxCheckSequenceThread.join(500);
 150                             } catch (InterruptedException e) {
 151                             }
 152                         }
 153                     }
 154                 } else {
 155                     while(!isFirstOrDisposed()) {
 156                         synchronized (SequencedEvent.class) {
 157                             try {
 158                                 SequencedEvent.class.wait(1000);




  64             public AWTEvent getNested(AWTEvent sequencedEvent) {
  65                 return ((SequencedEvent)sequencedEvent).nested;
  66             }
  67             public boolean isSequencedEvent(AWTEvent event) {
  68                 return event instanceof SequencedEvent;
  69             }
  70 
  71             public AWTEvent create(AWTEvent event) {
  72                 return new SequencedEvent(event);
  73             }
  74         });
  75         AccessController.doPrivileged(new PrivilegedAction<Object>() {
  76             public Object run() {
  77                 fxAppThreadIsDispatchThread =
  78                         "true".equals(System.getProperty("javafx.embed.singleThread"));
  79                 return null;
  80             }
  81         });
  82     }
  83 
  84     private static class SequencedEventsFilter implements EventFilter {
  85         @Override
  86         public FilterAction acceptEvent(AWTEvent ev) {
  87             final int eventID = ev.getID();
  88             if (eventID == ID || eventID == SentEvent.ID) {
  89                 return FilterAction.ACCEPT;
  90             }
  91             return FilterAction.REJECT;
  92         }
  93     }
  94 
  95     /**
  96      * Constructs a new SequencedEvent which will dispatch the specified
  97      * nested event.
  98      *
  99      * @param nested the AWTEvent which this SequencedEvent's dispatch()
 100      *        method will dispatch
 101      */
 102     public SequencedEvent(AWTEvent nested) {
 103         super(nested.getSource(), ID);
 104         this.nested = nested;
 105         // All AWTEvents that are wrapped in SequencedEvents are (at
 106         // least currently) implicitly generated by the system
 107         SunToolkit.setSystemGenerated(nested);
 108 
 109         if (fxAppThreadIsDispatchThread) {
 110             fxCheckSequenceThread = new Thread() {
 111                 @Override
 112                 public void run() {
 113                     while(!isFirstOrDisposed()) {
 114                         try {


 129      * Dispatches the nested event after all previous nested events have been
 130      * dispatched or disposed. If this method is invoked before all previous nested events
 131      * have been dispatched, then this method blocks until such a point is
 132      * reached.
 133      * While waiting disposes nested events to disposed AppContext
 134      *
 135      * NOTE: Locking protocol.  Since dispose() can get EventQueue lock,
 136      * dispatch() shall never call dispose() while holding the lock on the list,
 137      * as EventQueue lock is held during dispatching.  The locks should be acquired
 138      * in the same order.
 139      */
 140     public final void dispatch() {
 141         try {
 142             appContext = AppContext.getAppContext();
 143 
 144             if (getFirst() != this) {
 145                 if (EventQueue.isDispatchThread()) {
 146                     if (Thread.currentThread() instanceof EventDispatchThread) {
 147                         EventDispatchThread edt = (EventDispatchThread)
 148                                 Thread.currentThread();
 149                         edt.pumpEventsForFilter(() -> !SequencedEvent.this.isFirstOrDisposed(),
 150                                 new SequencedEventsFilter());
 151                     } else {
 152                         if (fxAppThreadIsDispatchThread) {
 153                             fxCheckSequenceThread.start();
 154                             try {
 155                                 // check if event is dispatched or disposed
 156                                 // but since this user app thread is same as
 157                                 // dispatch thread in fx when run with
 158                                 // javafx.embed.singleThread=true
 159                                 // we do not wait infinitely to avoid deadlock
 160                                 // as dispatch will ultimately be done by this thread
 161                                 fxCheckSequenceThread.join(500);
 162                             } catch (InterruptedException e) {
 163                             }
 164                         }
 165                     }
 166                 } else {
 167                     while(!isFirstOrDisposed()) {
 168                         synchronized (SequencedEvent.class) {
 169                             try {
 170                                 SequencedEvent.class.wait(1000);


< prev index next >