527 PostEventQueue postEventQueue = 528 (PostEventQueue)appContext.get(POST_EVENT_QUEUE_KEY); 529 if (postEventQueue != null) { 530 postEventQueue.postEvent(event); 531 } 532 } 533 534 /* 535 * Post AWTEvent of high priority. 536 */ 537 public static void postPriorityEvent(final AWTEvent e) { 538 PeerEvent pe = new PeerEvent(Toolkit.getDefaultToolkit(), new Runnable() { 539 public void run() { 540 AWTAccessor.getAWTEventAccessor().setPosted(e); 541 ((Component)e.getSource()).dispatchEvent(e); 542 } 543 }, PeerEvent.ULTIMATE_PRIORITY_EVENT); 544 postEvent(targetToAppContext(e.getSource()), pe); 545 } 546 547 protected static final Lock flushLock = new ReentrantLock(); 548 private static boolean isFlushingPendingEvents = false; 549 550 /* 551 * Flush any pending events which haven't been posted to the AWT 552 * EventQueue yet. 553 */ 554 public static void flushPendingEvents() { 555 flushLock.lock(); 556 try { 557 // Don't call flushPendingEvents() recursively 558 if (!isFlushingPendingEvents) { 559 isFlushingPendingEvents = true; 560 AppContext appContext = AppContext.getAppContext(); 561 PostEventQueue postEventQueue = 562 (PostEventQueue)appContext.get(POST_EVENT_QUEUE_KEY); 563 if (postEventQueue != null) { 564 postEventQueue.flush(); 565 } 566 } 567 } finally { 568 isFlushingPendingEvents = false; 569 flushLock.unlock(); 570 } 571 } 572 573 public static boolean isPostEventQueueEmpty() { 574 AppContext appContext = AppContext.getAppContext(); 575 PostEventQueue postEventQueue = 576 (PostEventQueue)appContext.get(POST_EVENT_QUEUE_KEY); 577 if (postEventQueue != null) { 578 return postEventQueue.noEvents(); 579 } else { 580 return true; 581 } 582 } 583 584 /* 585 * Execute a chunk of code on the Java event handler thread for the 586 * given target. Does not wait for the execution to occur before 587 * returning to the caller. 588 */ 589 public static void executeOnEventHandlerThread(Object target, 590 Runnable runnable) { 591 executeOnEventHandlerThread(new PeerEvent(target, runnable, PeerEvent.PRIORITY_EVENT)); 592 } 593 594 /* 595 * Fixed 5064013: the InvocationEvent time should be equals 596 * the time of the ActionEvent 597 */ 598 @SuppressWarnings("serial") 599 public static void executeOnEventHandlerThread(Object target, 600 Runnable runnable, 2095 return AWTAccessor.getAWTEventAccessor().isSystemGenerated(e); 2096 } 2097 2098 } // class SunToolkit 2099 2100 2101 /* 2102 * PostEventQueue is a Thread that runs in the same AppContext as the 2103 * Java EventQueue. It is a queue of AWTEvents to be posted to the 2104 * Java EventQueue. The toolkit Thread (AWT-Windows/AWT-Motif) posts 2105 * events to this queue, which then calls EventQueue.postEvent(). 2106 * 2107 * We do this because EventQueue.postEvent() may be overridden by client 2108 * code, and we mustn't ever call client code from the toolkit thread. 2109 */ 2110 class PostEventQueue { 2111 private EventQueueItem queueHead = null; 2112 private EventQueueItem queueTail = null; 2113 private final EventQueue eventQueue; 2114 2115 // For the case when queue is cleared but events are not posted 2116 private volatile boolean isFlushing = false; 2117 2118 PostEventQueue(EventQueue eq) { 2119 eventQueue = eq; 2120 } 2121 2122 public synchronized boolean noEvents() { 2123 return queueHead == null && !isFlushing; 2124 } 2125 2126 /* 2127 * Continually post pending AWTEvents to the Java EventQueue. The method 2128 * is synchronized to ensure the flush is completed before a new event 2129 * can be posted to this queue. 2130 * 2131 * 7177040: The method couldn't be wholly synchronized because of calls 2132 * of EventQueue.postEvent() that uses pushPopLock, otherwise it could 2133 * potentially lead to deadlock 2134 */ 2135 public void flush() { 2136 EventQueueItem tempQueue; 2137 synchronized (this) { 2138 tempQueue = queueHead; 2139 queueHead = queueTail = null; 2140 isFlushing = true; 2141 } 2142 try { 2143 while (tempQueue != null) { 2144 eventQueue.postEvent(tempQueue.event); 2145 tempQueue = tempQueue.next; 2146 } 2147 } 2148 finally { 2149 isFlushing = false; 2150 } 2151 } 2152 2153 /* 2154 * Enqueue an AWTEvent to be posted to the Java EventQueue. 2155 */ 2156 void postEvent(AWTEvent event) { 2157 EventQueueItem item = new EventQueueItem(event); 2158 2159 synchronized (this) { 2160 if (queueHead == null) { 2161 queueHead = queueTail = item; 2162 } else { 2163 queueTail.next = item; 2164 queueTail = item; 2165 } 2166 } 2167 SunToolkit.wakeupEventQueue(eventQueue, event.getSource() == AWTAutoShutdown.getInstance()); 2168 } 2169 } // class PostEventQueue | 527 PostEventQueue postEventQueue = 528 (PostEventQueue)appContext.get(POST_EVENT_QUEUE_KEY); 529 if (postEventQueue != null) { 530 postEventQueue.postEvent(event); 531 } 532 } 533 534 /* 535 * Post AWTEvent of high priority. 536 */ 537 public static void postPriorityEvent(final AWTEvent e) { 538 PeerEvent pe = new PeerEvent(Toolkit.getDefaultToolkit(), new Runnable() { 539 public void run() { 540 AWTAccessor.getAWTEventAccessor().setPosted(e); 541 ((Component)e.getSource()).dispatchEvent(e); 542 } 543 }, PeerEvent.ULTIMATE_PRIORITY_EVENT); 544 postEvent(targetToAppContext(e.getSource()), pe); 545 } 546 547 /* 548 * Flush any pending events which haven't been posted to the AWT 549 * EventQueue yet. 550 */ 551 public static void flushPendingEvents() { 552 AppContext appContext = AppContext.getAppContext(); 553 flushPendingEvents(appContext); 554 } 555 556 /* 557 * Flush the PostEventQueue for the right AppContext. 558 * The default flushPendingEvents only flushes the thread-local context, 559 * which is not always correct, c.f. 3746956 560 */ 561 public static void flushPendingEvents(AppContext appContext) { 562 PostEventQueue postEventQueue = 563 (PostEventQueue)appContext.get(POST_EVENT_QUEUE_KEY); 564 if (postEventQueue != null) { 565 postEventQueue.flush(); 566 } 567 } 568 569 /* 570 * Execute a chunk of code on the Java event handler thread for the 571 * given target. Does not wait for the execution to occur before 572 * returning to the caller. 573 */ 574 public static void executeOnEventHandlerThread(Object target, 575 Runnable runnable) { 576 executeOnEventHandlerThread(new PeerEvent(target, runnable, PeerEvent.PRIORITY_EVENT)); 577 } 578 579 /* 580 * Fixed 5064013: the InvocationEvent time should be equals 581 * the time of the ActionEvent 582 */ 583 @SuppressWarnings("serial") 584 public static void executeOnEventHandlerThread(Object target, 585 Runnable runnable, 2080 return AWTAccessor.getAWTEventAccessor().isSystemGenerated(e); 2081 } 2082 2083 } // class SunToolkit 2084 2085 2086 /* 2087 * PostEventQueue is a Thread that runs in the same AppContext as the 2088 * Java EventQueue. It is a queue of AWTEvents to be posted to the 2089 * Java EventQueue. The toolkit Thread (AWT-Windows/AWT-Motif) posts 2090 * events to this queue, which then calls EventQueue.postEvent(). 2091 * 2092 * We do this because EventQueue.postEvent() may be overridden by client 2093 * code, and we mustn't ever call client code from the toolkit thread. 2094 */ 2095 class PostEventQueue { 2096 private EventQueueItem queueHead = null; 2097 private EventQueueItem queueTail = null; 2098 private final EventQueue eventQueue; 2099 2100 // For synchronization of flush() method call 2101 private boolean isFlushing = false; 2102 2103 // For elimination of recursion of flush() method call 2104 private final ThreadLocal<Boolean> isThreadLocalFlushing = new ThreadLocal<>(); 2105 2106 PostEventQueue(EventQueue eq) { 2107 eventQueue = eq; 2108 } 2109 2110 /* 2111 * Continually post pending AWTEvents to the Java EventQueue. The method 2112 * is synchronized to ensure the flush is completed before a new event 2113 * can be posted to this queue. 2114 * 2115 * 7177040: The method couldn't be wholly synchronized because of calls 2116 * of EventQueue.postEvent() that uses pushPopLock, otherwise it could 2117 * potentially lead to deadlock 2118 */ 2119 public void flush() { 2120 Boolean b = isThreadLocalFlushing.get(); 2121 if (b != null && b) { 2122 return; 2123 } 2124 2125 isThreadLocalFlushing.set(true); 2126 try { 2127 EventQueueItem tempQueue; 2128 synchronized (this) { 2129 while (isFlushing) { 2130 wait(); 2131 } 2132 isFlushing = (queueHead != null); 2133 2134 tempQueue = queueHead; 2135 queueHead = queueTail = null; 2136 } 2137 while (tempQueue != null) { 2138 eventQueue.postEvent(tempQueue.event); 2139 tempQueue = tempQueue.next; 2140 } 2141 } 2142 catch (InterruptedException e) { 2143 } 2144 finally { 2145 synchronized (this) { 2146 isFlushing = false; 2147 notifyAll(); 2148 } 2149 } 2150 isThreadLocalFlushing.set(false); 2151 } 2152 2153 /* 2154 * Enqueue an AWTEvent to be posted to the Java EventQueue. 2155 */ 2156 void postEvent(AWTEvent event) { 2157 EventQueueItem item = new EventQueueItem(event); 2158 2159 synchronized (this) { 2160 if (queueHead == null) { 2161 queueHead = queueTail = item; 2162 } else { 2163 queueTail.next = item; 2164 queueTail = item; 2165 } 2166 } 2167 SunToolkit.wakeupEventQueue(eventQueue, event.getSource() == AWTAutoShutdown.getInstance()); 2168 } 2169 } // class PostEventQueue |