提交 3d5f6d90 编写于 作者: P pchelko

8015477: Support single threaded AWT/FX mode.

Reviewed-by: ant, anthony
上级 fcc74b1e
......@@ -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() {
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);
}
/*
......
/*
* 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();
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册