src/share/classes/sun/awt/SunToolkit.java

Print this page




 489         PostEventQueue postEventQueue =
 490             (PostEventQueue)appContext.get(POST_EVENT_QUEUE_KEY);
 491         if (postEventQueue != null) {
 492             postEventQueue.postEvent(event);
 493         }
 494     }
 495 
 496     /*
 497      * Post AWTEvent of high priority.
 498      */
 499     public static void postPriorityEvent(final AWTEvent e) {
 500         PeerEvent pe = new PeerEvent(Toolkit.getDefaultToolkit(), new Runnable() {
 501                 public void run() {
 502                     AWTAccessor.getAWTEventAccessor().setPosted(e);
 503                     ((Component)e.getSource()).dispatchEvent(e);
 504                 }
 505             }, PeerEvent.ULTIMATE_PRIORITY_EVENT);
 506         postEvent(targetToAppContext(e.getSource()), pe);
 507     }
 508 
 509     protected static final Lock flushLock = new ReentrantLock();
 510     private static boolean isFlushingPendingEvents = false;
 511 
 512     /*
 513      * Flush any pending events which haven't been posted to the AWT
 514      * EventQueue yet.
 515      */
 516     public static void flushPendingEvents()  {
 517         flushLock.lock();
 518         try {
 519             // Don't call flushPendingEvents() recursively
 520             if (!isFlushingPendingEvents) {
 521                 isFlushingPendingEvents = true;
 522                 AppContext appContext = AppContext.getAppContext();
 523                 PostEventQueue postEventQueue =
 524                     (PostEventQueue)appContext.get(POST_EVENT_QUEUE_KEY);
 525                 if (postEventQueue != null) {
 526                     postEventQueue.flush();
 527                 }
 528             }
 529         } finally {
 530             isFlushingPendingEvents = false;
 531             flushLock.unlock();
 532         }
 533     }
 534 
 535     public static boolean isPostEventQueueEmpty()  {
 536         AppContext appContext = AppContext.getAppContext();




 537         PostEventQueue postEventQueue =
 538             (PostEventQueue)appContext.get(POST_EVENT_QUEUE_KEY);
 539         if (postEventQueue != null) {
 540             return postEventQueue.noEvents();
 541         } else {
 542             return true;
 543         }
 544     }
 545 
 546     /*
 547      * Execute a chunk of code on the Java event handler thread for the
 548      * given target.  Does not wait for the execution to occur before
 549      * returning to the caller.
 550      */
 551     public static void executeOnEventHandlerThread(Object target,
 552                                                    Runnable runnable) {
 553         executeOnEventHandlerThread(new PeerEvent(target, runnable, PeerEvent.PRIORITY_EVENT));
 554     }
 555 
 556     /*
 557      * Fixed 5064013: the InvocationEvent time should be equals
 558      * the time of the ActionEvent
 559      */
 560     @SuppressWarnings("serial")
 561     public static void executeOnEventHandlerThread(Object target,
 562                                                    Runnable runnable,


2028         return AWTAccessor.getAWTEventAccessor().isSystemGenerated(e);
2029     }
2030 
2031 } // class SunToolkit
2032 
2033 
2034 /*
2035  * PostEventQueue is a Thread that runs in the same AppContext as the
2036  * Java EventQueue.  It is a queue of AWTEvents to be posted to the
2037  * Java EventQueue.  The toolkit Thread (AWT-Windows/AWT-Motif) posts
2038  * events to this queue, which then calls EventQueue.postEvent().
2039  *
2040  * We do this because EventQueue.postEvent() may be overridden by client
2041  * code, and we mustn't ever call client code from the toolkit thread.
2042  */
2043 class PostEventQueue {
2044     private EventQueueItem queueHead = null;
2045     private EventQueueItem queueTail = null;
2046     private final EventQueue eventQueue;
2047 
2048     // For the case when queue is cleared but events are not posted
2049     private volatile boolean isFlushing = false;
2050 
2051     PostEventQueue(EventQueue eq) {
2052         eventQueue = eq;
2053     }
2054 
2055     public synchronized boolean noEvents() {
2056         return queueHead == null && !isFlushing;
2057     }
2058 
2059     /*
2060      * Continually post pending AWTEvents to the Java EventQueue. The method
2061      * is synchronized to ensure the flush is completed before a new event
2062      * can be posted to this queue.
2063      *
2064      * 7177040: The method couldn't be wholly synchronized because of calls
2065      * of EventQueue.postEvent() that uses pushPopLock, otherwise it could
2066      * potentially lead to deadlock
2067      */
2068     public void flush() {




2069         EventQueueItem tempQueue;
2070         synchronized (this) {

















2071             tempQueue = queueHead;
2072             queueHead = queueTail = null;
2073             isFlushing = true;
2074         }
2075         try {
2076             while (tempQueue != null) {
2077                 eventQueue.postEvent(tempQueue.event);
2078                 tempQueue = tempQueue.next;
2079             }
2080         }




2081         finally {
2082             isFlushing = false;






2083         }
2084     }
2085 
2086     /*
2087      * Enqueue an AWTEvent to be posted to the Java EventQueue.
2088      */
2089     void postEvent(AWTEvent event) {
2090         EventQueueItem item = new EventQueueItem(event);
2091 
2092         synchronized (this) {
2093             if (queueHead == null) {
2094                 queueHead = queueTail = item;
2095             } else {
2096                 queueTail.next = item;
2097                 queueTail = item;
2098             }
2099         }
2100         SunToolkit.wakeupEventQueue(eventQueue, event.getSource() == AWTAutoShutdown.getInstance());
2101     }
2102 } // class PostEventQueue


 489         PostEventQueue postEventQueue =
 490             (PostEventQueue)appContext.get(POST_EVENT_QUEUE_KEY);
 491         if (postEventQueue != null) {
 492             postEventQueue.postEvent(event);
 493         }
 494     }
 495 
 496     /*
 497      * Post AWTEvent of high priority.
 498      */
 499     public static void postPriorityEvent(final AWTEvent e) {
 500         PeerEvent pe = new PeerEvent(Toolkit.getDefaultToolkit(), new Runnable() {
 501                 public void run() {
 502                     AWTAccessor.getAWTEventAccessor().setPosted(e);
 503                     ((Component)e.getSource()).dispatchEvent(e);
 504                 }
 505             }, PeerEvent.ULTIMATE_PRIORITY_EVENT);
 506         postEvent(targetToAppContext(e.getSource()), pe);
 507     }
 508 



 509     /*
 510      * Flush any pending events which haven't been posted to the AWT
 511      * EventQueue yet.
 512      */
 513     public static void flushPendingEvents()  {





 514         AppContext appContext = AppContext.getAppContext();
 515         flushPendingEvents(appContext);









 516     }
 517 
 518     /*
 519      * Flush the PostEventQueue for the right AppContext.
 520      * The default flushPendingEvents only flushes the thread-local context,
 521      * which is not always correct, c.f. 3746956
 522      */
 523     public static void flushPendingEvents(AppContext appContext) {
 524         PostEventQueue postEventQueue =
 525                 (PostEventQueue)appContext.get(POST_EVENT_QUEUE_KEY);
 526         if (postEventQueue != null) {
 527             postEventQueue.flush();


 528         }
 529     }
 530 
 531     /*
 532      * Execute a chunk of code on the Java event handler thread for the
 533      * given target.  Does not wait for the execution to occur before
 534      * returning to the caller.
 535      */
 536     public static void executeOnEventHandlerThread(Object target,
 537                                                    Runnable runnable) {
 538         executeOnEventHandlerThread(new PeerEvent(target, runnable, PeerEvent.PRIORITY_EVENT));
 539     }
 540 
 541     /*
 542      * Fixed 5064013: the InvocationEvent time should be equals
 543      * the time of the ActionEvent
 544      */
 545     @SuppressWarnings("serial")
 546     public static void executeOnEventHandlerThread(Object target,
 547                                                    Runnable runnable,


2013         return AWTAccessor.getAWTEventAccessor().isSystemGenerated(e);
2014     }
2015 
2016 } // class SunToolkit
2017 
2018 
2019 /*
2020  * PostEventQueue is a Thread that runs in the same AppContext as the
2021  * Java EventQueue.  It is a queue of AWTEvents to be posted to the
2022  * Java EventQueue.  The toolkit Thread (AWT-Windows/AWT-Motif) posts
2023  * events to this queue, which then calls EventQueue.postEvent().
2024  *
2025  * We do this because EventQueue.postEvent() may be overridden by client
2026  * code, and we mustn't ever call client code from the toolkit thread.
2027  */
2028 class PostEventQueue {
2029     private EventQueueItem queueHead = null;
2030     private EventQueueItem queueTail = null;
2031     private final EventQueue eventQueue;
2032 
2033     private Thread flushThread = null;

2034 
2035     PostEventQueue(EventQueue eq) {
2036         eventQueue = eq;
2037     }
2038 




2039     /*
2040      * Continually post pending AWTEvents to the Java EventQueue. The method
2041      * is synchronized to ensure the flush is completed before a new event
2042      * can be posted to this queue.
2043      *
2044      * 7177040: The method couldn't be wholly synchronized because of calls
2045      * of EventQueue.postEvent() that uses pushPopLock, otherwise it could
2046      * potentially lead to deadlock
2047      */
2048     public void flush() {
2049 
2050         Thread newThread = Thread.currentThread();
2051 
2052         try {
2053             EventQueueItem tempQueue;
2054             synchronized (this) {
2055                 // Avoid method recursion
2056                 if (newThread == flushThread) {
2057                     newThread = null;
2058                     return;
2059                 }
2060                 // Wait for other threads' flushing
2061                 while (flushThread != null) {
2062                     wait();
2063                 }
2064                 // Skip everything if queue is empty
2065                 if (queueHead == null) {
2066                     notifyAll();
2067                     return;
2068                 }
2069                 // Remember flushing thread
2070                 flushThread = newThread;
2071 
2072                 tempQueue = queueHead;
2073                 queueHead = queueTail = null;

2074             }

2075             while (tempQueue != null) {
2076                 eventQueue.postEvent(tempQueue.event);
2077                 tempQueue = tempQueue.next;
2078             }
2079         }
2080         catch (InterruptedException e) {
2081             // Couldn't allow exception go up, so at least recover the flag
2082             newThread.interrupt();
2083         }
2084         finally {
2085             synchronized (this) {
2086                 // Forget flushing thread, inform other pending threads
2087                 if (newThread == flushThread) {
2088                     flushThread = null;
2089                     notifyAll();
2090                 }
2091             }
2092         }
2093     }
2094 
2095     /*
2096      * Enqueue an AWTEvent to be posted to the Java EventQueue.
2097      */
2098     void postEvent(AWTEvent event) {
2099         EventQueueItem item = new EventQueueItem(event);
2100 
2101         synchronized (this) {
2102             if (queueHead == null) {
2103                 queueHead = queueTail = item;
2104             } else {
2105                 queueTail.next = item;
2106                 queueTail = item;
2107             }
2108         }
2109         SunToolkit.wakeupEventQueue(eventQueue, event.getSource() == AWTAutoShutdown.getInstance());
2110     }
2111 } // class PostEventQueue