8015477: Support single threaded AWT/FX mode
Reviewed-by: ant, anthony
This commit is contained in:
parent
a754c039be
commit
05a410aada
@ -77,8 +77,20 @@ public final class LWCToolkit extends LWToolkit {
|
||||
if (!GraphicsEnvironment.isHeadless()) {
|
||||
initIDs();
|
||||
}
|
||||
inAWT = AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
|
||||
@Override
|
||||
public Boolean run() {
|
||||
return !Boolean.parseBoolean(System.getProperty("javafx.embed.singleThread", "false"));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/*
|
||||
* If true we operate in normal mode and nested runloop is executed in JavaRunLoopMode
|
||||
* If false we operate in singleThreaded FX/AWT interop mode and nested loop uses NSDefaultRunLoopMode
|
||||
*/
|
||||
private static final boolean inAWT;
|
||||
|
||||
public LWCToolkit() {
|
||||
SunToolkit.setDataTransfererClassName("sun.lwawt.macosx.CDataTransferer");
|
||||
|
||||
@ -701,7 +713,10 @@ public final class LWCToolkit extends LWToolkit {
|
||||
*
|
||||
* if false - all events come after exit form the nested loop
|
||||
*/
|
||||
static native void doAWTRunLoop(long mediator, boolean processEvents);
|
||||
static void doAWTRunLoop(long mediator, boolean processEvents) {
|
||||
doAWTRunLoopImpl(mediator, processEvents, inAWT);
|
||||
}
|
||||
static private native void doAWTRunLoopImpl(long mediator, boolean processEvents, boolean inAWT);
|
||||
static native void stopAWTRunLoop(long mediator);
|
||||
|
||||
private native boolean nativeSyncQueue(long timeout);
|
||||
|
@ -61,7 +61,6 @@ static CDropTarget* GetCDropTarget(jlong jdroptarget) {
|
||||
JNIEXPORT jlong JNICALL Java_sun_lwawt_macosx_CDropTargetContextPeer_startTransfer
|
||||
(JNIEnv *env, jobject jthis, jlong jdroptarget, jlong jformat)
|
||||
{
|
||||
AWT_ASSERT_NOT_APPKIT_THREAD;
|
||||
|
||||
jlong result = (jlong) 0L;
|
||||
|
||||
|
@ -295,11 +295,11 @@ AWT_ASSERT_APPKIT_THREAD;
|
||||
|
||||
/*
|
||||
* Class: sun_lwawt_macosx_LWCToolkit
|
||||
* Method: doAWTRunLoop
|
||||
* Method: doAWTRunLoopImpl
|
||||
* Signature: (JZZ)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_sun_lwawt_macosx_LWCToolkit_doAWTRunLoop
|
||||
(JNIEnv *env, jclass clz, jlong mediator, jboolean processEvents)
|
||||
JNIEXPORT void JNICALL Java_sun_lwawt_macosx_LWCToolkit_doAWTRunLoopImpl
|
||||
(JNIEnv *env, jclass clz, jlong mediator, jboolean processEvents, jboolean inAWT)
|
||||
{
|
||||
AWT_ASSERT_APPKIT_THREAD;
|
||||
JNF_COCOA_ENTER(env);
|
||||
@ -311,7 +311,7 @@ JNF_COCOA_ENTER(env);
|
||||
// Don't use acceptInputForMode because that doesn't setup autorelease pools properly
|
||||
BOOL isRunning = true;
|
||||
while (![mediatorObject shouldEndRunLoop] && isRunning) {
|
||||
isRunning = [[NSRunLoop currentRunLoop] runMode:[JNFRunLoop javaRunLoopMode]
|
||||
isRunning = [[NSRunLoop currentRunLoop] runMode:(inAWT ? [JNFRunLoop javaRunLoopMode] : NSDefaultRunLoopMode)
|
||||
beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.010]];
|
||||
if (processEvents) {
|
||||
//We do not spin a runloop here as date is nil, so does not matter which mode to use
|
||||
@ -340,7 +340,6 @@ JNF_COCOA_EXIT(env);
|
||||
JNIEXPORT void JNICALL Java_sun_lwawt_macosx_LWCToolkit_stopAWTRunLoop
|
||||
(JNIEnv *env, jclass clz, jlong mediator)
|
||||
{
|
||||
AWT_ASSERT_NOT_APPKIT_THREAD;
|
||||
JNF_COCOA_ENTER(env);
|
||||
|
||||
AWTRunLoopObject* mediatorObject = (AWTRunLoopObject*)jlong_to_ptr(mediator);
|
||||
|
@ -37,16 +37,10 @@ import java.security.PrivilegedAction;
|
||||
|
||||
import java.util.EmptyStackException;
|
||||
|
||||
import sun.awt.*;
|
||||
import sun.awt.dnd.SunDropTargetEvent;
|
||||
import sun.util.logging.PlatformLogger;
|
||||
|
||||
import sun.awt.AppContext;
|
||||
import sun.awt.AWTAutoShutdown;
|
||||
import sun.awt.PeerEvent;
|
||||
import sun.awt.SunToolkit;
|
||||
import sun.awt.EventQueueItem;
|
||||
import sun.awt.AWTAccessor;
|
||||
|
||||
import java.util.concurrent.locks.Condition;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
@ -181,6 +175,8 @@ public class EventQueue {
|
||||
|
||||
private final String name = "AWT-EventQueue-" + threadInitNumber.getAndIncrement();
|
||||
|
||||
private FwDispatcher fwDispatcher;
|
||||
|
||||
private static final PlatformLogger eventLog = PlatformLogger.getLogger("java.awt.event.EventQueue");
|
||||
|
||||
static {
|
||||
@ -209,6 +205,10 @@ public class EventQueue {
|
||||
{
|
||||
EventQueue.invokeAndWait(source, r);
|
||||
}
|
||||
public void setFwDispatcher(EventQueue eventQueue,
|
||||
FwDispatcher dispatcher) {
|
||||
eventQueue.setFwDispatcher(dispatcher);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@ -684,7 +684,16 @@ public class EventQueue {
|
||||
final Object src = event.getSource();
|
||||
final PrivilegedAction<Void> action = new PrivilegedAction<Void>() {
|
||||
public Void run() {
|
||||
dispatchEventImpl(event, src);
|
||||
if (fwDispatcher == null) {
|
||||
dispatchEventImpl(event, src);
|
||||
} else {
|
||||
fwDispatcher.scheduleDispatch(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
dispatchEventImpl(event, src);
|
||||
}
|
||||
});
|
||||
}
|
||||
return null;
|
||||
}
|
||||
};
|
||||
@ -844,7 +853,9 @@ public class EventQueue {
|
||||
while (topQueue.nextQueue != null) {
|
||||
topQueue = topQueue.nextQueue;
|
||||
}
|
||||
|
||||
if (topQueue.fwDispatcher != null) {
|
||||
throw new RuntimeException("push() to queue with fwDispatcher");
|
||||
}
|
||||
if ((topQueue.dispatchThread != null) &&
|
||||
(topQueue.dispatchThread.getEventQueue() == this))
|
||||
{
|
||||
@ -975,6 +986,9 @@ public class EventQueue {
|
||||
// Forward the request to the top of EventQueue stack
|
||||
return nextQueue.createSecondaryLoop(cond, filter, interval);
|
||||
}
|
||||
if (fwDispatcher != null) {
|
||||
return fwDispatcher.createSecondaryLoop();
|
||||
}
|
||||
if (dispatchThread == null) {
|
||||
initDispatchThread();
|
||||
}
|
||||
@ -1018,6 +1032,9 @@ public class EventQueue {
|
||||
eq = next;
|
||||
next = eq.nextQueue;
|
||||
}
|
||||
if (eq.fwDispatcher != null) {
|
||||
return eq.fwDispatcher.isDispatchThread();
|
||||
}
|
||||
return (Thread.currentThread() == eq.dispatchThread);
|
||||
} finally {
|
||||
pushPopLock.unlock();
|
||||
@ -1303,6 +1320,15 @@ public class EventQueue {
|
||||
pushPopLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
// The method is used by AWTAccessor for javafx/AWT single threaded mode.
|
||||
private void setFwDispatcher(FwDispatcher dispatcher) {
|
||||
if (nextQueue != null) {
|
||||
nextQueue.setFwDispatcher(dispatcher);
|
||||
} else {
|
||||
fwDispatcher = dispatcher;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -484,6 +484,11 @@ public final class AWTAccessor {
|
||||
*/
|
||||
void invokeAndWait(Object source, Runnable r)
|
||||
throws InterruptedException, InvocationTargetException;
|
||||
|
||||
/**
|
||||
* Sets the delegate for the EventQueue used by FX/AWT single threaded mode
|
||||
*/
|
||||
public void setFwDispatcher(EventQueue eventQueue, FwDispatcher dispatcher);
|
||||
}
|
||||
|
||||
/*
|
||||
|
59
jdk/src/share/classes/sun/awt/FwDispatcher.java
Normal file
59
jdk/src/share/classes/sun/awt/FwDispatcher.java
Normal file
@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package sun.awt;
|
||||
|
||||
import java.awt.*;
|
||||
|
||||
/**
|
||||
* An interface for the EventQueue delegate.
|
||||
* This class is added to support JavaFX/AWT interop single threaded mode
|
||||
* The delegate should be set in EventQueue by {@link EventQueue#setFwDispatcher(FwDispatcher)}
|
||||
* If the delegate is not null, than it handles supported methods instead of the
|
||||
* event queue. If it is null than the behaviour of an event queue does not change.
|
||||
*
|
||||
* @see EventQueue
|
||||
*
|
||||
* @author Petr Pchelko
|
||||
*
|
||||
* @since 1.8
|
||||
*/
|
||||
public interface FwDispatcher {
|
||||
/**
|
||||
* Delegates the {@link EventQueue#isDispatchThread()} method
|
||||
*/
|
||||
boolean isDispatchThread();
|
||||
|
||||
/**
|
||||
* Forwards a runnable to the delegate, which executes it on an appropriate thread.
|
||||
* @param r - a runnable calling {@link EventQueue#dispatchEventImpl(java.awt.AWTEvent, Object)}
|
||||
*/
|
||||
void scheduleDispatch(Runnable r);
|
||||
|
||||
/**
|
||||
* Delegates the {@link java.awt.EventQueue#createSecondaryLoop()} method
|
||||
*/
|
||||
SecondaryLoop createSecondaryLoop();
|
||||
}
|
Loading…
Reference in New Issue
Block a user