1.1 --- a/src/share/classes/java/awt/Container.java Thu Mar 29 13:02:24 2012 -0700
1.2 +++ b/src/share/classes/java/awt/Container.java Wed May 23 11:51:09 2012 +0200
1.3 @@ -2887,8 +2887,7 @@
1.4
1.5 Runnable pumpEventsForHierarchy = new Runnable() {
1.6 public void run() {
1.7 - EventDispatchThread dispatchThread =
1.8 - (EventDispatchThread)Thread.currentThread();
1.9 + EventDispatchThread dispatchThread = EventDispatchThread.findCurrent();
1.10 dispatchThread.pumpEventsForHierarchy(
1.11 new Conditional() {
1.12 public boolean evaluate() {
2.1 --- a/src/share/classes/java/awt/DefaultKeyboardFocusManager.java Thu Mar 29 13:02:24 2012 -0700
2.2 +++ b/src/share/classes/java/awt/DefaultKeyboardFocusManager.java Wed May 23 11:51:09 2012 +0200
2.3 @@ -237,8 +237,7 @@
2.4 }
2.5 SunToolkit.postEvent(targetAppContext, se);
2.6 if (EventQueue.isDispatchThread()) {
2.7 - EventDispatchThread edt = (EventDispatchThread)
2.8 - Thread.currentThread();
2.9 + EventDispatchThread edt = EventDispatchThread.findCurrent();
2.10 edt.pumpEvents(SentEvent.ID, new Conditional() {
2.11 public boolean evaluate() {
2.12 return !se.dispatched && !targetAppContext.isDisposed();
3.1 --- a/src/share/classes/java/awt/EventDispatchThread.java Thu Mar 29 13:02:24 2012 -0700
3.2 +++ b/src/share/classes/java/awt/EventDispatchThread.java Wed May 23 11:51:09 2012 +0200
3.3 @@ -25,19 +25,15 @@
3.4
3.5 package java.awt;
3.6
3.7 -import java.awt.event.InputEvent;
3.8 import java.awt.event.MouseEvent;
3.9 import java.awt.event.ActionEvent;
3.10 import java.awt.event.WindowEvent;
3.11 import java.lang.reflect.Method;
3.12 -import java.security.AccessController;
3.13 -import sun.security.action.GetPropertyAction;
3.14 -import sun.awt.AWTAutoShutdown;
3.15 -import sun.awt.SunToolkit;
3.16 -import sun.awt.AppContext;
3.17
3.18 import java.util.ArrayList;
3.19 -import java.util.List;
3.20 +import java.util.concurrent.BlockingQueue;
3.21 +import java.util.concurrent.Executor;
3.22 +import java.util.concurrent.LinkedBlockingQueue;
3.23 import sun.util.logging.PlatformLogger;
3.24
3.25 import sun.awt.dnd.SunDragSourceContextPeer;
3.26 @@ -62,7 +58,7 @@
3.27 *
3.28 * @since 1.1
3.29 */
3.30 -class EventDispatchThread extends Thread {
3.31 +final class EventDispatchThread {
3.32
3.33 private static final PlatformLogger eventLog = PlatformLogger.getLogger("java.awt.event.EventDispatchThread");
3.34
3.35 @@ -70,14 +66,51 @@
3.36 private boolean doDispatch = true;
3.37 private volatile boolean shutdown = false;
3.38
3.39 - private static final int ANY_EVENT = -1;
3.40 + static final int ANY_EVENT = -1;
3.41
3.42 + private final Executor executor;
3.43 private ArrayList<EventFilter> eventFilters = new ArrayList<EventFilter>();
3.44
3.45 - EventDispatchThread(ThreadGroup group, String name, EventQueue queue) {
3.46 - super(group, name);
3.47 + EventDispatchThread(ThreadGroup group, String name, EventQueue queue, ClassLoader l) {
3.48 + // right now using simple executor that sort of mimics the old
3.49 + // behavior of the run() method of EventDispatchThread. But when
3.50 + // running together with FX, the executor should dispatch the runnable
3.51 + // using Platform.invokeLater to share the same processing thread
3.52 + executor = defaultThread(group, name, l);
3.53 setEventQueue(queue);
3.54 }
3.55 +
3.56 + private static Executor defaultThread(ThreadGroup group, String name, ClassLoader classLoader) {
3.57 + class ExecRuns implements Executor, Runnable {
3.58 + final BlockingQueue<Runnable> toRun = new LinkedBlockingQueue<>();
3.59 + @Override
3.60 + public void execute(Runnable command) {
3.61 + toRun.add(command);
3.62 + }
3.63 +
3.64 + @Override
3.65 + public void run() {
3.66 + while (true) {
3.67 + Runnable r;
3.68 + try {
3.69 + r = toRun.take();
3.70 + } catch (InterruptedException ex) {
3.71 + eventLog.severe(ex.getMessage(), ex);
3.72 + continue;
3.73 + }
3.74 + r.run();
3.75 + }
3.76 + }
3.77 + }
3.78 + ExecRuns er = new ExecRuns();
3.79 +
3.80 + Thread t = new Thread(group, name);
3.81 + t.setContextClassLoader(classLoader);
3.82 + t.setPriority(Thread.NORM_PRIORITY + 1);
3.83 + t.setDaemon(false);
3.84 + t.start();
3.85 + return er;
3.86 + }
3.87
3.88 /*
3.89 * Must be called on EDT only, that's why no synchronization
3.90 @@ -88,23 +121,29 @@
3.91
3.92 public void interrupt() {
3.93 shutdown = true;
3.94 - super.interrupt();
3.95 +//XXX super.interrupt();
3.96 }
3.97
3.98 - public void run() {
3.99 - while (true) {
3.100 - try {
3.101 - pumpEvents(new Conditional() {
3.102 - public boolean evaluate() {
3.103 - return true;
3.104 + public void processEvents() {
3.105 + executor.execute(new Runnable() {
3.106 + @Override
3.107 + public void run() {
3.108 + try {
3.109 + // XXX: the meaning now should be: the pumpEvents processes
3.110 + // currently pending events, and then it returns without
3.111 + // any blocking
3.112 + pumpEvents(new Conditional() {
3.113 + public boolean evaluate() {
3.114 + return true;
3.115 + }
3.116 + });
3.117 + } finally {
3.118 + if(getEventQueue().detachDispatchThread(this, shutdown)) {
3.119 + return;
3.120 }
3.121 - });
3.122 - } finally {
3.123 - if(getEventQueue().detachDispatchThread(this, shutdown)) {
3.124 - break;
3.125 }
3.126 }
3.127 - }
3.128 + });
3.129 }
3.130
3.131 // MacOSX change:
3.132 @@ -155,6 +194,11 @@
3.133 pumpEventsForFilter(ANY_EVENT, cond, filter);
3.134 }
3.135
3.136 + //XXX
3.137 + boolean isInterrupted() {
3.138 + return false;
3.139 + }
3.140 +
3.141 void pumpEventsForFilter(int id, Conditional cond, EventFilter filter) {
3.142 addEventFilter(filter);
3.143 doDispatch = true;
3.144 @@ -195,6 +239,10 @@
3.145 eventFilters.remove(filter);
3.146 }
3.147 }
3.148 +
3.149 + boolean blockWhenNoEvent() {
3.150 + return true;
3.151 + }
3.152
3.153 void pumpOneEventForFilters(int id) {
3.154 AWTEvent event = null;
3.155 @@ -210,7 +258,10 @@
3.156 if (delegate != null && id == ANY_EVENT) {
3.157 event = delegate.getNextEvent(eq);
3.158 } else {
3.159 - event = (id == ANY_EVENT) ? eq.getNextEvent() : eq.getNextEvent(id);
3.160 + event = eq.getNextEvent(id, blockWhenNoEvent());
3.161 + }
3.162 + if (event == null) {
3.163 + return;
3.164 }
3.165
3.166 eventOK = true;
3.167 @@ -263,7 +314,12 @@
3.168 if (eventLog.isLoggable(PlatformLogger.FINE)) {
3.169 eventLog.fine("Processing exception: " + e);
3.170 }
3.171 - getUncaughtExceptionHandler().uncaughtException(this, e);
3.172 +//XXX getUncaughtExceptionHandler().uncaughtException(this, e);
3.173 + }
3.174 +
3.175 + public static EventDispatchThread findCurrent() {
3.176 +//XXX return (EventDispatchThread)Thread.currentThread();
3.177 + return null;
3.178 }
3.179
3.180 public synchronized EventQueue getEventQueue() {
4.1 --- a/src/share/classes/java/awt/EventQueue.java Thu Mar 29 13:02:24 2012 -0700
4.2 +++ b/src/share/classes/java/awt/EventQueue.java Wed May 23 11:51:09 2012 +0200
4.3 @@ -299,9 +299,9 @@
4.4 if (theEvent.getSource() != AWTAutoShutdown.getInstance()) {
4.5 AWTAutoShutdown.getInstance().notifyThreadBusy(dispatchThread);
4.6 }
4.7 - pushPopCond.signalAll();
4.8 + signalAll();
4.9 } else if (notifyID) {
4.10 - pushPopCond.signalAll();
4.11 + signalAll();
4.12 }
4.13 } else {
4.14 // The event was not coalesced or has non-Component source.
4.15 @@ -309,7 +309,7 @@
4.16 queues[priority].tail.next = newItem;
4.17 queues[priority].tail = newItem;
4.18 if (notifyID) {
4.19 - pushPopCond.signalAll();
4.20 + signalAll();
4.21 }
4.22 }
4.23 }
4.24 @@ -484,6 +484,31 @@
4.25
4.26 return true;
4.27 }
4.28 +
4.29 + final AWTEvent getNextEvent(int id, boolean block) throws InterruptedException {
4.30 + if (block) {
4.31 + return (id == EventDispatchThread.ANY_EVENT) ? getNextEvent() : getNextEvent(id);
4.32 + }
4.33 + try {
4.34 + pushPopLock.lock();
4.35 + if (id == EventDispatchThread.ANY_EVENT) {
4.36 + if (noEvents()) {
4.37 + return null;
4.38 + }
4.39 + // XXX: calls SunToolkit.flushPendingEvents under lock now
4.40 + return getNextEvent();
4.41 + } else {
4.42 + AWTEvent peek = peekEvent(id);
4.43 + if (peek == null) {
4.44 + return null;
4.45 + }
4.46 + // XXX: calls SunToolkit.flushPendingEvents under lock now
4.47 + return getNextEvent(id);
4.48 + }
4.49 + } finally {
4.50 + pushPopLock.unlock();
4.51 + }
4.52 + }
4.53
4.54 /**
4.55 * Removes an event from the <code>EventQueue</code> and
4.56 @@ -853,7 +878,7 @@
4.57 appContext.put(AppContext.EVENT_QUEUE_KEY, newEventQueue);
4.58 }
4.59
4.60 - pushPopCond.signalAll();
4.61 + signalAll();
4.62 } finally {
4.63 pushPopLock.unlock();
4.64 }
4.65 @@ -918,7 +943,7 @@
4.66 // pick up a new EventQueue
4.67 topQueue.postEventPrivate(new InvocationEvent(topQueue, dummyRunnable));
4.68
4.69 - pushPopCond.signalAll();
4.70 + signalAll();
4.71 } finally {
4.72 pushPopLock.unlock();
4.73 }
4.74 @@ -1010,16 +1035,14 @@
4.75 EventDispatchThread t =
4.76 new EventDispatchThread(threadGroup,
4.77 name,
4.78 - EventQueue.this);
4.79 - t.setContextClassLoader(classLoader);
4.80 - t.setPriority(Thread.NORM_PRIORITY + 1);
4.81 - t.setDaemon(false);
4.82 + EventQueue.this,
4.83 + classLoader
4.84 + );
4.85 return t;
4.86 }
4.87 }
4.88 );
4.89 AWTAutoShutdown.getInstance().notifyThreadBusy(dispatchThread);
4.90 - dispatchThread.start();
4.91 }
4.92 } finally {
4.93 pushPopLock.unlock();
4.94 @@ -1252,7 +1275,7 @@
4.95 // Forward call to the top of EventQueue stack.
4.96 nextQueue.wakeup(isShutdown);
4.97 } else if (dispatchThread != null) {
4.98 - pushPopCond.signalAll();
4.99 + signalAll();
4.100 } else if (!isShutdown) {
4.101 initDispatchThread();
4.102 }
4.103 @@ -1260,8 +1283,15 @@
4.104 pushPopLock.unlock();
4.105 }
4.106 }
4.107 +
4.108 + private void signalAll() {
4.109 + pushPopCond.signalAll();
4.110 +
4.111 + // new event delivered - requesting new processing
4.112 + // of pending events
4.113 + dispatchThread.processEvents();
4.114 + }
4.115 }
4.116 -
4.117 /**
4.118 * The Queue object holds pointers to the beginning and end of one internal
4.119 * queue. An EventQueue object is composed of multiple internal Queues, one
5.1 --- a/src/share/classes/java/awt/SequencedEvent.java Thu Mar 29 13:02:24 2012 -0700
5.2 +++ b/src/share/classes/java/awt/SequencedEvent.java Wed May 23 11:51:09 2012 +0200
5.3 @@ -90,8 +90,7 @@
5.4
5.5 if (getFirst() != this) {
5.6 if (EventQueue.isDispatchThread()) {
5.7 - EventDispatchThread edt = (EventDispatchThread)
5.8 - Thread.currentThread();
5.9 + EventDispatchThread edt = EventDispatchThread.findCurrent();
5.10 edt.pumpEvents(SentEvent.ID, new Conditional() {
5.11 public boolean evaluate() {
5.12 return !SequencedEvent.this.isFirstOrDisposed();