mirror of
https://github.com/openjdk/jdk.git
synced 2026-05-16 08:29:34 +00:00
8384381: Remove AppContext from java.awt.EventQueue implementation
Reviewed-by: kizune, azvegint, serb
This commit is contained in:
parent
aa29f79564
commit
9be6e77d73
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1996, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1996, 2026, 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
|
||||
@ -40,6 +40,7 @@ import sun.util.logging.PlatformLogger;
|
||||
|
||||
import java.util.concurrent.locks.Condition;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
/**
|
||||
@ -112,11 +113,11 @@ public class EventQueue {
|
||||
|
||||
/*
|
||||
* A single lock to synchronize the push()/pop() and related operations with
|
||||
* all the EventQueues from the AppContext. Synchronization on any particular
|
||||
* all the EventQueues. Synchronization on any particular
|
||||
* event queue(s) is not enough: we should lock the whole stack.
|
||||
*/
|
||||
private final Lock pushPopLock;
|
||||
private final Condition pushPopCond;
|
||||
private static final Lock pushPopLock = new ReentrantLock();
|
||||
private static final Condition pushPopCond = pushPopLock.newCondition();
|
||||
|
||||
/*
|
||||
* Dummy runnable to wake up EDT from getNextEvent() after
|
||||
@ -156,11 +157,6 @@ public class EventQueue {
|
||||
*/
|
||||
private volatile int waitForID;
|
||||
|
||||
/*
|
||||
* AppContext corresponding to the queue.
|
||||
*/
|
||||
private final AppContext appContext;
|
||||
|
||||
private final String name = "AWT-EventQueue-" + threadInitNumber.getAndIncrement();
|
||||
|
||||
private FwDispatcher fwDispatcher;
|
||||
@ -222,18 +218,6 @@ public class EventQueue {
|
||||
for (int i = 0; i < NUM_PRIORITIES; i++) {
|
||||
queues[i] = new Queue();
|
||||
}
|
||||
/*
|
||||
* NOTE: if you ever have to start the associated event dispatch
|
||||
* thread at this point, be aware of the following problem:
|
||||
* If this EventQueue instance is created in
|
||||
* SunToolkit.createNewAppContext() the started dispatch thread
|
||||
* may call AppContext.getAppContext() before createNewAppContext()
|
||||
* completes thus causing mess in thread group to appcontext mapping.
|
||||
*/
|
||||
|
||||
appContext = AppContext.getAppContext();
|
||||
pushPopLock = (Lock)appContext.get(AppContext.EVENT_QUEUE_LOCK_KEY);
|
||||
pushPopCond = (Condition)appContext.get(AppContext.EVENT_QUEUE_COND_KEY);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -247,7 +231,7 @@ public class EventQueue {
|
||||
* @throws NullPointerException if {@code theEvent} is {@code null}
|
||||
*/
|
||||
public void postEvent(AWTEvent theEvent) {
|
||||
SunToolkit.flushPendingEvents(appContext);
|
||||
SunToolkit.flushPendingEvents();
|
||||
postEventPrivate(theEvent);
|
||||
}
|
||||
|
||||
@ -532,7 +516,7 @@ public class EventQueue {
|
||||
* of the synchronized block to avoid deadlock when
|
||||
* event queues are nested with push()/pop().
|
||||
*/
|
||||
SunToolkit.flushPendingEvents(appContext);
|
||||
SunToolkit.flushPendingEvents();
|
||||
pushPopLock.lock();
|
||||
try {
|
||||
AWTEvent event = getNextEventPrivate();
|
||||
@ -572,7 +556,7 @@ public class EventQueue {
|
||||
* of the synchronized block to avoid deadlock when
|
||||
* event queues are nested with push()/pop().
|
||||
*/
|
||||
SunToolkit.flushPendingEvents(appContext);
|
||||
SunToolkit.flushPendingEvents();
|
||||
pushPopLock.lock();
|
||||
try {
|
||||
for (int i = 0; i < NUM_PRIORITIES; i++) {
|
||||
@ -869,8 +853,8 @@ public class EventQueue {
|
||||
newEventQueue.previousQueue = topQueue;
|
||||
topQueue.nextQueue = newEventQueue;
|
||||
|
||||
if (appContext.get(AppContext.EVENT_QUEUE_KEY) == topQueue) {
|
||||
appContext.put(AppContext.EVENT_QUEUE_KEY, newEventQueue);
|
||||
if (SunToolkit.currentEventQueue == topQueue) {
|
||||
SunToolkit.currentEventQueue = newEventQueue;
|
||||
}
|
||||
|
||||
pushPopCond.signalAll();
|
||||
@ -929,8 +913,8 @@ public class EventQueue {
|
||||
topQueue.dispatchThread.setEventQueue(prevQueue);
|
||||
}
|
||||
|
||||
if (appContext.get(AppContext.EVENT_QUEUE_KEY) == this) {
|
||||
appContext.put(AppContext.EVENT_QUEUE_KEY, prevQueue);
|
||||
if (SunToolkit.currentEventQueue == this) {
|
||||
SunToolkit.currentEventQueue = prevQueue;
|
||||
}
|
||||
|
||||
// Wake up EDT waiting in getNextEvent(), so it can
|
||||
@ -1053,7 +1037,7 @@ public class EventQueue {
|
||||
final void initDispatchThread() {
|
||||
pushPopLock.lock();
|
||||
try {
|
||||
if (dispatchThread == null && !threadGroup.isDestroyed() && !appContext.isDisposed()) {
|
||||
if (dispatchThread == null && !threadGroup.isDestroyed()) {
|
||||
EventDispatchThread t = new EventDispatchThread(threadGroup, name, EventQueue.this);
|
||||
t.setContextClassLoader(classLoader);
|
||||
t.setPriority(Thread.NORM_PRIORITY + 1);
|
||||
@ -1071,7 +1055,7 @@ public class EventQueue {
|
||||
/*
|
||||
* Minimize discard possibility for non-posted events
|
||||
*/
|
||||
SunToolkit.flushPendingEvents(appContext);
|
||||
SunToolkit.flushPendingEvents();
|
||||
/*
|
||||
* This synchronized block is to secure that the event dispatch
|
||||
* thread won't die in the middle of posting a new event to the
|
||||
@ -1129,7 +1113,7 @@ public class EventQueue {
|
||||
* {@code removeNotify} method.
|
||||
*/
|
||||
final void removeSourceEvents(Object source, boolean removeAllEvents) {
|
||||
SunToolkit.flushPendingEvents(appContext);
|
||||
SunToolkit.flushPendingEvents();
|
||||
pushPopLock.lock();
|
||||
try {
|
||||
for (int i = 0; i < NUM_PRIORITIES; i++) {
|
||||
|
||||
@ -43,9 +43,6 @@ import java.beans.PropertyChangeListener;
|
||||
import java.lang.ref.SoftReference;
|
||||
|
||||
import sun.util.logging.PlatformLogger;
|
||||
import java.util.concurrent.locks.Condition;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
/**
|
||||
@ -121,17 +118,6 @@ public final class AppContext {
|
||||
/* Since the contents of an AppContext are unique to each Java
|
||||
* session, this class should never be serialized. */
|
||||
|
||||
/*
|
||||
* The key to put()/get() the Java EventQueue into/from the AppContext.
|
||||
*/
|
||||
public static final Object EVENT_QUEUE_KEY = new StringBuffer("EventQueue");
|
||||
|
||||
/*
|
||||
* The keys to store EventQueue push/pop lock and condition.
|
||||
*/
|
||||
public static final Object EVENT_QUEUE_LOCK_KEY = new StringBuilder("EventQueue.Lock");
|
||||
public static final Object EVENT_QUEUE_COND_KEY = new StringBuilder("EventQueue.Condition");
|
||||
|
||||
/* A map of AppContexts, referenced by ThreadGroup.
|
||||
*/
|
||||
private static final Map<ThreadGroup, AppContext> threadGroup2appContext =
|
||||
@ -225,12 +211,6 @@ public final class AppContext {
|
||||
threadGroup2appContext.put(threadGroup, this);
|
||||
|
||||
this.contextClassLoader = Thread.currentThread().getContextClassLoader();
|
||||
// Initialize push/pop lock and its condition to be used by all the
|
||||
// EventQueues within this AppContext
|
||||
Lock eventQueuePushPopLock = new ReentrantLock();
|
||||
put(EVENT_QUEUE_LOCK_KEY, eventQueuePushPopLock);
|
||||
Condition eventQueuePushPopCond = eventQueuePushPopLock.newCondition();
|
||||
put(EVENT_QUEUE_COND_KEY, eventQueuePushPopCond);
|
||||
}
|
||||
|
||||
private static final ThreadLocal<AppContext> threadAppContext =
|
||||
|
||||
@ -133,10 +133,6 @@ public abstract class SunToolkit extends Toolkit
|
||||
*/
|
||||
public static final int GRAB_EVENT_MASK = 0x80000000;
|
||||
|
||||
/* The key to put()/get() the PostEventQueue into/from the AppContext.
|
||||
*/
|
||||
private static final String POST_EVENT_QUEUE_KEY = "PostEventQueue";
|
||||
|
||||
/**
|
||||
* Number of buttons.
|
||||
* By default it's taken from the system. If system value does not
|
||||
@ -156,20 +152,17 @@ public abstract class SunToolkit extends Toolkit
|
||||
*/
|
||||
public static final int MAX_BUTTONS_SUPPORTED = 20;
|
||||
|
||||
/**
|
||||
* Creates and initializes EventQueue instance for the specified
|
||||
* AppContext.
|
||||
* Note that event queue must be created from createNewAppContext()
|
||||
* only in order to ensure that EventQueue constructor obtains
|
||||
* the correct AppContext.
|
||||
* @param appContext AppContext to associate with the event queue
|
||||
*/
|
||||
private static void initEQ(AppContext appContext) {
|
||||
EventQueue eventQueue = new EventQueue();
|
||||
appContext.put(AppContext.EVENT_QUEUE_KEY, eventQueue);
|
||||
public static volatile EventQueue currentEventQueue;
|
||||
private static volatile PostEventQueue postEventQueue;
|
||||
|
||||
PostEventQueue postEventQueue = new PostEventQueue(eventQueue);
|
||||
appContext.put(POST_EVENT_QUEUE_KEY, postEventQueue);
|
||||
/**
|
||||
* Creates and initializes EventQueue instance.
|
||||
*/
|
||||
private static synchronized void initEQ() {
|
||||
if (currentEventQueue == null) {
|
||||
currentEventQueue = new EventQueue();
|
||||
postEventQueue = new PostEventQueue(currentEventQueue);
|
||||
}
|
||||
}
|
||||
|
||||
public SunToolkit() {
|
||||
@ -279,8 +272,7 @@ public abstract class SunToolkit extends Toolkit
|
||||
// the calls to AppContext.getAppContext() from EventQueue ctor
|
||||
// return correct values
|
||||
AppContext appContext = new AppContext(threadGroup);
|
||||
initEQ(appContext);
|
||||
|
||||
initEQ();
|
||||
return appContext;
|
||||
}
|
||||
|
||||
@ -468,12 +460,6 @@ public abstract class SunToolkit extends Toolkit
|
||||
// otherwise have to be modified to precisely identify
|
||||
// system-generated events.
|
||||
setSystemGenerated(event);
|
||||
AppContext eventContext = targetToAppContext(event.getSource());
|
||||
if (eventContext != null && !eventContext.equals(appContext)) {
|
||||
throw new RuntimeException("Event posted on wrong app context : " + event);
|
||||
}
|
||||
PostEventQueue postEventQueue =
|
||||
(PostEventQueue)appContext.get(POST_EVENT_QUEUE_KEY);
|
||||
if (postEventQueue != null) {
|
||||
postEventQueue.postEvent(event);
|
||||
}
|
||||
@ -498,18 +484,6 @@ public abstract class SunToolkit extends Toolkit
|
||||
* EventQueue yet.
|
||||
*/
|
||||
public static void flushPendingEvents() {
|
||||
AppContext appContext = AppContext.getAppContext();
|
||||
flushPendingEvents(appContext);
|
||||
}
|
||||
|
||||
/*
|
||||
* Flush the PostEventQueue for the right AppContext.
|
||||
* The default flushPendingEvents only flushes the thread-local context,
|
||||
* which is not always correct, c.f. 3746956
|
||||
*/
|
||||
public static void flushPendingEvents(AppContext appContext) {
|
||||
PostEventQueue postEventQueue =
|
||||
(PostEventQueue)appContext.get(POST_EVENT_QUEUE_KEY);
|
||||
if (postEventQueue != null) {
|
||||
postEventQueue.flush();
|
||||
}
|
||||
@ -600,20 +574,6 @@ public abstract class SunToolkit extends Toolkit
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns true if the calling thread is the event dispatch thread
|
||||
* contained within AppContext which associated with the given target.
|
||||
* Use this call to ensure that a given task is being executed
|
||||
* (or not being) on the event dispatch thread for the given target.
|
||||
*/
|
||||
public static boolean isDispatchThreadForAppContext(Object target) {
|
||||
AppContext appContext = targetToAppContext(target);
|
||||
EventQueue eq = (EventQueue)appContext.get(AppContext.EVENT_QUEUE_KEY);
|
||||
|
||||
AWTAccessor.EventQueueAccessor accessor = AWTAccessor.getEventQueueAccessor();
|
||||
return accessor.isDispatchThreadImpl(eq);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension getScreenSize() {
|
||||
return GraphicsEnvironment.getLocalGraphicsEnvironment()
|
||||
@ -1035,13 +995,8 @@ public abstract class SunToolkit extends Toolkit
|
||||
}
|
||||
|
||||
public static EventQueue getSystemEventQueueImplPP() {
|
||||
return getSystemEventQueueImplPP(AppContext.getAppContext());
|
||||
}
|
||||
|
||||
public static EventQueue getSystemEventQueueImplPP(AppContext appContext) {
|
||||
EventQueue theEventQueue =
|
||||
(EventQueue)appContext.get(AppContext.EVENT_QUEUE_KEY);
|
||||
return theEventQueue;
|
||||
initEQ();
|
||||
return currentEventQueue;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2021,7 +1976,7 @@ public abstract class SunToolkit extends Toolkit
|
||||
|
||||
|
||||
/*
|
||||
* PostEventQueue is a Thread that runs in the same AppContext as the
|
||||
* PostEventQueue is a Thread tied to the
|
||||
* Java EventQueue. It is a queue of AWTEvents to be posted to the
|
||||
* Java EventQueue. The toolkit Thread (AWT-Windows/AWT-Motif) posts
|
||||
* events to this queue, which then calls EventQueue.postEvent().
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user