public static void replaceIdeEventQueueSafely() { if (Toolkit.getDefaultToolkit().getSystemEventQueue() instanceof IdeEventQueue) { return; } if (SwingUtilities.isEventDispatchThread()) { throw new RuntimeException("must not call under EDT"); } AWTAutoShutdown.getInstance().notifyThreadBusy(Thread.currentThread()); UIUtil.pump(); // in JDK 1.6 java.awt.EventQueue.push() causes slow painful death of current EDT // so we have to wait through its agony to termination try { SwingUtilities.invokeAndWait(new Runnable() { @Override public void run() { IdeEventQueue.getInstance(); } }); SwingUtilities.invokeAndWait(EmptyRunnable.getInstance()); SwingUtilities.invokeAndWait(EmptyRunnable.getInstance()); } catch (Exception e) { throw new RuntimeException(e); } }
/** * Posts a 1.1-style event to the <code>EventQueue</code>. * If there is an existing event on the queue with the same ID * and event source, the source <code>Component</code>'s * <code>coalesceEvents</code> method will be called. * * @param theEvent an instance of <code>java.awt.AWTEvent</code>, * or a subclass of it */ final void postEventPrivate(AWTEvent theEvent) { theEvent.isPosted = true; synchronized(this) { if (dispatchThread == null && nextQueue == null) { if (theEvent.getSource() == AWTAutoShutdown.getInstance()) { return; } else { initDispatchThread(); } } if (nextQueue != null) { // Forward event to top of EventQueue stack. nextQueue.postEventPrivate(theEvent); return; } postEvent(theEvent, getPriority(theEvent)); } }
/** * Removes an event from the <code>EventQueue</code> and * returns it. This method will block until an event has * been posted by another thread. * @return the next <code>AWTEvent</code> * @exception InterruptedException * if any thread has interrupted this thread */ public AWTEvent getNextEvent() throws InterruptedException { do { /* * SunToolkit.flushPendingEvents must be called outside * of the synchronized block to avoid deadlock when * event queues are nested with push()/pop(). */ SunToolkit.flushPendingEvents(); synchronized (this) { for (int i = NUM_PRIORITIES - 1; i >= 0; i--) { if (queues[i].head != null) { EventQueueItem entry = queues[i].head; queues[i].head = entry.next; if (entry.next == null) { queues[i].tail = null; } uncacheEQItem(entry); return entry.event; } } AWTAutoShutdown.getInstance().notifyThreadFree(dispatchThread); wait(); } } while(true); }
final void initDispatchThread() { synchronized (this) { if (dispatchThread == null && !threadGroup.isDestroyed()) { dispatchThread = (EventDispatchThread) AccessController.doPrivileged(new PrivilegedAction() { public Object run() { EventDispatchThread t = new EventDispatchThread(threadGroup, name, EventQueue.this); t.setContextClassLoader(classLoader); t.setPriority(Thread.NORM_PRIORITY + 1); t.setDaemon(false); return t; } }); AWTAutoShutdown.getInstance().notifyThreadBusy(dispatchThread); dispatchThread.start(); } } }
/** * Posts a 1.1-style event to the <code>EventQueue</code>. * If there is an existing event on the queue with the same ID * and event source, the source <code>Component</code>'s * <code>coalesceEvents</code> method will be called. * * @param theEvent an instance of <code>java.awt.AWTEvent</code>, * or a subclass of it */ private final void postEventPrivate(AWTEvent theEvent) { theEvent.isPosted = true; pushPopLock.lock(); try { if (nextQueue != null) { // Forward the event to the top of EventQueue stack nextQueue.postEventPrivate(theEvent); return; } if (dispatchThread == null) { if (theEvent.getSource() == AWTAutoShutdown.getInstance()) { return; } else { initDispatchThread(); } } postEvent(theEvent, getPriority(theEvent)); } finally { pushPopLock.unlock(); } }
/** * Removes an event from the <code>EventQueue</code> and * returns it. This method will block until an event has * been posted by another thread. * @return the next <code>AWTEvent</code> * @exception InterruptedException * if any thread has interrupted this thread */ public AWTEvent getNextEvent() throws InterruptedException { do { /* * SunToolkit.flushPendingEvents must be called outside * of the synchronized block to avoid deadlock when * event queues are nested with push()/pop(). */ SunToolkit.flushPendingEvents(appContext); pushPopLock.lock(); try { AWTEvent event = getNextEventPrivate(); if (event != null) { return event; } AWTAutoShutdown.getInstance().notifyThreadFree(dispatchThread); pushPopCond.await(); } finally { pushPopLock.unlock(); } } while(true); }
/** * Called from dispatchEvent() under a correct AccessControlContext */ private void dispatchEventImpl(final AWTEvent event, final Object src) { event.isPosted = true; if (event instanceof ActiveEvent) { // This could become the sole method of dispatching in time. setCurrentEventAndMostRecentTimeImpl(event); ((ActiveEvent)event).dispatch(); } else if (src instanceof Component) { ((Component)src).dispatchEvent(event); event.dispatched(); } else if (src instanceof MenuComponent) { ((MenuComponent)src).dispatchEvent(event); } else if (src instanceof TrayIcon) { ((TrayIcon)src).dispatchEvent(event); } else if (src instanceof AWTAutoShutdown) { if (noEvents()) { dispatchThread.stopDispatching(); } } else { if (eventLog.isLoggable(PlatformLogger.FINE)) { eventLog.fine("Unable to dispatch event: " + event); } } }
final void initDispatchThread() { pushPopLock.lock(); try { if (dispatchThread == null && !threadGroup.isDestroyed() && !appContext.isDisposed()) { dispatchThread = AccessController.doPrivileged( new PrivilegedAction<EventDispatchThread>() { public EventDispatchThread run() { EventDispatchThread t = new EventDispatchThread(threadGroup, name, EventQueue.this); t.setContextClassLoader(classLoader); t.setPriority(Thread.NORM_PRIORITY + 1); t.setDaemon(false); AWTAutoShutdown.getInstance().notifyThreadBusy(t); return t; } } ); dispatchThread.start(); } } finally { pushPopLock.unlock(); } }
/** * Removes an event from the <code>EventQueue</code> and * returns it. This method will block until an event has * been posted by another thread. * @return the next <code>AWTEvent</code> * @exception InterruptedException * if any thread has interrupted this thread */ public AWTEvent getNextEvent() throws InterruptedException { do { /* * SunToolkit.flushPendingEvents must be called outside * of the synchronized block to avoid deadlock when * event queues are nested with push()/pop(). */ SunToolkit.flushPendingEvents(); pushPopLock.lock(); try { AWTEvent event = getNextEventPrivate(); if (event != null) { return event; } AWTAutoShutdown.getInstance().notifyThreadFree(dispatchThread); pushPopCond.await(); } finally { pushPopLock.unlock(); } } while(true); }
final void initDispatchThread() { pushPopLock.lock(); try { AppContext appContext = AppContext.getAppContext(); if (dispatchThread == null && !threadGroup.isDestroyed() && !appContext.isDisposed()) { dispatchThread = AccessController.doPrivileged( new PrivilegedAction<EventDispatchThread>() { public EventDispatchThread run() { EventDispatchThread t = new EventDispatchThread(threadGroup, name, EventQueue.this); t.setContextClassLoader(classLoader); t.setPriority(Thread.NORM_PRIORITY + 1); t.setDaemon(false); return t; } } ); AWTAutoShutdown.getInstance().notifyThreadBusy(dispatchThread); dispatchThread.start(); } } finally { pushPopLock.unlock(); } }
final void initDispatchThread() { pushPopLock.lock(); try { if (dispatchThread == null && !threadGroup.isDestroyed() && !appContext.isDisposed()) { dispatchThread = AccessController.doPrivileged( new PrivilegedAction<EventDispatchThread>() { public EventDispatchThread run() { EventDispatchThread t = new EventDispatchThread(threadGroup, name, EventQueue.this); t.setContextClassLoader(classLoader); t.setPriority(Thread.NORM_PRIORITY + 1); t.setDaemon(false); return t; } } ); AWTAutoShutdown.getInstance().notifyThreadBusy(dispatchThread); dispatchThread.start(); } } finally { pushPopLock.unlock(); } }
AppDelayQueue() { /* this thread takes the ready-to-execute scheduled tasks off the queue and passes them for immediate execution to {@link SchedulingWrapper#backendExecutorService} */ scheduledToPooledTransferer = new Thread(new Runnable() { @Override public void run() { while (!shutdown.get()) { try { final SchedulingWrapper.MyScheduledFutureTask task = take(); if (LOG.isTraceEnabled()) { LOG.trace("Took " + task.toString()); } if (!task.isDone()) { // can be cancelled already task.getBackendExecutorService().execute(task); } } catch (InterruptedException e) { if (!shutdown.get()) { LOG.error(e); } } } LOG.debug("scheduledToPooledTransferer Stopped"); } }, "Periodic tasks thread"); scheduledToPooledTransferer.start(); AWTAutoShutdown.getInstance().notifyThreadBusy(scheduledToPooledTransferer); // needed for EDT not to exit suddenly }
public void run() { try { pumpEvents(new Conditional() { public boolean evaluate() { return true; } }); } finally { /* * This synchronized block is to secure that the event dispatch * thread won't die in the middle of posting a new event to the * associated event queue. It is important because we notify * that the event dispatch thread is busy after posting a new event * to its queue, so the EventQueue.dispatchThread reference must * be valid at that point. */ synchronized (theQueue) { if (theQueue.getDispatchThread() == this) { theQueue.detachDispatchThread(); } /* * Event dispatch thread dies in case of an uncaught exception. * A new event dispatch thread for this queue will be started * only if a new event is posted to it. In case if no more * events are posted after this thread died all events that * currently are in the queue will never be dispatched. */ /* * Fix for 4648733. Check both the associated java event * queue and the PostEventQueue. */ if (theQueue.peekEvent() != null || !SunToolkit.isPostEventQueueEmpty()) { theQueue.initDispatchThread(); } AWTAutoShutdown.getInstance().notifyThreadFree(this); } } }
/** * Posts the event to the internal Queue of specified priority, * coalescing as appropriate. * * @param theEvent an instance of <code>java.awt.AWTEvent</code>, * or a subclass of it * @param priority the desired priority of the event */ private void postEvent(AWTEvent theEvent, int priority) { Object source = theEvent.getSource(); if (coalesceEvent(theEvent, priority)) { return; } EventQueueItem newItem = new EventQueueItem(theEvent); cacheEQItem(newItem); boolean notifyID = (theEvent.getID() == this.waitForID); if (queues[priority].head == null) { boolean shouldNotify = noEvents(); queues[priority].head = queues[priority].tail = newItem; if (shouldNotify) { if (theEvent.getSource() != AWTAutoShutdown.getInstance()) { AWTAutoShutdown.getInstance().notifyThreadBusy(dispatchThread); } notifyAll(); } else if (notifyID) { notifyAll(); } } else { // The event was not coalesced or has non-Component source. // Insert it at the end of the appropriate Queue. queues[priority].tail.next = newItem; queues[priority].tail = newItem; if (notifyID) { notifyAll(); } } }
/** * Posts the event to the internal Queue of specified priority, * coalescing as appropriate. * * @param theEvent an instance of <code>java.awt.AWTEvent</code>, * or a subclass of it * @param priority the desired priority of the event */ private void postEvent(AWTEvent theEvent, int priority) { if (coalesceEvent(theEvent, priority)) { return; } EventQueueItem newItem = new EventQueueItem(theEvent); cacheEQItem(newItem); boolean notifyID = (theEvent.getID() == this.waitForID); if (queues[priority].head == null) { boolean shouldNotify = noEvents(); queues[priority].head = queues[priority].tail = newItem; if (shouldNotify) { if (theEvent.getSource() != AWTAutoShutdown.getInstance()) { AWTAutoShutdown.getInstance().notifyThreadBusy(dispatchThread); } pushPopCond.signalAll(); } else if (notifyID) { pushPopCond.signalAll(); } } else { // The event was not coalesced or has non-Component source. // Insert it at the end of the appropriate Queue. queues[priority].tail.next = newItem; queues[priority].tail = newItem; if (notifyID) { pushPopCond.signalAll(); } } }
final boolean detachDispatchThread(EventDispatchThread edt, boolean forceDetach) { /* * This synchronized block is to secure that the event dispatch * thread won't die in the middle of posting a new event to the * associated event queue. It is important because we notify * that the event dispatch thread is busy after posting a new event * to its queue, so the EventQueue.dispatchThread reference must * be valid at that point. */ pushPopLock.lock(); try { if (edt == dispatchThread) { /* * Don't detach the thread if any events are pending. Not * sure if it's a possible scenario, though. * * Fix for 4648733. Check both the associated java event * queue and the PostEventQueue. */ if (!forceDetach && (peekEvent() != null) || !SunToolkit.isPostEventQueueEmpty()) { return false; } dispatchThread = null; } AWTAutoShutdown.getInstance().notifyThreadFree(edt); return true; } finally { pushPopLock.unlock(); } }
final boolean detachDispatchThread(EventDispatchThread edt) { /* * This synchronized block is to secure that the event dispatch * thread won't die in the middle of posting a new event to the * associated event queue. It is important because we notify * that the event dispatch thread is busy after posting a new event * to its queue, so the EventQueue.dispatchThread reference must * be valid at that point. */ pushPopLock.lock(); try { if (edt == dispatchThread) { /* * Don't detach the thread if any events are pending. Not * sure if it's a possible scenario, though. * * Fix for 4648733. Check both the associated java event * queue and the PostEventQueue. */ if ((peekEvent() != null) || !SunToolkit.isPostEventQueueEmpty()) { return false; } dispatchThread = null; } AWTAutoShutdown.getInstance().notifyThreadFree(edt); return true; } finally { pushPopLock.unlock(); } }
void shutdown() { if (shutdown.getAndSet(true)) { throw new IllegalStateException("Already shutdown"); } scheduledToPooledTransferer.interrupt(); try { scheduledToPooledTransferer.join(); } catch (Exception e) { throw new RuntimeException(e); } AWTAutoShutdown.getInstance().notifyThreadFree(scheduledToPooledTransferer); }
public WToolkit() { // Startup toolkit threads if (PerformanceLogger.loggingEnabled()) { PerformanceLogger.setTime("WToolkit construction"); } sun.java2d.Disposer.addRecord(anchor, new ToolkitDisposer()); /* * Fix for 4701990. * AWTAutoShutdown state must be changed before the toolkit thread * starts to avoid race condition. */ AWTAutoShutdown.notifyToolkitThreadBusy(); // Find a root TG and attach Appkit thread to it ThreadGroup rootTG = AccessController.doPrivileged( (PrivilegedAction<ThreadGroup>) ThreadGroupUtils::getRootThreadGroup); if (!startToolkitThread(this, rootTG)) { Thread toolkitThread = new Thread(rootTG, this, "AWT-Windows"); toolkitThread.setDaemon(true); toolkitThread.start(); } try { synchronized(this) { while(!inited) { wait(); } } } catch (InterruptedException x) { // swallow the exception } // Enabled "live resizing" by default. It remains controlled // by the native system though. setDynamicLayout(true); areExtraMouseButtonsEnabled = Boolean.parseBoolean(System.getProperty("sun.awt.enableExtraMouseButtons", "true")); //set system property if not yet assigned System.setProperty("sun.awt.enableExtraMouseButtons", ""+areExtraMouseButtonsEnabled); setExtraMouseButtonsEnabledNative(areExtraMouseButtonsEnabled); }